Added signal/slot communication for audio format. The rx audio handler

will now send to the tx audio handler information about the speaker
output hardware on the host. The tx handler is now smart enough to check
if the format needs conversion or not.
monitor
Elliott Liggett 2022-08-30 10:18:40 -07:00
rodzic 4fdcc4bf26
commit 7dfac11315
7 zmienionych plików z 80 dodań i 25 usunięć

Wyświetl plik

@ -182,6 +182,13 @@ bool audioHandler::init(audioSetup setup)
return true;
}
void audioHandler::acceptMonitorAudioFormat(QAudioFormat mformat)
{
// TODO
qDebug(logAudio()) << "Error, this should not have been called: " << __PRETTY_FUNCTION__;
(void)mformat;
}
void audioHandler::start()
{
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "start() running";

Wyświetl plik

@ -64,6 +64,7 @@ public slots:
virtual void incomingAudio(const audioPacket data);
virtual void convertedInput(audioPacket audio);
virtual void convertedOutput(audioPacket audio);
virtual void acceptMonitorAudioFormat(QAudioFormat mformat);
private slots:
virtual void stateChanged(QAudio::State state);
@ -77,6 +78,7 @@ signals:
void haveLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency,quint16 current,bool under,bool over);
void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio);
void haveAudioFormat(QAudioFormat format);
private:

Wyświetl plik

@ -41,6 +41,27 @@ void paHandler::setSharedAudioData(sharedAudioType *m)
this->monitorFormat = m->monitorFormat;
}
void paHandler::acceptMonitorAudioFormat(QAudioFormat mformat)
{
qDebug(logAudio()) << "Monitor audio format received into tx audio handler.";
this->monitorFormat = mformat;
this->sharedAudioInfo->monitorFormat = mformat;
emit setupMonitorStreamConverter(outFormat, monitorFormat, 7, setup.resampleQuality);
connect(converterToMonitor, SIGNAL(converted(audioPacket)), this, SLOT(convertedMonitorAudio(audioPacket)));
if(checkFormatsSame(&outFormat, &monitorFormat))
{
convertMonitorFormat = false;
} else {
convertMonitorFormat = true;
qDebug(logAudio()) << "outFormat: " << outFormat;
qDebug(logAudio()) << "monitorFormat: " << monitorFormat;
}
qInfo(logAudio()) << "Conversion for monitor audio: " << convertMonitorFormat;
haveMonitorInformation = true;
}
bool paHandler::init(audioSetup setup)
{
if (isInitialized) {
@ -210,17 +231,16 @@ bool paHandler::init(audioSetup setup)
}
}
if (setup.isinput) {
err = Pa_OpenStream(&audio, &aParams, 0, outFormat.sampleRate(), this->chunkSize, paNoFlag, &paHandler::staticWrite, (void*)this);
emit setupConverter(outFormat, inFormat, 7, setup.resampleQuality);
emit setupMonitorStreamConverter(outFormat, outFormat, 7, setup.resampleQuality);
connect(converterToMonitor, SIGNAL(converted(audioPacket)), this, SLOT(convertedMonitorAudio(audioPacket)));
connect(converter, SIGNAL(converted(audioPacket)), this, SLOT(convertedInput(audioPacket)));
}
else {
if (setup.isinput) {
err = Pa_OpenStream(&audio, &aParams, 0, outFormat.sampleRate(), this->chunkSize, paNoFlag, &paHandler::staticWrite, (void*)this);
emit setupConverter(outFormat, inFormat, 7, setup.resampleQuality);
//emit setupMonitorStreamConverter(outFormat, monitorFormat, 7, setup.resampleQuality);
connect(converter, SIGNAL(converted(audioPacket)), this, SLOT(convertedInput(audioPacket)));
}
else {
err = Pa_OpenStream(&audio, 0, &aParams, outFormat.sampleRate(), this->chunkSize, paNoFlag, NULL, NULL);
emit setupConverter(inFormat, outFormat, 7, setup.resampleQuality);
emit haveAudioFormat(outFormat);
connect(converter, SIGNAL(converted(audioPacket)), this, SLOT(convertedOutput(audioPacket)));
}
@ -263,17 +283,21 @@ void paHandler::incomingAudio(audioPacket packet)
// (not currently working)
//convertedOutput(packet);
// Convert: (if needed)
//emit sendToMonitorConverter(packet);
// if the formats are actually the same, no need to convert:
convertedMonitorAudio(packet);
if(haveMonitorInformation)
{
if(convertMonitorFormat)
{
// Convert format: (if needed)
emit sendToMonitorConverter(packet);
} else {
// if the formats are actually the same, no need to convert:
convertedMonitorAudio(packet);
}
}
}
return;
}
int paHandler::writeData(const void* inputBuffer, void* outputBuffer,
unsigned long nFrames, const PaStreamCallbackTimeInfo * streamTime,
PaStreamCallbackFlags status)
@ -313,12 +337,12 @@ void paHandler::mixAudio(QByteArray *dest, unsigned char *monitorSource)
int size = dest->size();
float* mon = reinterpret_cast<float*>(monitorSource);
float* dst = reinterpret_cast<float*>(dest->data());
//32 bits per float sample means the size is divide by four.
// 32 bits per float sample means the size is divide by four.
int floatSize = size / 4;
for(int s=0; s < floatSize; s++)
{
dst[s] = dst[s] + mon[s];
dst[s] = dst[s] + sharedAudioInfo->monitorVolume*mon[s];
}
}
@ -416,7 +440,6 @@ void paHandler::convertedMonitorAudio(audioPacket audio)
}
void paHandler::convertedInput(audioPacket packet)
{
if (packet.data.size() > 0) {
@ -428,7 +451,17 @@ void paHandler::convertedInput(audioPacket packet)
}
}
bool paHandler::checkFormatsSame(QAudioFormat *a, QAudioFormat *b)
{
bool same = true;
same = same && (a->codec() == b->codec());
same = same && (a->sampleRate() == b->sampleRate());
same = same && (a->byteOrder() == b->byteOrder());
same = same && (a->channelCount() == b->channelCount());
same = same && (a->sampleSize() == b->sampleSize());
same = same && (a->sampleType() == b->sampleType());
return same;
}
void paHandler::changeLatency(const quint16 newSize)
{

Wyświetl plik

@ -50,6 +50,7 @@ public slots:
void convertedOutput(audioPacket audio);
void convertedMonitorAudio(audioPacket audio);
void incomingAudio(const audioPacket data);
void acceptMonitorAudioFormat(QAudioFormat mformat);
private slots:
@ -63,6 +64,7 @@ signals:
void setupMonitorStreamConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio);
void sendToMonitorConverter(audioPacket audio);
void haveAudioFormat(QAudioFormat format);
private:
@ -76,8 +78,10 @@ private:
}
void mixAudio(QByteArray *dest, unsigned char *monitorSource);
bool isInitialized = false;
bool checkFormatsSame(QAudioFormat *a, QAudioFormat *b);
bool convertMonitorFormat = true;
bool haveMonitorInformation = false;
bool isInitialized = false;
PaStream* audio = Q_NULLPTR;
PaStreamParameters aParams;
const PaDeviceInfo* info;

