summaryrefslogtreecommitdiffstats
path: root/sdrbase
diff options
context:
space:
mode:
authorHoernchen <la@tfc-server.de>2013-07-30 14:39:07 +0200
committerHoernchen <la@tfc-server.de>2013-07-30 14:39:07 +0200
commitfca9f8870f8fa8144a97c02843aa6004ddd26421 (patch)
treeaae540d70445b8a7cab20d3eb4a82f3ecc531bdf /sdrbase
parent99466ed1d9cf2eadb8b43ea9dbe68ce52aa25ecf (diff)
at5 audio
requires qtmultimedia5-dev
Diffstat (limited to 'sdrbase')
-rw-r--r--sdrbase/audio/audiodeviceinfo.cpp59
-rw-r--r--sdrbase/audio/audiooutput.cpp224
-rw-r--r--sdrbase/audio/portaudioholder.cpp18
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");
}
}