/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015-2019 F4EXB // // written by Edouard Griffiths // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include "audio/audiodevicemanager.h" #include "audiodialog.h" #include "ui_audiodialog.h" AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* parent) : QDialog(parent), ui(new Ui::AudioDialog), m_audioDeviceManager(audioDeviceManager) { ui->setupUi(this); QTreeWidgetItem* treeItem; // out panel AudioDeviceManager::OutputDeviceInfo outDeviceInfo; QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice(); treeItem = new QTreeWidgetItem(ui->audioOutTree); treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName); bool found = m_audioDeviceManager->getOutputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, outDeviceInfo); treeItem->setText(0, found ? "__" : "_D"); ui->audioOutTree->setCurrentItem(treeItem); const QList& outputDevices = m_audioDeviceManager->getOutputDevices(); for(QList::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it) { treeItem = new QTreeWidgetItem(ui->audioOutTree); treeItem->setText(1, it->deviceName()); bool systemDefault = it->deviceName() == defaultOutputDeviceInfo.deviceName(); found = m_audioDeviceManager->getOutputDeviceInfo(it->deviceName(), outDeviceInfo); treeItem->setText(0, QString(systemDefault ? "S" : "_") + QString(found ? "_" : "D")); if (systemDefault) { treeItem->setBackground(1, QBrush(qRgb(96,96,96))); } } ui->audioOutTree->resizeColumnToContents(0); ui->audioOutTree->resizeColumnToContents(1); // in panel AudioDeviceManager::InputDeviceInfo inDeviceInfo; QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice(); treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName); found = m_audioDeviceManager->getInputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, inDeviceInfo); treeItem->setText(0, found ? "__" : "_D"); ui->audioInTree->setCurrentItem(treeItem); const QList& inputDevices = m_audioDeviceManager->getInputDevices(); for(QList::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it) { treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem->setText(1, it->deviceName()); bool systemDefault = it->deviceName() == defaultInputDeviceInfo.deviceName(); found = m_audioDeviceManager->getInputDeviceInfo(it->deviceName(), inDeviceInfo); treeItem->setText(0, QString(systemDefault ? "S" : "_") + QString(found ? "_" : "D")); if (systemDefault) { treeItem->setBackground(1, QBrush(qRgb(96,96,96))); } } ui->audioInTree->resizeColumnToContents(0); ui->audioInTree->resizeColumnToContents(1); m_outputUDPPort = 9998; m_outIndex = -1; m_inIndex = -1; ui->tabWidget->setCurrentIndex(0); } AudioDialogX::~AudioDialogX() { delete ui; } void AudioDialogX::accept() { m_inIndex = ui->audioInTree->indexOfTopLevelItem(ui->audioInTree->currentItem()); m_outIndex = ui->audioOutTree->indexOfTopLevelItem(ui->audioOutTree->currentItem()); if (ui->tabWidget->currentIndex() == 0) // output { updateOutputDeviceInfo(); if (ui->outputResetKey->isChecked()) { m_audioDeviceManager->unsetOutputDeviceInfo(m_outIndex-1); } else { m_audioDeviceManager->setOutputDeviceInfo(m_outIndex-1, m_outputDeviceInfo); } } else if (ui->tabWidget->currentIndex() == 1) // input { updateInputDeviceInfo(); if (ui->inputResetKey->isChecked()) { m_audioDeviceManager->unsetInputDeviceInfo(m_inIndex-1); } else { m_audioDeviceManager->setInputDeviceInfo(m_inIndex-1, m_inputDeviceInfo); } } QDialog::accept(); } void AudioDialogX::reject() { QDialog::reject(); } void AudioDialogX::on_audioInTree_currentItemChanged( QTreeWidgetItem* currentItem, QTreeWidgetItem* previousItem) { AudioDeviceManager::InputDeviceInfo inDeviceInfo; QString inDeviceName = currentItem->text(1); int newIndex = ui->audioInTree->indexOfTopLevelItem(currentItem); int oldIndex = ui->audioInTree->indexOfTopLevelItem(previousItem); if (newIndex != oldIndex) { ui->inputResetKey->setChecked(false); } m_audioDeviceManager->getInputDeviceInfo(inDeviceName, inDeviceInfo); m_inputDeviceInfo = inDeviceInfo; updateInputDisplay(); } void AudioDialogX::on_audioOutTree_currentItemChanged( QTreeWidgetItem* currentItem, QTreeWidgetItem* previousItem) { AudioDeviceManager::OutputDeviceInfo outDeviceInfo; QString outDeviceName = currentItem->text(1); int newIndex = ui->audioOutTree->indexOfTopLevelItem(currentItem); int oldIndex = ui->audioOutTree->indexOfTopLevelItem(previousItem); if (newIndex != oldIndex) { ui->outputResetKey->setChecked(false); } m_audioDeviceManager->getOutputDeviceInfo(outDeviceName, outDeviceInfo); m_outputDeviceInfo = outDeviceInfo; updateOutputDisplay(); } void AudioDialogX::on_inputVolume_valueChanged(int value) { float volume = value / 100.0f; ui->inputVolumeText->setText(QString("%1").arg(volume, 0, 'f', 2)); } void AudioDialogX::on_inputReset_clicked(bool checked) { (void) checked; m_inputDeviceInfo.resetToDefaults(); updateInputDisplay(); } void AudioDialogX::on_inputCleanup_clicked(bool checked) { (void) checked; m_audioDeviceManager->inputInfosCleanup(); } void AudioDialogX::updateInputDisplay() { ui->inputSampleRate->setValue(m_inputDeviceInfo.sampleRate); ui->inputVolume->setValue(round(m_inputDeviceInfo.volume * 100.0f)); ui->inputVolumeText->setText(QString("%1").arg(m_inputDeviceInfo.volume, 0, 'f', 2)); } void AudioDialogX::updateInputDeviceInfo() { m_inputDeviceInfo.sampleRate = ui->inputSampleRate->value(); m_inputDeviceInfo.volume = ui->inputVolume->value() / 100.0f; } void AudioDialogX::on_outputUDPPort_editingFinished() { bool ok; quint16 udpPort = ui->outputUDPPort->text().toInt(&ok); if((!ok) || (udpPort < 1024)) { udpPort = 9999; } m_outputUDPPort = udpPort; ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort)); } void AudioDialogX::on_outputReset_clicked(bool checked) { (void) checked; m_outputDeviceInfo.resetToDefaults(); updateOutputDisplay(); } void AudioDialogX::on_outputCleanup_clicked(bool checked) { (void) checked; m_audioDeviceManager->outputInfosCleanup(); } void AudioDialogX::on_outputSampleRate_valueChanged(int value) { m_outputDeviceInfo.sampleRate = value; updateOutputSDPString(); } void AudioDialogX::on_decimationFactor_currentIndexChanged(int index) { m_outputDeviceInfo.udpDecimationFactor = index + 1; updateOutputSDPString(); } void AudioDialogX::on_outputUDPChannelCodec_currentIndexChanged(int index) { m_outputDeviceInfo.udpChannelCodec = (AudioOutput::UDPChannelCodec) index; updateOutputSDPString(); } void AudioDialogX::on_outputUDPChannelMode_currentIndexChanged(int index) { m_outputDeviceInfo.udpChannelMode = (AudioOutput::UDPChannelMode) index; updateOutputSDPString(); } void AudioDialogX::updateOutputDisplay() { ui->outputSampleRate->setValue(m_outputDeviceInfo.sampleRate); ui->outputUDPAddress->setText(m_outputDeviceInfo.udpAddress); ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort)); ui->outputUDPCopy->setChecked(m_outputDeviceInfo.copyToUDP); ui->outputUDPUseRTP->setChecked(m_outputDeviceInfo.udpUseRTP); ui->outputUDPChannelMode->setCurrentIndex((int) m_outputDeviceInfo.udpChannelMode); ui->outputUDPChannelCodec->setCurrentIndex((int) m_outputDeviceInfo.udpChannelCodec); ui->decimationFactor->setCurrentIndex(m_outputDeviceInfo.udpDecimationFactor == 0 ? 0 : m_outputDeviceInfo.udpDecimationFactor - 1); updateOutputSDPString(); } void AudioDialogX::updateOutputDeviceInfo() { m_outputDeviceInfo.sampleRate = ui->outputSampleRate->value(); m_outputDeviceInfo.udpAddress = ui->outputUDPAddress->text(); m_outputDeviceInfo.udpPort = m_outputUDPPort; m_outputDeviceInfo.copyToUDP = ui->outputUDPCopy->isChecked(); m_outputDeviceInfo.udpUseRTP = ui->outputUDPUseRTP->isChecked(); m_outputDeviceInfo.udpChannelMode = (AudioOutput::UDPChannelMode) ui->outputUDPChannelMode->currentIndex(); m_outputDeviceInfo.udpChannelCodec = (AudioOutput::UDPChannelCodec) ui->outputUDPChannelCodec->currentIndex(); m_outputDeviceInfo.udpDecimationFactor = ui->decimationFactor->currentIndex() + 1; } void AudioDialogX::updateOutputSDPString() { QString format; int nChannels = m_outputDeviceInfo.udpChannelMode == AudioOutput::UDPChannelStereo ? 2 : 1; uint32_t decimationFactor = m_outputDeviceInfo.udpDecimationFactor == 0 ? 1 : m_outputDeviceInfo.udpDecimationFactor; if (m_outputDeviceInfo.udpChannelCodec == AudioOutput::UDPCodecALaw) { format = "PCMA"; if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 8000)) { QMessageBox::information(this, tr("Message"), tr("PCMA must be 8000 Hz single channel")); } } else if (m_outputDeviceInfo.udpChannelCodec == AudioOutput::UDPCodecULaw) { format = "PCMU"; if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 8000)) { QMessageBox::information(this, tr("Message"), tr("PCMU must be 8000 Hz single channel")); } } else if (m_outputDeviceInfo.udpChannelCodec == AudioOutput::UDPCodecG722) { format = "G722"; if ((nChannels != 1) || (m_outputDeviceInfo.sampleRate/decimationFactor != 16000)) { QMessageBox::information(this, tr("Message"), tr("G722 must be 16000 Hz single channel")); } } else if (m_outputDeviceInfo.udpChannelCodec == AudioOutput::UDPCodecL8) { format = "L8"; } else if (m_outputDeviceInfo.udpChannelCodec == AudioOutput::UDPCodecL16) { format = "L16"; } else { QMessageBox::information(this, tr("Message"), tr("Unknown codec")); format = "UNK"; } ui->outputSDPText->setText(tr("%1/%2/%3").arg(format).arg(m_outputDeviceInfo.sampleRate/decimationFactor).arg(nChannels)); }