diff options
author | Hoernchen <la@tfc-server.de> | 2013-07-30 14:39:07 +0200 |
---|---|---|
committer | Hoernchen <la@tfc-server.de> | 2013-07-30 14:39:07 +0200 |
commit | fca9f8870f8fa8144a97c02843aa6004ddd26421 (patch) | |
tree | aae540d70445b8a7cab20d3eb4a82f3ecc531bdf /sdrbase | |
parent | 99466ed1d9cf2eadb8b43ea9dbe68ce52aa25ecf (diff) |
at5 audio
requires qtmultimedia5-dev
Diffstat (limited to 'sdrbase')
-rw-r--r-- | sdrbase/audio/audiodeviceinfo.cpp | 59 | ||||
-rw-r--r-- | sdrbase/audio/audiooutput.cpp | 224 | ||||
-rw-r--r-- | sdrbase/audio/portaudioholder.cpp | 18 |
3 files changed, 158 insertions, 143 deletions
diff --git a/sdrbase/audio/audiodeviceinfo.cpp b/sdrbase/audio/audiodeviceinfo.cpp index dacefc3..4d36691 100644 --- a/sdrbase/audio/audiodeviceinfo.cpp +++ b/sdrbase/audio/audiodeviceinfo.cpp @@ -16,39 +16,38 @@ /////////////////////////////////////////////////////////////////////////////////// #include "audio/audiodeviceinfo.h" -#include <portaudio.h> AudioDeviceInfo::AudioDeviceInfo() { - const PaDeviceInfo *deviceInfo; - const PaHostApiInfo *apiInfo; - PaError err; - int numDevices; - int i; - - if((numDevices = Pa_GetDeviceCount()) < 0) { - err = numDevices; - goto failed; - } - - m_devices.clear(); - - for(i = 0; i < numDevices; i++) { - deviceInfo = Pa_GetDeviceInfo(i); - if(deviceInfo->maxOutputChannels >= 2) { - apiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi); - m_devices.append(Device( - QString::fromLatin1(deviceInfo->name), - QString::fromLatin1(apiInfo->name), - i)); - } - } - qDebug("Audio initialisation: %d devices found", m_devices.count()); - return; - -failed: - if(err != paNoError) - qCritical("Audio initialisation failed: %s (%d)", Pa_GetErrorText(err), err); +// const PaDeviceInfo *deviceInfo; +// const PaHostApiInfo *apiInfo; +// PaError err; +// int numDevices; +// int i; +// +// if((numDevices = Pa_GetDeviceCount()) < 0) { +// err = numDevices; +// goto failed; +// } +// +// m_devices.clear(); +// +// for(i = 0; i < numDevices; i++) { +// deviceInfo = Pa_GetDeviceInfo(i); +// if(deviceInfo->maxOutputChannels >= 2) { +// apiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi); +// m_devices.append(Device( +// QString::fromLatin1(deviceInfo->name), +// QString::fromLatin1(apiInfo->name), +// i)); +// } +// } +// qDebug("Audio initialisation: %d devices found", m_devices.count()); +// return; +// +//failed: +// if(err != paNoError) +// qCritical("Audio initialisation failed: %s (%d)", Pa_GetErrorText(err), err); } int AudioDeviceInfo::match(const QString& api, const QString device) const diff --git a/sdrbase/audio/audiooutput.cpp b/sdrbase/audio/audiooutput.cpp index 5599bf2..ddd8f69 100644 --- a/sdrbase/audio/audiooutput.cpp +++ b/sdrbase/audio/audiooutput.cpp @@ -19,17 +19,93 @@ #include "audio/audiooutput.h" #include "audio/audiofifo.h" + +SoundThread::SoundThread(AudioOutput* out, QObject *parent) : + m_generator(out) + , m_audioOutput(0) + , QThread(parent) +{ + start(); + + // Move event processing of SoundThread to this thread + QObject::moveToThread(this); +} + +SoundThread::~SoundThread() +{ + stop(); + //delete m_audioOutput; + quit(); + wait(); +} + +void SoundThread::stop() +{ + m_audioOutput->stop(); +} + +void SoundThread::kill() +{ + m_audioOutput->stop(); + delete m_audioOutput; +} + + +void SoundThread::play() +{ + playInt(); +} + + +void SoundThread::playInt() +{ + + //connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State))); + m_generator->start(); + m_audioOutput->start(m_generator); +} + +void SoundThread::run() +{ + QAudioFormat m_format; + QList<QAudioDeviceInfo> foo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + QAudioDeviceInfo m_device(foo[0]); + + m_format.setSampleRate(44100); + m_format.setChannelCount(2); + m_format.setSampleSize(16); + m_format.setCodec("audio/pcm"); + m_format.setByteOrder(QAudioFormat::LittleEndian); + m_format.setSampleType(QAudioFormat::SignedInt); + + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + if (!info.isFormatSupported(m_format)) { + qWarning("Default format not supported - trying to use nearest"); + m_format = info.nearestFormat(m_format); + } + + //m_generator = new Generator(m_format, DurationSeconds*1000000, ToneFrequencyHz, this); + + delete m_audioOutput; + m_audioOutput = 0; + m_audioOutput = new QAudioOutput(m_device, m_format, this); + //m_audioOutput->setBufferSize(16384); + + exec(); +} + AudioOutput::AudioOutput() : m_mutex(), - m_stream(NULL), m_audioFifos(), - m_sampleRate(0) + m_sampleRate(0), + _sfxThread(this) { } AudioOutput::~AudioOutput() { stop(); + QMetaObject::invokeMethod(&_sfxThread, "kill", Qt::QueuedConnection); QMutexLocker mutexLocker(&m_mutex); for(AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) @@ -40,120 +116,38 @@ AudioOutput::~AudioOutput() bool AudioOutput::start(int device, int rate) { QMutexLocker mutexLocker(&m_mutex); - if(m_stream != NULL) { - Pa_StopStream(m_stream); - Pa_CloseStream(m_stream); - m_stream = NULL; - m_sampleRate = 0; - } for(AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) (*it)->clear(); - PaStreamParameters outputParameters; - const PaStreamInfo* streamInfo; - PaError err; - - outputParameters.device = device; - outputParameters.channelCount = 2; - outputParameters.sampleFormat = paInt16; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - qDebug("AudioOutput: open"); - if((err = Pa_OpenStream(&m_stream, NULL, &outputParameters, rate, 1024, paClipOff, callbackHelper, this)) != paNoError) - goto failed; - - qDebug("AudioOutput: start"); -// m_streamStartTime = Pa_GetStreamTime(m_stream); - if((err = Pa_StartStream(m_stream)) != paNoError) - goto failed; - - streamInfo = Pa_GetStreamInfo(m_stream); - m_sampleRate = streamInfo->sampleRate; - - qDebug("AudioOutput: playback has started (%s @ %d Hz)", Pa_GetDeviceInfo(outputParameters.device)->name, rate); + QMetaObject::invokeMethod(&_sfxThread, "play", Qt::QueuedConnection); return true; - -failed: - qCritical("AudioOutput: playback failed: %s (%d)", Pa_GetErrorText(err), err); - Pa_CloseStream(m_stream); - m_stream = NULL; - m_sampleRate = 0; - return false; } -void AudioOutput::stop() -{ - m_mutex.lock(); - if(m_stream != NULL) { - m_mutex.unlock(); - Pa_StopStream(m_stream); - m_mutex.lock(); - Pa_CloseStream(m_stream); - m_stream = NULL; - m_sampleRate = 0; - qDebug("AudioOutput: stopped"); - } - m_mutex.unlock(); -} -void AudioOutput::addFifo(AudioFifo* audioFifo) +void AudioOutput::start() { - QMutexLocker mutexLocker(&m_mutex); - - m_audioFifos.push_back(audioFifo); + open(QIODevice::ReadOnly); } -void AudioOutput::removeFifo(AudioFifo* audioFifo) +void AudioOutput::stop() { QMutexLocker mutexLocker(&m_mutex); - - m_audioFifos.remove(audioFifo); -} - -/* -int AudioOutput::bufferedSamples() -{ - return (Pa_GetStreamTime(m_stream) - m_streamStartTime) * m_sampleRate; + QMetaObject::invokeMethod(&_sfxThread, "stop", Qt::QueuedConnection); + qDebug("AudioOutput: stopped"); + close(); } -*/ - -int AudioOutput::callbackHelper( - const void *inputBuffer, - void *outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void *userData) -{ - AudioOutput* audioOutput = (AudioOutput*)userData; - if(audioOutput == NULL) - return paAbort; - if(outputBuffer == NULL) - return paAbort; - - return audioOutput->callback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags); -} - -int AudioOutput::callback( - const void* inputBuffer, - void* outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags) +qint64 AudioOutput::readData(char *data, qint64 len) { + int reallen = len/4; QMutexLocker mutexLocker(&m_mutex); - Q_UNUSED(inputBuffer); - Q_UNUSED(timeInfo); - Q_UNUSED(statusFlags); - - if(m_mixBuffer.size() != framesPerBuffer * 2) { - m_mixBuffer.resize(framesPerBuffer * 2); // allocate 2 qint32 per frame (stereo) - if(m_mixBuffer.size() != framesPerBuffer * 2) - return paAbort; + if(m_mixBuffer.size() != reallen * 2) { + m_mixBuffer.resize(reallen * 2); // allocate 2 qint32 per frame (stereo) + if(m_mixBuffer.size() != reallen * 2) + return 0; } memset(m_mixBuffer.data(), 0x00, m_mixBuffer.size() * sizeof(m_mixBuffer[0])); // start with silence @@ -161,10 +155,10 @@ int AudioOutput::callback( // sum up a block from all fifos for(AudioFifos::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) { // use outputBuffer as temp - yes, one memcpy could be saved - uint samples = (*it)->read((quint8*)outputBuffer, framesPerBuffer, 0); - const qint16* src = (const qint16*)outputBuffer; + uint samples = (*it)->read((quint8*)data, reallen, 0); + const qint16* src = (const qint16*)data; std::vector<qint32>::iterator dst = m_mixBuffer.begin(); - for(int i = 0; i < samples; i++) { + for(uint i = 0; i < samples; i++) { *dst += *src; ++src; ++dst; @@ -176,8 +170,8 @@ int AudioOutput::callback( // convert to int16 std::vector<qint32>::const_iterator src = m_mixBuffer.begin(); - qint16* dst = (qint16*)outputBuffer; - for(int i = 0; i < framesPerBuffer; ++i) { + qint16* dst = (qint16*)data; + for(uint i = 0; i < reallen; ++i) { qint32 s = *src++; if(s < -32768) s = -32768; @@ -186,7 +180,29 @@ int AudioOutput::callback( *dst++ = s; } -// m_streamStartTime += (PaTime)framesPerBuffer / (PaTime)m_sampleRate; + //qDebug("AudioOutput: read %d", len); + return len; +} - return paContinue; +qint64 AudioOutput::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + Q_UNUSED(len); + qDebug("AudioOutput: watwatwatwatwat??!"); + return 0; +} + +void AudioOutput::addFifo(AudioFifo* audioFifo) +{ + QMutexLocker mutexLocker(&m_mutex); + + m_audioFifos.push_back(audioFifo); } + +void AudioOutput::removeFifo(AudioFifo* audioFifo) +{ + QMutexLocker mutexLocker(&m_mutex); + + m_audioFifos.remove(audioFifo); +} + diff --git a/sdrbase/audio/portaudioholder.cpp b/sdrbase/audio/portaudioholder.cpp index 1ba31c8..9a58781 100644 --- a/sdrbase/audio/portaudioholder.cpp +++ b/sdrbase/audio/portaudioholder.cpp @@ -1,26 +1,26 @@ #include <QMessageBox> -#include <portaudio.h> +//#include <portaudio.h> #include "audio/portaudioholder.h" PortAudioHolder::PortAudioHolder() : m_initialized(false) { - PaError err; + //PaError err; - if((err = Pa_Initialize()) == paNoError) { + //if((err = Pa_Initialize()) == paNoError) { m_initialized = true; qDebug("PortAudio initialized"); - } else { - qCritical("PortAudio: could not initialise: %s (%d)", Pa_GetErrorText(err), err); - QString error = QObject::tr("PortAudio could not be initialised: %1 (%2)").arg(Pa_GetErrorText(err)).arg(err); - QMessageBox::critical(NULL, "PortAudio failure", error); - } + //} else { + // qCritical("PortAudio: could not initialise: %s (%d)", Pa_GetErrorText(err), err); + // QString error = QObject::tr("PortAudio could not be initialised: %1 (%2)").arg(Pa_GetErrorText(err)).arg(err); + // QMessageBox::critical(NULL, "PortAudio failure", error); + //} } PortAudioHolder::~PortAudioHolder() { if(m_initialized) { - Pa_Terminate(); + //Pa_Terminate(); qDebug("PortAudio terminated"); } } |