Entropy Piano Tuner  1.1.3 (documentation not yet complete)
An open-source experimental software for piano tuning by entropy minimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
audiorecorderforqt.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2015 Haye Hinrichsen, Christoph Wick
3  *
4  * This file is part of Entropy Piano Tuner.
5  *
6  * Entropy Piano Tuner is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * Entropy Piano Tuner is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * Entropy Piano Tuner. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 #include "audiorecorderforqt.h"
21 #include <qdebug.h>
22 #include <QTimer>
23 #include <assert.h>
24 #include "../core/system/log.h"
25 #include "settingsforqt.h"
27 
28 const AudioRecorderForQt::DataFormat AudioRecorderForQt::SIGNAL_SCALING = std::numeric_limits<AudioRecorderForQt::DataFormat>::max();
29 // const AudioRecorderForQt::DataFormat AudioRecorderForQt::SIGNAL_SCALING = 1;
30 
32  : QObject(parent),
33  mAudioInput(nullptr),
34  mIODevice(nullptr) {
35 
36  setDeviceName(SettingsForQt::getSingleton().getInputDeviceName().toStdString());
37  setSamplingRate(SettingsForQt::getSingleton().getInputDeviceSamplingRate());
38 }
39 
41 {
42 }
43 
44 
46  QAudioFormat format;
47  // Set up the format, eg.
48  format.setSampleRate(getSamplingRate());
49  format.setChannelCount(getChannelCount());
50  format.setCodec("audio/pcm");
51  format.setSampleSize(sizeof(DataFormat) * 8);
52  format.setSampleType(QAudioFormat::SignedInt);
53  //format.setByteOrder(QAudioFormat::LittleEndian);
54 
55  QAudioDeviceInfo device(QAudioDeviceInfo::defaultInputDevice());
56  if (getDeviceName().size() > 0) {
57  QList<QAudioDeviceInfo> devices(QAudioDeviceInfo::availableDevices(QAudio::AudioInput));
58  for (const QAudioDeviceInfo &i : devices) {
59  if (i.deviceName().toStdString() == getDeviceName()) {
60  device = i;
61  break;
62  }
63  }
64 
65  if (!device.isFormatSupported(format)) {
66  LogE("Selected device settings are not supported!");
67  }
68  }
69  else {
70  // only necessary if default settings
71  if (!device.isFormatSupported(format)) {
72  LogW("Raw audio format not supported by backend, falling back to nearest supported");
73  format = device.nearestFormat(format);
74  // update sampling rate, buffer type has to stay the same!
75  if (not device.isFormatSupported(format))
76  {
77  LogW("Fallback failed. Probably there is no input device available. Did you connect your microphone?");
78  return;
79  }
80  setSamplingRate(format.sampleRate());
81  if (format.sampleSize() != sizeof(DataFormat) * 8) {
82  LogW("Sample size not supported");
83  return;
84  }
85  if (format.sampleType() != QAudioFormat::SignedInt) {
86  LogW("Sample format not supported");
87  return;
88  }
89  }
90  }
91 
92  mAudioInput = new QAudioInput(device, format);
93  if (mAudioInput->error() != QAudio::NoError) {
94  LogE("Error creating QAudioInput with error %d", mAudioInput->error());
95  return;
96  }
97  mAudioInput->setNotifyInterval(20);
98 
99  setDeviceName(device.deviceName().toStdString());
100 
101 
102  QObject::connect(&mReadTimer, SIGNAL(timeout()), this, SLOT(onReadPacket()));
103 
104  LogI("Initialized Qt audio recorder using device: %s", getDeviceName().c_str());
105 }
106 
108  mReadTimer.stop();
109 
110  if (mAudioInput) {
111  if (mIODevice) {
112  mIODevice->close();
113  mIODevice = nullptr;
114  }
115  mAudioInput->reset();
116  delete mAudioInput;
117  mAudioInput = nullptr;
118  }
119  LogI("Qt audio recorder closed.");
120 }
121 
123  if (!mAudioInput) {
124  LogI("Audio device not created, cannot start it.");
125  return;
126  }
127  mIODevice = mAudioInput->start();
128  if (mAudioInput->error() != QAudio::NoError) {
129  qWarning() << "Error starting QAudioInput with error " << mAudioInput->error();
130  return;
131  }
132  mReadTimer.start(mAudioInput->notifyInterval());
133 }
134 
136  if (!mAudioInput) {
137  return;
138  }
139  mReadTimer.stop();
140  if (mAudioInput) {
141  mAudioInput->stop();
142  mIODevice = nullptr;
143  }
144 }
145 
147  if (mAudioInput) {
148  mAudioInput->setVolume(volume);
149  }
150 }
151 
153  if (mAudioInput) {
154  return mAudioInput->volume();
155  }
156  return 1;
157 }
158 
160  QByteArray rawdata = mIODevice->readAll();
161  std::vector<DataFormat> data(rawdata.size() / sizeof(DataFormat));
162  memcpy(data.data(), rawdata.data(), data.size() * sizeof(DataFormat));
163 
164  PacketType realData(data.size());
165  for (size_t i = 0; i < data.size(); ++i) {
166  realData[i] = data[i] * 1.0 / SIGNAL_SCALING;
167  }
168 
169  pushRawData(realData);
170 }
std::vector< PCMDataType > PacketType
Type definition of a PCM packet (vector of PCM values).
Definition: audiobase.h:51
int16_t DataFormat
Data format of the input/output stream.
void start() override
Start/restart the audio device.
void pushRawData(const PacketType &data)
The implementation calls this function when new data is available.
#define LogW(...)
Definition: log.h:56
void exit() override
Destroy the audio device.
const std::string & getDeviceName() const
Get a readable string of the name of the audio device.
Definition: audiobase.cpp:52
AudioRecorderForQt(QObject *parent)
void init() override
Inizialize the audio device.
QAudioInput * mAudioInput
void setDeviceName(const std::string &n)
Set the device name.
Definition: audiobase.cpp:65
int getChannelCount() const
Get the actual number of channels (1=mono, 2=stereo).
Definition: audiobase.cpp:109
virtual void setDeviceInputGain(double volume) overridefinal
#define LogI(...)
Definition: log.h:50
int getSamplingRate() const
Get the actual sampling rate.
Definition: audiobase.cpp:78
#define LogE(...)
Definition: log.h:62
virtual double getDeviceInputGain() const overridefinal
void setSamplingRate(int rate) override
static const DataFormat SIGNAL_SCALING
maximal alloed value of the stream
static SettingsForQt & getSingleton()
Getter function for the singleton.
void stop() override
Stop the audio device.