SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
audiodialog.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015-2019 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <math.h>
20 
21 #include <QTreeWidgetItem>
22 #include <QMessageBox>
23 
25 #include "audiodialog.h"
26 #include "ui_audiodialog.h"
27 
28 AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* parent) :
29  QDialog(parent),
30  ui(new Ui::AudioDialog),
31  m_audioDeviceManager(audioDeviceManager)
32 {
33  ui->setupUi(this);
34  QTreeWidgetItem* treeItem;
35 
36  // out panel
37 
39  QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
40  treeItem = new QTreeWidgetItem(ui->audioOutTree);
41  treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName);
43  treeItem->setText(0, found ? "__" : "_D");
44  ui->audioOutTree->setCurrentItem(treeItem);
45 
46  const QList<QAudioDeviceInfo>& outputDevices = m_audioDeviceManager->getOutputDevices();
47 
48  for(QList<QAudioDeviceInfo>::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it)
49  {
50  treeItem = new QTreeWidgetItem(ui->audioOutTree);
51  treeItem->setText(1, it->deviceName());
52  bool systemDefault = it->deviceName() == defaultOutputDeviceInfo.deviceName();
53  found = m_audioDeviceManager->getOutputDeviceInfo(it->deviceName(), outDeviceInfo);
54  treeItem->setText(0, QString(systemDefault ? "S" : "_") + QString(found ? "_" : "D"));
55 
56  if (systemDefault) {
57  treeItem->setBackground(1, QBrush(qRgb(96,96,96)));
58  }
59  }
60 
61  ui->audioOutTree->resizeColumnToContents(0);
62  ui->audioOutTree->resizeColumnToContents(1);
63 
64  // in panel
65 
67  QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice();
68  treeItem = new QTreeWidgetItem(ui->audioInTree);
69  treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName);
71  treeItem->setText(0, found ? "__" : "_D");
72  ui->audioInTree->setCurrentItem(treeItem);
73 
74  const QList<QAudioDeviceInfo>& inputDevices = m_audioDeviceManager->getInputDevices();
75 
76  for(QList<QAudioDeviceInfo>::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it)
77  {
78  treeItem = new QTreeWidgetItem(ui->audioInTree);
79  treeItem->setText(1, it->deviceName());
80  bool systemDefault = it->deviceName() == defaultInputDeviceInfo.deviceName();
81  found = m_audioDeviceManager->getInputDeviceInfo(it->deviceName(), inDeviceInfo);
82  treeItem->setText(0, QString(systemDefault ? "S" : "_") + QString(found ? "_" : "D"));
83 
84  if (systemDefault) {
85  treeItem->setBackground(1, QBrush(qRgb(96,96,96)));
86  }
87  }
88 
89  ui->audioInTree->resizeColumnToContents(0);
90  ui->audioInTree->resizeColumnToContents(1);
91 
92  m_outputUDPPort = 9998;
93  m_outIndex = -1;
94  m_inIndex = -1;
95 
96  ui->tabWidget->setCurrentIndex(0);
97 }
98 
100 {
101  delete ui;
102 }
103 
105 {
106  m_inIndex = ui->audioInTree->indexOfTopLevelItem(ui->audioInTree->currentItem());
107  m_outIndex = ui->audioOutTree->indexOfTopLevelItem(ui->audioOutTree->currentItem());
108 
109  if (ui->tabWidget->currentIndex() == 0) // output
110  {
112 
113  if (ui->outputResetKey->isChecked()) {
115  } else {
117  }
118  }
119  else if (ui->tabWidget->currentIndex() == 1) // input
120  {
122 
123  if (ui->inputResetKey->isChecked()) {
125  } else {
127  }
128  }
129 
130  QDialog::accept();
131 }
132 
134 {
135  QDialog::reject();
136 }
137 
139  QTreeWidgetItem* currentItem,
140  QTreeWidgetItem* previousItem)
141 {
143  QString inDeviceName = currentItem->text(1);
144  int newIndex = ui->audioInTree->indexOfTopLevelItem(currentItem);
145  int oldIndex = ui->audioInTree->indexOfTopLevelItem(previousItem);
146 
147  if (newIndex != oldIndex) {
148  ui->inputResetKey->setChecked(false);
149  }
150 
151  m_audioDeviceManager->getInputDeviceInfo(inDeviceName, inDeviceInfo);
152  m_inputDeviceInfo = inDeviceInfo;
153 
155 }
156 
158  QTreeWidgetItem* currentItem,
159  QTreeWidgetItem* previousItem)
160 {
162  QString outDeviceName = currentItem->text(1);
163  int newIndex = ui->audioOutTree->indexOfTopLevelItem(currentItem);
164  int oldIndex = ui->audioOutTree->indexOfTopLevelItem(previousItem);
165 
166  if (newIndex != oldIndex) {
167  ui->outputResetKey->setChecked(false);
168  }
169 
170  m_audioDeviceManager->getOutputDeviceInfo(outDeviceName, outDeviceInfo);
171  m_outputDeviceInfo = outDeviceInfo;
172 
174 }
175 
177 {
178  float volume = value / 100.0f;
179  ui->inputVolumeText->setText(QString("%1").arg(volume, 0, 'f', 2));
180 }
181 
183 {
184  (void) checked;
187 }
188 
190 {
191  (void) checked;
193 }
194 
196 {
197  ui->inputSampleRate->setValue(m_inputDeviceInfo.sampleRate);
198  ui->inputVolume->setValue(round(m_inputDeviceInfo.volume * 100.0f));
199  ui->inputVolumeText->setText(QString("%1").arg(m_inputDeviceInfo.volume, 0, 'f', 2));
200 }
201 
203 {
204  m_inputDeviceInfo.sampleRate = ui->inputSampleRate->value();
205  m_inputDeviceInfo.volume = ui->inputVolume->value() / 100.0f;
206 }
207 
209 {
210  bool ok;
211  quint16 udpPort = ui->outputUDPPort->text().toInt(&ok);
212 
213  if((!ok) || (udpPort < 1024)) {
214  udpPort = 9999;
215  }
216 
217  m_outputUDPPort = udpPort;
218  ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort));
219 }
220 
222 {
223  (void) checked;
226 }
227 
229 {
230  (void) checked;
232 }
233 
235 {
238  check();
239 }
240 
242 {
245  check();
246 }
247 
249 {
252  check();
253 }
254 
256 {
259  check();
260 }
261 
263 {
264  ui->outputSampleRate->blockSignals(true);
265  ui->outputUDPChannelMode->blockSignals(true);
266  ui->outputUDPChannelCodec->blockSignals(true);
267  ui->decimationFactor->blockSignals(true);
268 
269  ui->outputSampleRate->setValue(m_outputDeviceInfo.sampleRate);
270  ui->outputUDPAddress->setText(m_outputDeviceInfo.udpAddress);
271  ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort));
272  ui->outputUDPCopy->setChecked(m_outputDeviceInfo.copyToUDP);
273  ui->outputUDPUseRTP->setChecked(m_outputDeviceInfo.udpUseRTP);
274  ui->outputUDPChannelMode->setCurrentIndex((int) m_outputDeviceInfo.udpChannelMode);
275  ui->outputUDPChannelCodec->setCurrentIndex((int) m_outputDeviceInfo.udpChannelCodec);
276  ui->decimationFactor->setCurrentIndex(m_outputDeviceInfo.udpDecimationFactor == 0 ? 0 : m_outputDeviceInfo.udpDecimationFactor - 1);
277 
279 
280  ui->outputSampleRate->blockSignals(false);
281  ui->outputUDPChannelMode->blockSignals(false);
282  ui->outputUDPChannelCodec->blockSignals(false);
283  ui->decimationFactor->blockSignals(false);
284 }
285 
287 {
288  m_outputDeviceInfo.sampleRate = ui->outputSampleRate->value();
289  m_outputDeviceInfo.udpAddress = ui->outputUDPAddress->text();
291  m_outputDeviceInfo.copyToUDP = ui->outputUDPCopy->isChecked();
292  m_outputDeviceInfo.udpUseRTP = ui->outputUDPUseRTP->isChecked();
293  m_outputDeviceInfo.udpChannelMode = (AudioOutput::UDPChannelMode) ui->outputUDPChannelMode->currentIndex();
294  m_outputDeviceInfo.udpChannelCodec = (AudioOutput::UDPChannelCodec) ui->outputUDPChannelCodec->currentIndex();
295  m_outputDeviceInfo.udpDecimationFactor = ui->decimationFactor->currentIndex() + 1;
296 }
297 
299 {
300  QString format;
303 
305  {
307  format = "PCMA";
308  break;
310  format = "PCMU";
311  break;
313  format = "G722";
314  effectiveSampleRate /= 2; // codec does a decimation by 2
315  break;
317  format = "L8";
318  break;
320  format = "opus";
321  nChannels = 2; // always 2 even for mono
322  effectiveSampleRate = 48000; // always 48000 regardless of input rate
323  break;
325  default:
326  format = "L16";
327  break;
328  }
329 
330  ui->outputSDPText->setText(tr("%1/%2/%3").arg(format).arg(effectiveSampleRate).arg(nChannels));
331 }
332 
334 {
337 
339  {
340  if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 8000)) {
341  QMessageBox::information(this, tr("Message"), tr("PCMA must be 8000 Hz single channel"));
342  }
343  }
345  {
346  if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 8000)) {
347  QMessageBox::information(this, tr("Message"), tr("PCMU must be 8000 Hz single channel"));
348  }
349  }
351  {
352  if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 16000)) {
353  QMessageBox::information(this, tr("Message"), tr("G722 must be 16000 Hz single channel"));
354  }
355  }
357  {
358  int effectiveSampleRate = m_outputDeviceInfo.sampleRate/decimationFactor;
359  if ((effectiveSampleRate != 48000) && (effectiveSampleRate != 24000) && (effectiveSampleRate != 16000) && (effectiveSampleRate != 12000)) {
360  QMessageBox::information(this, tr("Message"), tr("Opus takes only 48, 24, 16 or 12 kHz sample rates"));
361  }
362  }
363 }
void on_outputReset_clicked(bool checked)
static const QString m_defaultDeviceName
const QList< QAudioDeviceInfo > & getInputDevices() const
void updateInputDeviceInfo()
Opus compression.
Definition: audiooutput.h:52
void on_outputUDPChannelMode_currentIndexChanged(int index)
void outputInfosCleanup()
Remove output info from map for output devices not present.
AudioDialogX(AudioDeviceManager *audioDeviceManager, QWidget *parent=0)
Definition: audiodialog.cpp:28
AudioDeviceManager::OutputDeviceInfo m_outputDeviceInfo
Definition: audiodialog.h:36
void on_audioInTree_currentItemChanged(QTreeWidgetItem *currentItem, QTreeWidgetItem *previousItem)
void on_audioOutTree_currentItemChanged(QTreeWidgetItem *currentItem, QTreeWidgetItem *previousItem)
void on_decimationFactor_currentIndexChanged(int index)
AudioOutput::UDPChannelCodec udpChannelCodec
void on_inputReset_clicked(bool checked)
unsigned int uint32_t
Definition: rtptypes_win.h:46
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void on_inputVolume_valueChanged(int value)
void setOutputDeviceInfo(int outputDeviceIndex, const OutputDeviceInfo &deviceInfo)
void on_outputUDPPort_editingFinished()
bool getInputDeviceInfo(const QString &deviceName, InputDeviceInfo &deviceInfo) const
void inputInfosCleanup()
Remove input info from map for input devices not present.
bool getOutputDeviceInfo(const QString &deviceName, OutputDeviceInfo &deviceInfo) const
Linear 16 bit (no codec)
Definition: audiooutput.h:47
void updateOutputSDPString()
const QList< QAudioDeviceInfo > & getOutputDevices() const
void unsetInputDeviceInfo(int inputDeviceIndex)
void on_outputSampleRate_valueChanged(int value)
AudioDeviceManager * m_audioDeviceManager
Definition: audiodialog.h:34
G722 compression.
Definition: audiooutput.h:51
AudioOutput::UDPChannelMode udpChannelMode
void on_inputCleanup_clicked(bool checked)
void updateInputDisplay()
void updateOutputDisplay()
Ui::AudioDialog * ui
Definition: audiodialog.h:32
void on_outputCleanup_clicked(bool checked)
Linear 8 bit.
Definition: audiooutput.h:48
void setInputDeviceInfo(int inputDeviceIndex, const InputDeviceInfo &deviceInfo)
void updateOutputDeviceInfo()
PCM A-law 8 bit.
Definition: audiooutput.h:49
quint16 m_outputUDPPort
Definition: audiodialog.h:37
PCM Mu-law 8 bit.
Definition: audiooutput.h:50
void unsetOutputDeviceInfo(int outputDeviceIndex)
AudioDeviceManager::InputDeviceInfo m_inputDeviceInfo
Definition: audiodialog.h:35
void on_outputUDPChannelCodec_currentIndexChanged(int index)