Wyświetl plik

@ -250,6 +250,11 @@ errorHandler:
}
void rtHandler::acceptMonitorAudioFormat(QAudioFormat mformat)
{
// TODO
(void)mformat;
}
void rtHandler::setVolume(unsigned char volume)
{

Wyświetl plik

@ -54,7 +54,7 @@ public slots:
void convertedInput(audioPacket audio);
void convertedOutput(audioPacket audio);
void incomingAudio(const audioPacket data);
void acceptMonitorAudioFormat(QAudioFormat mformat);
private slots:

Wyświetl plik

@ -23,8 +23,11 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
monitorAudio.testNumber = 17; // TODO remove
monitorAudio.monitorVolume = 0.5;
monitorAudio.monitorFeatureOn = true;
monitorAudio.hostSetup = rxSetup;
monitorAudio.monitorFormat = toQAudioFormat(rxSetup.codec, rxSetup.sampleRate);
// TODO: This is not the right format to copy, this is the radio's format, not
// the host audio format (speaker).
//monitorAudio.hostSetup = rxSetup;
//monitorAudio.monitorFormat = toQAudioFormat(rxSetup.codec, rxSetup.sampleRate);
startAudio();
watchdogTimer = new QTimer();
@ -303,6 +306,7 @@ void udpAudio::startAudio() {
connect(txaudio, SIGNAL(haveLevels(quint16, quint16, quint16, quint16, bool, bool)), this, SLOT(getTxLevels(quint16, quint16, quint16, quint16, bool, bool)));
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
connect(rxaudio, SIGNAL(haveAudioFormat(QAudioFormat)), txaudio, SLOT(acceptMonitorAudioFormat(QAudioFormat)));
emit setupTxAudio(txSetup);
}