From 3ce92c4f247fddf15da6207fbb2db6b6bfc67b2c Mon Sep 17 00:00:00 2001 From: Csaba Hruska Date: Wed, 27 Aug 2008 18:51:43 +0000 Subject: [PATCH] portaudio V18 and V19 are supported now. git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1511 0778d3d1-df1d-0410-868b-ea421aaaa00d --- CMakeLists.txt | 2 +- include/audio_portaudio.h | 37 +++++++++++- src/core/audio/audio_portaudio.cpp | 92 +++++++++++++++++++++++++----- 3 files changed, 114 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53ef39695..c71560e78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ IF(WANT_PORTAUDIO) SET(LMMS_HAVE_PORTAUDIO TRUE) SET(STATUS_PORTAUDIO "OK") ELSE(PORTAUDIO_FOUND) - SET(STATUS_PORTAUDIO "not found, please install portaudio19-dev (or similiar, version >= 1.9)") + SET(STATUS_PORTAUDIO "not found, please install libportaudio-dev (or similiar, version >= 1.8)") ENDIF(PORTAUDIO_FOUND) ENDIF(WANT_PORTAUDIO) IF(NOT LMMS_HAVE_PORTAUDIO) diff --git a/include/audio_portaudio.h b/include/audio_portaudio.h index 9f6c639ef..773bc3b1f 100644 --- a/include/audio_portaudio.h +++ b/include/audio_portaudio.h @@ -50,6 +50,12 @@ public: #include "audio_device.h" +#if defined paNeverDropInput || defined paNonInterleaved +# define PORTAUDIO_V19 +#else +# define PORTAUDIO_V18 +#endif + class comboBox; class lcdSpinBox; @@ -94,15 +100,42 @@ private: virtual void stopProcessing( void ); virtual void applyQualitySettings( void ); - static int _process_callback( const void *_inputBuffer, void *_outputBuffer, +#ifdef PORTAUDIO_V19 + static int _process_callback( const void *_inputBuffer, void * _outputBuffer, unsigned long _framesPerBuffer, - const PaStreamCallbackTimeInfo* _timeInfo, + const PaStreamCallbackTimeInfo * _timeInfo, PaStreamCallbackFlags _statusFlags, void *arg ); +#else + +#define Pa_GetDeviceCount Pa_CountDevices +#define Pa_GetDefaultInputDevice Pa_GetDefaultInputDeviceID +#define Pa_GetDefaultOutputDevice Pa_GetDefaultOutputDeviceID +#define Pa_IsStreamActive Pa_StreamActive + + static int _process_callback( void * _inputBuffer, void * _outputBuffer, + unsigned long _framesPerBuffer, PaTimestamp _outTime, void * _arg ); + + + typedef double PaTime; + typedef PaDeviceID PaDeviceIndex; + + typedef struct PaStreamParameters + { + PaDeviceIndex device; + int channelCount; + PaSampleFormat sampleFormat; + PaTime suggestedLatency; + void *hostApiSpecificStreamInfo; + + } PaStreamParameters; +#endif + PaStream * m_paStream; PaStreamParameters m_outputParameters; PaStreamParameters m_inputParameters; + bool m_wasPAInitError; surroundSampleFrame * m_outBuf; diff --git a/src/core/audio/audio_portaudio.cpp b/src/core/audio/audio_portaudio.cpp index c27134285..4a992f07a 100644 --- a/src/core/audio/audio_portaudio.cpp +++ b/src/core/audio/audio_portaudio.cpp @@ -53,8 +53,6 @@ void audioPortAudioSetupUtil::updateChannels( void ) #include "lcd_spinbox.h" - - audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : audioDevice( tLimit( configManager::inst()->value( "audioportaudio", "channels" ).toInt(), @@ -93,8 +91,12 @@ audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : for( int i = 0; i < Pa_GetDeviceCount(); ++i ) { di = Pa_GetDeviceInfo( i ); +#ifdef PORTAUDIO_V19 if( di->name == device && Pa_GetHostApiInfo( di->hostApi )->name == backend ) +#else + if( di->name == device ) +#endif { inDevIdx = i; outDevIdx = i; @@ -115,8 +117,10 @@ audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : double outLatency = (double)getMixer()->framesPerPeriod() / (double)sampleRate(); // FIXME: remove this +#ifdef PORTAUDIO_V19 inLatency = Pa_GetDeviceInfo( inDevIdx )->defaultLowInputLatency; outLatency = Pa_GetDeviceInfo( outDevIdx )->defaultLowOutputLatency; +#endif int samples = qMax( 1024, (int)getMixer()->framesPerPeriod() ); // Configure output parameters. @@ -134,6 +138,7 @@ audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : m_inputParameters.hostApiSpecificStreamInfo = NULL; // Open an audio I/O stream. +#ifdef PORTAUDIO_V19 err = Pa_OpenStream( &m_paStream, &m_inputParameters, // The input parameter @@ -143,6 +148,24 @@ audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : paNoFlag, // Don't use any flags _process_callback, // our callback function this ); +#else + err = Pa_OpenStream( + &m_paStream, + m_inputParameters.device, + m_inputParameters.channelCount, + m_inputParameters.sampleFormat, + NULL, + m_outputParameters.device, + m_outputParameters.channelCount, + m_outputParameters.sampleFormat, + NULL, + sampleRate(), + samples, + 0, + paNoFlag, // Don't use any flags + _process_callback, // our callback function + this ); +#endif if( err != paNoError ) { @@ -150,8 +173,14 @@ audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) : return; } + // FIXME: remove this debug info +#ifdef PORTAUDIO_V19 printf( "Input device: '%s' backend: '%s'\n", Pa_GetDeviceInfo( inDevIdx )->name, Pa_GetHostApiInfo( Pa_GetDeviceInfo( inDevIdx )->hostApi )->name ); printf( "Output device: '%s' backend: '%s'\n", Pa_GetDeviceInfo( outDevIdx )->name, Pa_GetHostApiInfo( Pa_GetDeviceInfo( outDevIdx )->hostApi )->name ); +#else + printf( "Input device: '%s'\n", Pa_GetDeviceInfo( inDevIdx )->name ); + printf( "Output device: '%s'\n", Pa_GetDeviceInfo( outDevIdx )->name ); +#endif m_stop_semaphore.acquire(); @@ -220,15 +249,34 @@ void audioPortAudio::applyQualitySettings( void ) setSampleRate( engine::getMixer()->processingSampleRate() ); int samples = qMax( 1024, (int)getMixer()->framesPerPeriod() ); - PaError err = Pa_OpenStream( - &m_paStream, - &m_inputParameters, // The input parameter - &m_outputParameters, // The outputparameter - sampleRate(), - samples, - paNoFlag, // Don't use any flags - _process_callback, // our callback function - this ); +#ifdef PORTAUDIO_V19 + PaError err = Pa_OpenStream( + &m_paStream, + &m_inputParameters, // The input parameter + &m_outputParameters, // The outputparameter + sampleRate(), + samples, + paNoFlag, // Don't use any flags + _process_callback, // our callback function + this ); +#else + PaError err = Pa_OpenStream( + &m_paStream, + m_inputParameters.device, + m_inputParameters.channelCount, + m_inputParameters.sampleFormat, + NULL, + m_outputParameters.device, + m_outputParameters.channelCount, + m_outputParameters.sampleFormat, + NULL, + sampleRate(), + samples, + 0, + paNoFlag, // Don't use any flags + _process_callback, // our callback function + this ); +#endif if( err != paNoError ) { @@ -295,6 +343,7 @@ int audioPortAudio::process_callback( +#ifdef PORTAUDIO_V19 int audioPortAudio::_process_callback( const void *_inputBuffer, void * _outputBuffer, @@ -305,6 +354,11 @@ int audioPortAudio::_process_callback( { Q_UNUSED(_timeInfo); Q_UNUSED(_statusFlags); +#else +int audioPortAudio::_process_callback( void *_inputBuffer, void *_outputBuffer, + unsigned long _framesPerBuffer, PaTimestamp _outTime, void *_arg ) +{ +#endif audioPortAudio * _this = static_cast (_arg); _this->process_callback( (const float*)_inputBuffer, @@ -315,7 +369,6 @@ int audioPortAudio::_process_callback( - void audioPortAudioSetupUtil::updateDevices( void ) { PaError err = Pa_Initialize(); @@ -323,6 +376,7 @@ void audioPortAudioSetupUtil::updateDevices( void ) printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) ); return; } +#ifdef PORTAUDIO_V19 // get active backend const QString& backend = m_backendModel.currentText(); int hostApi = 0; @@ -336,6 +390,7 @@ void audioPortAudioSetupUtil::updateDevices( void ) break; } } +#endif // get devices for selected backend m_deviceModel.clear(); @@ -343,10 +398,14 @@ void audioPortAudioSetupUtil::updateDevices( void ) for( int i = 0; i < Pa_GetDeviceCount(); ++i ) { di = Pa_GetDeviceInfo( i ); +#ifdef PORTAUDIO_V19 if( di->hostApi == hostApi ) { m_deviceModel.addItem( di->name ); } +#else + m_deviceModel.addItem( di->name ); +#endif } Pa_Terminate(); } @@ -377,7 +436,11 @@ audioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : QLabel * backend_lbl = new QLabel( tr( "BACKEND" ), this ); backend_lbl->setFont( pointSize<6>( backend_lbl->font() ) ); backend_lbl->move( 10, 17 ); - +#ifndef PORTAUDIO_V19 + m_backend->hide(); + backend_lbl->hide(); +#endif + m_device = new comboBox( this, "DEVICE" ); m_device->setGeometry( 52, 35, 250, 20 ); @@ -404,13 +467,14 @@ audioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : } // todo: setup backend model +#ifdef PORTAUDIO_V19 const PaHostApiInfo * hi; for( int i = 0; i < Pa_GetHostApiCount(); ++i ) { hi = Pa_GetHostApiInfo( i ); m_setupUtil.m_backendModel.addItem( hi->name ); } - +#endif Pa_Terminate();