diff --git a/audiohandler.cpp b/audiohandler.cpp index 9a10329..38a85b5 100644 --- a/audiohandler.cpp +++ b/audiohandler.cpp @@ -8,9 +8,6 @@ #include "logcategories.h" #include "ulaw.h" -#if defined(Q_OS_WIN) && defined(PORTAUDIO) -#include -#endif audioHandler::audioHandler(QObject* parent) @@ -22,28 +19,23 @@ audioHandler::~audioHandler() { if (isInitialized) { -#if defined(RTAUDIO) - - try { - audio->abortStream(); - audio->closeStream(); - } - catch (RtAudioError& e) { - qInfo(logAudio()) << "Error closing stream:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage()); - } - delete audio; -#elif defined(PORTAUDIO) - Pa_StopStream(audio); - Pa_CloseStream(audio); -#else stop(); -#endif } if (ringBuf != Q_NULLPTR) { delete ringBuf; } + if (audioInput != Q_NULLPTR) { + audioInput = Q_NULLPTR; + delete audioInput; + } + if (audioOutput != Q_NULLPTR) { + delete audioOutput; + audioOutput = Q_NULLPTR; + } + + if (resampler != Q_NULLPTR) { speex_resampler_destroy(resampler); qDebug(logAudio()) << "Resampler closed"; @@ -109,181 +101,6 @@ bool audioHandler::init(audioSetup setupIn) this->setVolume(setup.localAFgain); } -#if defined(RTAUDIO) -#if !defined(Q_OS_MACX) - options.flags = ((!RTAUDIO_HOG_DEVICE) | (RTAUDIO_MINIMIZE_LATENCY)); -#endif - -#if defined(Q_OS_LINUX) - audio = new RtAudio(RtAudio::Api::LINUX_ALSA); -#elif defined(Q_OS_WIN) - audio = new RtAudio(RtAudio::Api::WINDOWS_WASAPI); -#elif defined(Q_OS_MACX) - audio = new RtAudio(RtAudio::Api::MACOSX_CORE); -#endif - - if (setup.port > 0) { - aParams.deviceId = setup.port; - } - else if (setup.isinput) { - aParams.deviceId = audio->getDefaultInputDevice(); - } - else { - aParams.deviceId = audio->getDefaultOutputDevice(); - } - aParams.firstChannel = 0; - - try { - info = audio->getDeviceInfo(aParams.deviceId); - } - catch (RtAudioError& e) { - qInfo(logAudio()) << "Device error:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage()); - return isInitialized; - } - - if (info.probed) - { - // Always use the "preferred" sample rate - // We can always resample if needed - this->nativeSampleRate = info.preferredSampleRate; - - // Per channel chunk size. - this->chunkSize = (this->nativeSampleRate / 50); - - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << QString::fromStdString(info.name) << "(" << aParams.deviceId << ") successfully probed"; - if (info.nativeFormats == 0) - { - qInfo(logAudio()) << " No natively supported data formats!"; - return false; - } - else { - qDebug(logAudio()) << " Supported formats:" << - (info.nativeFormats & RTAUDIO_SINT8 ? "8-bit int," : "") << - (info.nativeFormats & RTAUDIO_SINT16 ? "16-bit int," : "") << - (info.nativeFormats & RTAUDIO_SINT24 ? "24-bit int," : "") << - (info.nativeFormats & RTAUDIO_SINT32 ? "32-bit int," : "") << - (info.nativeFormats & RTAUDIO_FLOAT32 ? "32-bit float," : "") << - (info.nativeFormats & RTAUDIO_FLOAT64 ? "64-bit float," : ""); - - qInfo(logAudio()) << " Preferred sample rate:" << info.preferredSampleRate; - if (setup.isinput) { - devChannels = info.inputChannels; - } - else { - devChannels = info.outputChannels; - } - qInfo(logAudio()) << " Channels:" << devChannels; - if (devChannels > 2) { - devChannels = 2; - } - aParams.nChannels = devChannels; - } - - qInfo(logAudio()) << " chunkSize: " << chunkSize; - try { - if (setup.isinput) { - audio->openStream(NULL, &aParams, RTAUDIO_SINT16, this->nativeSampleRate, &this->chunkSize, &staticWrite, this, &options); - } - else { - audio->openStream(&aParams, NULL, RTAUDIO_SINT16, this->nativeSampleRate, &this->chunkSize, &staticRead, this, &options); - } - audio->startStream(); - isInitialized = true; - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "device successfully opened"; - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "detected latency:" << audio->getStreamLatency(); - } - catch (RtAudioError& e) { - qInfo(logAudio()) << "Error opening:" << QString::fromStdString(e.getMessage()); - } - } - else - { - qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << QString::fromStdString(info.name) << "(" << aParams.deviceId << ") could not be probed, check audio configuration!"; - } - - -#elif defined(PORTAUDIO) - - PaError err; - -#ifdef Q_OS_WIN - CoInitialize(0); -#endif - - memset(&aParams, 0,sizeof(PaStreamParameters)); - - if (setup.port > 0) { - aParams.device = setup.port; - } - else if (setup.isinput) { - aParams.device = Pa_GetDefaultInputDevice(); - } - else { - aParams.device = Pa_GetDefaultOutputDevice(); - } - - info = Pa_GetDeviceInfo(aParams.device); - - aParams.channelCount = 2; - aParams.hostApiSpecificStreamInfo = NULL; - aParams.sampleFormat = paInt16; - if (setup.isinput) { - aParams.suggestedLatency = info->defaultLowInputLatency; - } - else { - aParams.suggestedLatency = info->defaultLowOutputLatency; - } - - aParams.hostApiSpecificStreamInfo = NULL; - - // Always use the "preferred" sample rate (unless it is 44100) - // We can always resample if needed - if (info->defaultSampleRate == 44100) { - this->nativeSampleRate = 48000; - } - else { - this->nativeSampleRate = info->defaultSampleRate; - } - // Per channel chunk size. - this->chunkSize = (this->nativeSampleRate / 50); - - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << info->name << "(" << aParams.device << ") successfully probed"; - if (setup.isinput) { - devChannels = info->maxInputChannels; - } - else { - devChannels = info->maxOutputChannels; - } - if (devChannels > 2) { - devChannels = 2; - } - aParams.channelCount = devChannels; - - qInfo(logAudio()) << " Channels:" << devChannels; - qInfo(logAudio()) << " chunkSize: " << chunkSize; - qInfo(logAudio()) << " sampleRate: " << nativeSampleRate; - - if (setup.isinput) { - err=Pa_OpenStream(&audio, &aParams, 0, this->nativeSampleRate, this->chunkSize, paNoFlag, &audioHandler::staticWrite, (void*)this); - } - else { - err=Pa_OpenStream(&audio, 0, &aParams, this->nativeSampleRate, this->chunkSize, paNoFlag, &audioHandler::staticRead, (void*)this); - } - - if (err == paNoError) { - err = Pa_StartStream(audio); - } - if (err == paNoError) { - isInitialized = true; - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "device successfully opened"; - } - else { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "failed to open device" << Pa_GetErrorText(err); - } - - -#else - format.setSampleSize(16); format.setChannelCount(2); format.setSampleRate(INTERNAL_SAMPLE_RATE); @@ -320,21 +137,16 @@ bool audioHandler::init(audioSetup setupIn) if (setup.isinput) { audioInput = new QAudioInput(setup.port, format, this); - connect(audioInput, SIGNAL(notify()), SLOT(notified())); - connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); + //connect(audioInput, SIGNAL(notify()), SLOT(notified())); isInitialized = true; } else { audioOutput = new QAudioOutput(setup.port, format, this); audioOutput->setBufferSize(getAudioSize(setup.latency, format)); - - //connect(audioOutput, SIGNAL(notify()), SLOT(notified())); - connect(audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); isInitialized = true; } -#endif // Setup resampler and opus if they are needed. int resample_error = 0; int opus_err = 0; @@ -370,16 +182,10 @@ bool audioHandler::init(audioSetup setupIn) qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "thread id" << QThread::currentThreadId(); -#if !defined (RTAUDIO) && !defined(PORTAUDIO) - if (isInitialized) { - this->start(); - } -#endif - + this->start(); return isInitialized; } -#if !defined (RTAUDIO) && !defined(PORTAUDIO) void audioHandler::start() { qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "start() running"; @@ -390,196 +196,30 @@ void audioHandler::start() } if (setup.isinput) { -#ifndef Q_OS_WIN - this->open(QIODevice::WriteOnly); -#else - this->open(QIODevice::WriteOnly); - //this->open(QIODevice::WriteOnly | QIODevice::Unbuffered); -#endif - audioInput->start(this); + audioDevice = audioInput->start(); + connect(audioInput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection); + connect(audioDevice, &QIODevice::destroyed, this, &QAudioInput::deleteLater, Qt::UniqueConnection); } else { -#ifndef Q_OS_WIN - this->open(QIODevice::ReadOnly); -#else - //this->open(QIODevice::ReadOnly | QIODevice::Unbuffered); - //this->open(QIODevice::ReadOnly); -#endif audioDevice = audioOutput->start(); - if (!audioDevice) - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio device failed to start()"; - return; - } connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection); connect(audioDevice, &QIODevice::destroyed, this, &QAudioOutput::deleteLater, Qt::UniqueConnection); - audioBuffered = true; - + } + if (!audioDevice) { + qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio device failed to start()"; + return; } } -#endif void audioHandler::setVolume(unsigned char volume) { - this->volume = audiopot[volume]; - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")"; } - -/// -/// This function processes the incoming audio FROM the radio and pushes it into the playback buffer *data -/// -/// -/// -/// -#if defined(RTAUDIO) -int audioHandler::readData(void* outputBuffer, void* inputBuffer, - unsigned int nFrames, double streamTime, RtAudioStreamStatus status) -{ - Q_UNUSED(inputBuffer); - Q_UNUSED(streamTime); - if (status == RTAUDIO_OUTPUT_UNDERFLOW) - qDebug(logAudio()) << "Underflow detected"; - int nBytes = nFrames * devChannels * 2; // This is ALWAYS 2 bytes per sample and 2 channels - quint8* buffer = (quint8*)outputBuffer; -#elif defined(PORTAUDIO) - -int audioHandler::readData(const void* inputBuffer, void* outputBuffer, - unsigned long nFrames, const PaStreamCallbackTimeInfo * streamTime, PaStreamCallbackFlags status) -{ - Q_UNUSED(inputBuffer); - Q_UNUSED(streamTime); - Q_UNUSED(status); - int nBytes = nFrames * devChannels * 2; // This is ALWAYS 2 bytes per sample and 2 channels - quint8* buffer = (quint8*)outputBuffer; -#else -qint64 audioHandler::readData(char* buffer, qint64 nBytes) -{ -#endif - // Calculate output length, always full samples - int sentlen = 0; - if (!isReady) { - isReady = true; - } - if (!audioBuffered) { - memset(buffer, 0, nBytes); -#if defined(RTAUDIO) - return 0; -#elif defined(PORTAUDIO) - return 0; -#else - return nBytes; -#endif - } - audioPacket packet; - if (ringBuf->size()>0) - { - // Output buffer is ALWAYS 16 bit. - while (sentlen < nBytes) - { - if (!ringBuf->try_read(packet)) - { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "buffer is empty, sentlen:" << sentlen << " nBytes:" << nBytes ; - break; - } - //qDebug(logAudio()) << "Packet size:" << packet.data.length() << "nBytes (requested)" << nBytes << "remaining" << nBytes-sentlen; - currentLatency = packet.time.msecsTo(QTime::currentTime()); - - // This shouldn't be required but if we did output a partial packet - // This will add the remaining packet data to the output buffer. - if (tempBuf.sent != tempBuf.data.length()) - { - int send = qMin((int)nBytes - sentlen, tempBuf.data.length() - tempBuf.sent); - memcpy(buffer + sentlen, tempBuf.data.constData() + tempBuf.sent, send); - tempBuf.sent = tempBuf.sent + send; - sentlen = sentlen + send; - if (tempBuf.sent != tempBuf.data.length()) - { - // We still don't have enough buffer space for this? - break; - } - //qDebug(logAudio()) << "Adding partial:" << send; - } - - if (currentLatency > setup.latency) { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Packet " << hex << packet.seq << - " arrived too late (increase output latency!) " << - dec << packet.time.msecsTo(QTime::currentTime()) << "ms"; - delayedPackets++; - } - - int send = qMin((int)nBytes - sentlen, packet.data.length()); - memcpy(buffer + sentlen, packet.data.constData(), send); - sentlen = sentlen + send; - if (send < packet.data.length()) - { - //qDebug(logAudio()) << "Asking for partial, sent:" << send << "packet length" << packet.data.length(); - tempBuf = packet; - tempBuf.sent = tempBuf.sent + send; - lastSeq = packet.seq; - break; - } - - - if (packet.seq <= lastSeq) { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Duplicate/early audio packet: " << hex << lastSeq << " got " << hex << packet.seq; - } - else if (packet.seq != lastSeq + 1) { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Missing audio packet(s) from: " << hex << lastSeq + 1 << " to " << hex << packet.seq - 1; - } - - lastSeq = packet.seq; - } - } - - // fill the rest of the buffer with silence - if (nBytes > sentlen) { - qDebug(logAudio()) << "looking for: " << nBytes << " got: " << sentlen; - memset(buffer + sentlen, 0, nBytes - sentlen); - } - - if (delayedPackets > 10) { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Too many delayed packets, flushing buffer"; - //while (ringBuf->try_read(packet)); // Empty buffer - delayedPackets = 0; - //audioBuffered = false; - } - -#if defined(RTAUDIO) - return 0; -#elif defined(PORTAUDIO) - return 0; -#else - return nBytes; -#endif -} - -#if defined(RTAUDIO) -int audioHandler::writeData(void* outputBuffer, void* inputBuffer, - unsigned int nFrames, double streamTime, RtAudioStreamStatus status) -{ - Q_UNUSED(outputBuffer); - Q_UNUSED(streamTime); - Q_UNUSED(status); - int nBytes = nFrames * devChannels * 2; // This is ALWAYS 2 bytes per sample and 2 channels - const char* data = (const char*)inputBuffer; -#elif defined(PORTAUDIO) -int audioHandler::writeData(const void* inputBuffer, void* outputBuffer, - unsigned long nFrames, const PaStreamCallbackTimeInfo * streamTime, - PaStreamCallbackFlags status) -{ - Q_UNUSED(outputBuffer); - Q_UNUSED(streamTime); - Q_UNUSED(status); - int nBytes = nFrames * devChannels * 2; // This is ALWAYS 2 bytes per sample and 2 channels - const char* data = (const char*)inputBuffer; -#else qint64 audioHandler::writeData(const char* data, qint64 nBytes) { -#endif if (!isReady) { isReady = true; } @@ -609,13 +249,7 @@ qint64 audioHandler::writeData(const char* data, qint64 nBytes) } //qDebug(logAudio()) << "sentlen" << sentlen; -#if defined(RTAUDIO) - return 0; -#elif defined(PORTAUDIO) - return 0; -#else return nBytes; -#endif } void audioHandler::incomingAudio(audioPacket inPacket) @@ -666,7 +300,7 @@ void audioHandler::incomingAudio(audioPacket inPacket) } } - // Process uLaw + // Process uLaw. if (setup.ulaw) { // Current packet is 8bit so need to create a new buffer that is 16bit @@ -691,7 +325,7 @@ void audioHandler::incomingAudio(audioPacket inPacket) if (setup.format.sampleSize() == 16) { VectorXint16 samplesI = Eigen::Map(reinterpret_cast(livePacket.data.data()), livePacket.data.size() / int(sizeof(qint16))); - samplesF = samplesI.cast(); + samplesF = samplesI.cast() / float(std::numeric_limits::max()); } else { @@ -701,7 +335,7 @@ void audioHandler::incomingAudio(audioPacket inPacket) // Set the max amplitude found in the vector amplitude = samplesF.array().abs().maxCoeff(); - + qDebug(logAudio()) << "Current amplitude" << QString::number(amplitude, 'f', 4) << getAmplitude() ; // Set the volume samplesF *= volume; @@ -716,7 +350,8 @@ void audioHandler::incomingAudio(audioPacket inPacket) if (format.sampleType() == QAudioFormat::SignedInt) { - VectorXint16 samplesI = samplesF.cast(); + Eigen::VectorXf samplesITemp = samplesF * float(std::numeric_limits::max()); + VectorXint16 samplesI = samplesITemp.cast(); livePacket.data = QByteArray(reinterpret_cast(samplesI.data()), int(samplesI.size()) * int(sizeof(qint16))); } else @@ -747,8 +382,8 @@ void audioHandler::incomingAudio(audioPacket inPacket) //qDebug(logAudio()) << "Adding packet to buffer:" << livePacket.seq << ": " << livePacket.data.length(); - - currentLatency = livePacket.time.msecsTo(QTime::currentTime()); + + currentLatency = livePacket.time.msecsTo(QTime::currentTime()) + getAudioDuration(audioOutput->bufferSize()-audioOutput->bytesFree(),format); audioDevice->write(livePacket.data); @@ -766,20 +401,16 @@ void audioHandler::incomingAudio(audioPacket inPacket) void audioHandler::changeLatency(const quint16 newSize) { + qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Changing latency to: " << newSize << " from " << setup.latency; setup.latency = newSize; - //delete ringBuf; - //audioBuffered = false; - //ringBuf = new wilt::Ring(setup.latency + 1); // Should be customizable. + if (!setup.isinput) { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Current buffer size is" << audioOutput->bufferSize() << " " << getAudioDuration(audioOutput->bufferSize(), format) << "ms)"; - audioOutput->stop(); + stop(); audioOutput->setBufferSize(getAudioSize(setup.latency, format)); - audioDevice = audioOutput->start(); - connect(audioOutput, &QAudioOutput::destroyed, audioDevice, &QIODevice::deleteLater, Qt::UniqueConnection); - connect(audioDevice, &QIODevice::destroyed, this, &QAudioOutput::deleteLater, Qt::UniqueConnection); - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "New buffer size is" << audioOutput->bufferSize() << " " << getAudioDuration(audioOutput->bufferSize(), format) << "ms)"; + start(); } + } int audioHandler::getLatency() @@ -793,18 +424,11 @@ void audioHandler::getNextAudioChunk(QByteArray& ret) { audioPacket packet; packet.sent = 0; - - if (isInitialized && ringBuf != Q_NULLPTR && ringBuf->try_read(packet)) - { - currentLatency = packet.time.msecsTo(QTime::currentTime()); - - if (currentLatency > setup.latency) { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Packet " << hex << packet.seq << - " arrived too late (increase latency!) " << - dec << packet.time.msecsTo(QTime::currentTime()) << "ms"; - delayedPackets++; - } - + if (audioDevice != Q_NULLPTR) { + packet.data = audioDevice->readAll(); + } + if (packet.data.length() > 0) + { //qDebug(logAudio) << "Chunksize" << this->chunkSize << "Packet size" << packet.data.length(); // Packet will arrive as stereo interleaved 16bit 48K if (resampleRatio != 1.0) @@ -904,12 +528,6 @@ void audioHandler::getNextAudioChunk(QByteArray& ret) amplitude = tempAmplitude; ret = packet.data; - //qDebug(logAudio()) << "Now radio format, length" << packet.data.length(); - if (delayedPackets > 10) { - qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Too many delayed packets, flushing buffer"; - while (ringBuf->try_read(packet)); // Empty buffer - delayedPackets = 0; - } } @@ -918,85 +536,23 @@ void audioHandler::getNextAudioChunk(QByteArray& ret) } -#if !defined (RTAUDIO) && !defined(PORTAUDIO) - -qint64 audioHandler::bytesAvailable() const -{ - return 0; -} - -bool audioHandler::isSequential() const -{ - return true; -} - -void audioHandler::notified() -{ -} - - -void audioHandler::stateChanged(QAudio::State state) -{ - // Process the state - switch (state) - { - case QAudio::IdleState: - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio now in idle state: " << audioBuffer.size() << " packets in buffer"; - if (audioOutput != Q_NULLPTR && audioOutput->error() == QAudio::UnderrunError) - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "buffer underrun"; - //audioOutput->suspend(); - } - break; - } - case QAudio::ActiveState: - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio now in active state: " << audioBuffer.size() << " packets in buffer"; - break; - } - case QAudio::SuspendedState: - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio now in suspended state: " << audioBuffer.size() << " packets in buffer"; - break; - } - case QAudio::StoppedState: - { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio now in stopped state: " << audioBuffer.size() << " packets in buffer"; - break; - } - default: { - qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Unhandled audio state: " << audioBuffer.size() << " packets in buffer"; - } - } -} - void audioHandler::stop() { if (audioOutput != Q_NULLPTR && audioOutput->state() != QAudio::StoppedState) { // Stop audio output audioOutput->stop(); - this->stop(); - this->close(); - delete audioOutput; - audioOutput = Q_NULLPTR; } if (audioInput != Q_NULLPTR && audioInput->state() != QAudio::StoppedState) { // Stop audio output audioInput->stop(); - this->stop(); - this->close(); - delete audioInput; - audioInput = Q_NULLPTR; } isInitialized = false; } -#endif quint16 audioHandler::getAmplitude() { - return *reinterpret_cast(&litude); + return static_cast(amplitude * 255.0); } diff --git a/audiohandler.h b/audiohandler.h index d1bfa01..be23b6d 100644 --- a/audiohandler.h +++ b/audiohandler.h @@ -69,29 +69,18 @@ struct audioPacket { struct audioSetup { QString name; -// quint8 bits; -// quint8 radioChan; -// quint16 samplerate; quint16 latency; quint8 codec; bool ulaw = false; bool isinput; QAudioFormat format; // Use this for all audio APIs -#if defined(RTAUDIO) || defined(PORTAUDIO) - int port; -#else QAudioDeviceInfo port; -#endif quint8 resampleQuality; unsigned char localAFgain; }; // For QtMultimedia, use a native QIODevice -#if !defined(PORTAUDIO) && !defined(RTAUDIO) -class audioHandler : public QIODevice -#else class audioHandler : public QObject -#endif { Q_OBJECT @@ -101,15 +90,8 @@ public: int getLatency(); -#if !defined (RTAUDIO) && !defined(PORTAUDIO) - bool setDevice(QAudioDeviceInfo deviceInfo); - void start(); - void flush(); void stop(); - qint64 bytesAvailable() const; - bool isSequential() const; -#endif void getNextAudioChunk(QByteArray &data); quint16 getAmplitude(); @@ -121,10 +103,6 @@ public slots: void incomingAudio(const audioPacket data); private slots: -#if !defined (RTAUDIO) && !defined(PORTAUDIO) - void notified(); - void stateChanged(QAudio::State state); -#endif signals: void audioMessage(QString message); @@ -134,61 +112,18 @@ signals: private: -#if defined(RTAUDIO) - int readData(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status); - - static int staticRead(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) { - return static_cast(userData)->readData(outputBuffer, inputBuffer, nFrames, streamTime, status); - } - - int writeData(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status); - - static int staticWrite(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) { - return static_cast(userData)->writeData(outputBuffer, inputBuffer, nFrames, streamTime, status); - } -#elif defined(PORTAUDIO) - int readData(const void* inputBuffer, void* outputBuffer, - unsigned long nFrames, - const PaStreamCallbackTimeInfo* streamTime, - PaStreamCallbackFlags status); - static int staticRead(const void* inputBuffer, void* outputBuffer, unsigned long nFrames, const PaStreamCallbackTimeInfo* streamTime, PaStreamCallbackFlags status, void* userData) { - return ((audioHandler*)userData)->readData(inputBuffer, outputBuffer, nFrames, streamTime, status); - } - - int writeData(const void* inputBuffer, void* outputBuffer, - unsigned long nFrames, - const PaStreamCallbackTimeInfo* streamTime, - PaStreamCallbackFlags status); - static int staticWrite(const void* inputBuffer, void* outputBuffer, unsigned long nFrames, const PaStreamCallbackTimeInfo* streamTime, PaStreamCallbackFlags status, void* userData) { - return ((audioHandler*)userData)->writeData(inputBuffer, outputBuffer, nFrames, streamTime, status); - } - -#else - qint64 readData(char* data, qint64 nBytes); qint64 writeData(const char* data, qint64 nBytes); -#endif - void reinit(); bool isInitialized=false; bool isReady = false; bool audioBuffered = false; -#if defined(RTAUDIO) - RtAudio* audio = Q_NULLPTR; - int audioDevice = 0; - RtAudio::StreamParameters aParams; - RtAudio::StreamOptions options; - RtAudio::DeviceInfo info; -#elif defined(PORTAUDIO) - PaStream* audio = Q_NULLPTR; - PaStreamParameters aParams; - const PaDeviceInfo *info; -#else + QAudioOutput* audioOutput=Q_NULLPTR; QAudioInput* audioInput=Q_NULLPTR; QIODevice* audioDevice=Q_NULLPTR; QAudioFormat format; QAudioDeviceInfo deviceInfo; -#endif + SpeexResamplerState* resampler = Q_NULLPTR; //r8b::CFixedBuffer* resampBufs;