kopia lustrzana https://gitlab.com/eliggett/wfview
Add portaudio support
rodzic
43efadbeaa
commit
0c7bc17382
106
audiohandler.cpp
106
audiohandler.cpp
|
@ -8,6 +8,10 @@
|
|||
#include "logcategories.h"
|
||||
#include "ulaw.h"
|
||||
|
||||
#if defined(Q_OS_WIN) && defined(PORTAUDIO)
|
||||
#include <objbase.h>
|
||||
#endif
|
||||
|
||||
|
||||
audioHandler::audioHandler(QObject* parent)
|
||||
{
|
||||
|
@ -29,6 +33,7 @@ audioHandler::~audioHandler()
|
|||
}
|
||||
delete audio;
|
||||
#elif defined(PORTAUDIO)
|
||||
Pa_StopStream(audio);
|
||||
#else
|
||||
stop();
|
||||
#endif
|
||||
|
@ -184,6 +189,79 @@ bool audioHandler::init(audioSetup setupIn)
|
|||
|
||||
|
||||
#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;
|
||||
aParams.suggestedLatency = info->defaultLowInputLatency;
|
||||
aParams.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
// Always use the "preferred" sample rate
|
||||
// We can always resample if needed
|
||||
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;
|
||||
}
|
||||
qInfo(logAudio()) << " Channels:" << devChannels;
|
||||
if (devChannels > 2) {
|
||||
devChannels = 2;
|
||||
}
|
||||
aParams.channelCount = devChannels;
|
||||
|
||||
qInfo(logAudio()) << " chunkSize: " << chunkSize;
|
||||
|
||||
if (setup.isinput) {
|
||||
err=Pa_OpenStream(&audio, &aParams, 0, this->nativeSampleRate, this->chunkSize, paNoFlag, &audioHandler::staticWrite, (void*)this);
|
||||
//err = Pa_OpenDefaultStream(&audio, 2, 0, paFloat32, this->nativeSampleRate, this->chunkSize, &audioHandler::staticWrite, (void*)this);
|
||||
}
|
||||
else {
|
||||
err=Pa_OpenStream(&audio, 0, &aParams, this->nativeSampleRate, this->chunkSize, paNoFlag, &audioHandler::staticRead, (void*)this);
|
||||
//err = Pa_OpenDefaultStream(&audio, 0, 2, paFloat32, this->nativeSampleRate, this->chunkSize, &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);
|
||||
}
|
||||
//qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "detected latency:" << audio->getStreamLatency();
|
||||
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
format.setSampleSize(16);
|
||||
|
@ -323,7 +401,8 @@ void audioHandler::setVolume(unsigned char volume)
|
|||
/// <param name="maxlen"></param>
|
||||
/// <returns></returns>
|
||||
#if defined(RTAUDIO)
|
||||
int audioHandler::readData(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status)
|
||||
int audioHandler::readData(void* outputBuffer, void* inputBuffer,
|
||||
unsigned int nFrames, double streamTime, RtAudioStreamStatus status)
|
||||
{
|
||||
Q_UNUSED(inputBuffer);
|
||||
Q_UNUSED(streamTime);
|
||||
|
@ -332,6 +411,15 @@ int audioHandler::readData(void* outputBuffer, void* inputBuffer, unsigned int n
|
|||
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)
|
||||
{
|
||||
|
@ -411,13 +499,15 @@ qint64 audioHandler::readData(char* buffer, qint64 nBytes)
|
|||
#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)
|
||||
int audioHandler::writeData(void* outputBuffer, void* inputBuffer,
|
||||
unsigned int nFrames, double streamTime, RtAudioStreamStatus status)
|
||||
{
|
||||
Q_UNUSED(outputBuffer);
|
||||
Q_UNUSED(streamTime);
|
||||
|
@ -425,6 +515,15 @@ int audioHandler::writeData(void* outputBuffer, void* inputBuffer, unsigned int
|
|||
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)
|
||||
{
|
||||
|
@ -462,6 +561,7 @@ qint64 audioHandler::writeData(const char* data, qint64 nBytes)
|
|||
#if defined(RTAUDIO)
|
||||
return 0;
|
||||
#elif defined(PORTAUDIO)
|
||||
return 0;
|
||||
#else
|
||||
return nBytes;
|
||||
#endif
|
||||
|
@ -586,7 +686,7 @@ void audioHandler::incomingAudio(audioPacket inPacket)
|
|||
|
||||
if (!ringBuf->try_write(inPacket))
|
||||
{
|
||||
qDebug(logAudio()) << "Buffer full! capacity:" << ringBuf->capacity() << "length" << ringBuf->size();
|
||||
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Buffer full! capacity:" << ringBuf->capacity() << "length" << ringBuf->size();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,14 @@
|
|||
#include <QtMath>
|
||||
|
||||
#if defined(RTAUDIO)
|
||||
#ifdef Q_OS_WIN
|
||||
#include "RtAudio.h"
|
||||
#else
|
||||
#include "rtaudio/RtAudio.h"
|
||||
#endif
|
||||
#elif defined (PORTAUDIO)
|
||||
#include "portaudio.h"
|
||||
#error "PORTAUDIO is not currently supported"
|
||||
//#error "PORTAUDIO is not currently supported"
|
||||
#else
|
||||
#include <QAudioOutput>
|
||||
#include <QAudioFormat>
|
||||
|
@ -67,9 +71,8 @@ struct audioSetup {
|
|||
quint8 codec;
|
||||
bool ulaw;
|
||||
bool isinput;
|
||||
#if defined(RTAUDIO)
|
||||
#if defined(RTAUDIO) || defined(PORTAUDIO)
|
||||
int port;
|
||||
#elif defined(PORTAUDIO)
|
||||
#else
|
||||
QAudioDeviceInfo port;
|
||||
#endif
|
||||
|
@ -137,6 +140,21 @@ private:
|
|||
return static_cast<audioHandler*>(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);
|
||||
|
@ -154,6 +172,9 @@ private:
|
|||
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;
|
||||
|
|
38
wfmain.cpp
38
wfmain.cpp
|
@ -106,6 +106,11 @@ wfmain::~wfmain()
|
|||
delete rpt;
|
||||
delete ui;
|
||||
delete settings;
|
||||
|
||||
#if defined(PORTAUDIO)
|
||||
Pa_Terminate();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void wfmain::closeEvent(QCloseEvent *event)
|
||||
|
@ -1023,6 +1028,35 @@ void wfmain::setAudioDevicesUI()
|
|||
|
||||
#elif defined(PORTAUDIO)
|
||||
// Use PortAudio device enumeration
|
||||
|
||||
PaError err;
|
||||
|
||||
err = Pa_Initialize();
|
||||
|
||||
if (err != paNoError)
|
||||
{
|
||||
qInfo(logAudio()) << "ERROR: Cannot initialize Portaudio";
|
||||
}
|
||||
|
||||
qInfo(logAudio()) << "PortAudio version: " << Pa_GetVersionInfo()->versionText;
|
||||
|
||||
int numDevices;
|
||||
numDevices = Pa_GetDeviceCount();
|
||||
qInfo(logAudio()) << "Pa_CountDevices returned" << numDevices;
|
||||
|
||||
const PaDeviceInfo* info;
|
||||
for (int i = 0; i < numDevices; i++)
|
||||
{
|
||||
info = Pa_GetDeviceInfo(i);
|
||||
if (info->maxInputChannels > 0) {
|
||||
qInfo(logAudio()) << (i == Pa_GetDefaultInputDevice() ? "*" : " ") << "(" << i << ") Output Device : " << info->name;
|
||||
ui->audioInputCombo->addItem(info->name, i);
|
||||
}
|
||||
if (info->maxOutputChannels > 0) {
|
||||
qInfo(logAudio()) << (i == Pa_GetDefaultOutputDevice() ? "*" : " ") << "(" << i << ") Input Device : " << info->name;
|
||||
ui->audioOutputCombo->addItem(info->name, i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// If no external library is configured, use QTMultimedia
|
||||
|
@ -1466,6 +1500,7 @@ void wfmain::loadSettings()
|
|||
#if defined(RTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioOutputCombo->currentData();
|
||||
rxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
@ -1482,6 +1517,7 @@ void wfmain::loadSettings()
|
|||
#if defined(RTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioInputCombo->currentData();
|
||||
txSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
@ -4223,6 +4259,7 @@ void wfmain::on_audioOutputCombo_currentIndexChanged(int value)
|
|||
#if defined(RTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioOutputCombo->itemData(value);
|
||||
rxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
@ -4236,6 +4273,7 @@ void wfmain::on_audioInputCombo_currentIndexChanged(int value)
|
|||
#if defined(RTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioInputCombo->itemData(value);
|
||||
txSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
|
|
@ -46,7 +46,7 @@ DEFINES += PREFIX=\\\"$$PREFIX\\\"
|
|||
|
||||
# Choose audio system, uses QTMultimedia if both are commented out.
|
||||
# DEFINES += RTAUDIO
|
||||
# DEFINES += PORTAUDIO
|
||||
DEFINES += PORTAUDIO
|
||||
|
||||
contains(DEFINES, RTAUDIO) {
|
||||
# RTAudio defines
|
||||
|
|
Ładowanie…
Reference in New Issue