added support for PortAudio

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1507 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-08-27 13:51:39 +00:00
parent f539fce7e1
commit d1283bc54e
6 changed files with 684 additions and 3 deletions

View File

@@ -34,6 +34,7 @@ OPTION(WANT_FFTW3F "Include SpectrumAnalyzer plugin" ON)
OPTION(WANT_JACK "Include JACK (Jack Audio Connection Kit) support" ON)
OPTION(WANT_OGGVORBIS "Include OGG/Vorbis support" ON)
OPTION(WANT_PULSEAUDIO "Include PulseAudio support" ON)
OPTION(WANT_PORTAUDIO "Include PortAudio support" ON)
OPTION(WANT_SDL "Include SDL (Simple DirectMedia Layer) support" ON)
OPTION(WANT_SF2 "Include SoundFont2 player plugin" ON)
OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON)
@@ -150,6 +151,22 @@ IF(WANT_STK)
ENDIF(WANT_STK)
# check for PortAudio
IF(WANT_PORTAUDIO)
FIND_PACKAGE(Portaudio)
IF(PORTAUDIO_FOUND)
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)")
ENDIF(PORTAUDIO_FOUND)
ENDIF(WANT_PORTAUDIO)
IF(NOT LMMS_HAVE_PORTAUDIO)
SET(PORTAUDIO_INCLUDE_DIR "")
SET(PORTAUDIO_LIBRARIES "")
ENDIF(NOT LMMS_HAVE_PORTAUDIO)
# check for PulseAudio
IF(WANT_PULSEAUDIO)
FIND_PACKAGE(PulseAudio)
@@ -343,11 +360,11 @@ ADD_SUBDIRECTORY(data)
#
# build LMMS-binary
#
ADD_DEFINITIONS(-D'LIB_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/"' -D'PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/lmms/"' ${PULSEAUDIO_DEFINITIONS})
ADD_DEFINITIONS(-D'LIB_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/"' -D'PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/lmms/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS})
LINK_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/lib ${ASOUND_LIBRARY_DIR} ${JACK_LIBRARY_DIRS} ${SAMPLERATE_LIBRARY_DIRS} ${SNDFILE_LIBRARY_DIRS})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES})
ADD_EXECUTABLE(lmms ${lmms_SOURCES} ${lmms_INCLUDES} ${LIBSAMPLERATE_SOURCES} ${LMMS_ER_H} ${lmms_UI_out} lmmsconfig.h ${WINRC})
IF(LMMS_BUILD_WIN32)
@@ -472,6 +489,7 @@ MESSAGE(
"* ALSA : ${STATUS_ALSA}\n"
"* JACK : ${STATUS_JACK}\n"
"* OSS : ${STATUS_OSS}\n"
"* PortAudio : ${STATUS_PORTAUDIO}\n"
"* PulseAudio : ${STATUS_PULSEAUDIO}\n"
"* SDL : ${STATUS_SDL}\n"
)

View File

@@ -0,0 +1,65 @@
# - Try to find Portaudio
# Once done this will define
#
# PORTAUDIO_FOUND - system has Portaudio
# PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
# PORTAUDIO_LIBRARIES - Link these to use Portaudio
# PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
#
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
# in cache already
set(PORTAUDIO_FOUND TRUE)
else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
find_path(PORTAUDIO_INCLUDE_DIR
NAMES
portaudio.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
find_library(PORTAUDIO_LIBRARY
NAMES
portaudio
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(PORTAUDIO_INCLUDE_DIRS
${PORTAUDIO_INCLUDE_DIR}
)
set(PORTAUDIO_LIBRARIES
${PORTAUDIO_LIBRARY}
)
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
set(PORTAUDIO_FOUND TRUE)
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
if (PORTAUDIO_FOUND)
if (NOT Portaudio_FIND_QUIETLY)
message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
endif (NOT Portaudio_FIND_QUIETLY)
else (PORTAUDIO_FOUND)
if (Portaudio_FIND_REQUIRED)
message(FATAL_ERROR "Could not find Portaudio")
endif (Portaudio_FIND_REQUIRED)
endif (PORTAUDIO_FOUND)
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)

119
include/audio_portaudio.h Normal file
View File

@@ -0,0 +1,119 @@
/*
* audio_portaudio.h - device-class that performs PCM-output via PortAudio
*
* Copyright (c) 2008 Csaba Hruska <csaba.hruska/at/gmail.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _AUDIO_PORTAUDIO_H
#define _AUDIO_PORTAUDIO_H
#include <QtCore/QObject>
#include "lmmsconfig.h"
#include "combobox_model.h"
class audioPortAudioSetupUtil : public QObject
{
Q_OBJECT
public slots:
void updateDevices( void );
void updateChannels( void );
public:
comboBoxModel m_backendModel;
comboBoxModel m_deviceModel;
} ;
#ifdef LMMS_HAVE_PORTAUDIO
#include <portaudio.h>
#include "audio_device.h"
class comboBox;
class lcdSpinBox;
class audioPortAudio : public audioDevice
{
public:
audioPortAudio( bool & _success_ful, mixer * _mixer );
virtual ~audioPortAudio();
inline static QString name( void )
{
return( QT_TRANSLATE_NOOP( "setupWidget",
"PortAudio" ) );
}
int process_callback( const float *_inputBuffer,
float * _outputBuffer,
unsigned long _framesPerBuffer );
class setupWidget : public audioDevice::setupWidget
{
public:
setupWidget( QWidget * _parent );
virtual ~setupWidget();
virtual void saveSettings( void );
private:
comboBox * m_backend;
comboBox * m_device;
lcdSpinBox * m_channels;
audioPortAudioSetupUtil m_setupUtil;
} ;
private:
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void applyQualitySettings( void );
static int _process_callback( const void *_inputBuffer, void *_outputBuffer,
unsigned long _framesPerBuffer,
const PaStreamCallbackTimeInfo* _timeInfo,
PaStreamCallbackFlags _statusFlags,
void *arg );
PaStream * m_paStream;
PaStreamParameters m_outputParameters;
PaStreamParameters m_inputParameters;
bool m_wasPAInitError;
surroundSampleFrame * m_outBuf;
int m_outBuf_pos;
int m_outBuf_size;
bool m_stopped;
QSemaphore m_stop_semaphore;
} ;
#endif
#endif

View File

@@ -10,6 +10,7 @@
#cmakedefine LMMS_HAVE_JACK
#cmakedefine LMMS_HAVE_OGGVORBIS
#cmakedefine LMMS_HAVE_OSS
#cmakedefine LMMS_HAVE_PORTAUDIO
#cmakedefine LMMS_HAVE_PULSEAUDIO
#cmakedefine LMMS_HAVE_SDL
#cmakedefine LMMS_HAVE_STK

View File

@@ -0,0 +1,472 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* audio_portaudio.cpp - device-class that performs PCM-output via PortAudio
*
* Copyright (c) 2008 Csaba Hruska <csaba.hruska/at/gmail.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "audio_portaudio.h"
#ifndef LMMS_HAVE_PORTAUDIO
void audioPortAudioSetupUtil::updateDevices( void )
{
}
void audioPortAudioSetupUtil::updateChannels( void )
{
}
#endif
#ifdef LMMS_HAVE_PORTAUDIO
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include "engine.h"
#include "debug.h"
#include "config_mgr.h"
#include "gui_templates.h"
#include "templates.h"
#include "combobox.h"
#include "lcd_spinbox.h"
audioPortAudio::audioPortAudio( bool & _success_ful, mixer * _mixer ) :
audioDevice( tLimit<ch_cnt_t>(
configManager::inst()->value( "audioportaudio", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ),
_mixer ),
m_outBuf( new surroundSampleFrame[getMixer()->framesPerPeriod()] ),
m_outBuf_pos( 0 ),
m_stop_semaphore( 1 ),
m_wasPAInitError( FALSE )
{
_success_ful = FALSE;
m_outBuf_size = getMixer()->framesPerPeriod();
PaError err = Pa_Initialize();
if( err != paNoError ) {
printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) );
m_wasPAInitError = TRUE;
return;
}
if( Pa_GetDeviceCount() <= 0 )
{
return;
}
const QString& backend = configManager::inst()->value( "audioportaudio",
"backend" );
const QString& device = configManager::inst()->value( "audioportaudio",
"device" );
PaDeviceIndex inDevIdx = -1;
PaDeviceIndex outDevIdx = -1;
const PaDeviceInfo * di;
for( int i = 0; i < Pa_GetDeviceCount(); ++i )
{
di = Pa_GetDeviceInfo( i );
if( di->name == device &&
Pa_GetHostApiInfo( di->hostApi )->name == backend )
{
inDevIdx = i;
outDevIdx = i;
}
}
if( inDevIdx < 0 )
{
inDevIdx = Pa_GetDefaultInputDevice();
}
if( outDevIdx < 0 )
{
outDevIdx = Pa_GetDefaultOutputDevice();
}
double inLatency = (double)getMixer()->framesPerPeriod() / (double)sampleRate();
double outLatency = (double)getMixer()->framesPerPeriod() / (double)sampleRate();
// FIXME: remove this
inLatency = Pa_GetDeviceInfo( inDevIdx )->defaultLowInputLatency;
outLatency = Pa_GetDeviceInfo( outDevIdx )->defaultLowOutputLatency;
int samples = qMax( 1024, (int)getMixer()->framesPerPeriod() );
// Configure output parameters.
m_outputParameters.device = outDevIdx;
m_outputParameters.channelCount = channels();
m_outputParameters.sampleFormat = paFloat32; // 32 bit floating point output
m_outputParameters.suggestedLatency = inLatency;
m_outputParameters.hostApiSpecificStreamInfo = NULL;
// Configure input parameters.
m_inputParameters.device = inDevIdx;
m_inputParameters.channelCount = DEFAULT_CHANNELS;
m_inputParameters.sampleFormat = paFloat32; // 32 bit floating point input
m_inputParameters.suggestedLatency = outLatency;
m_inputParameters.hostApiSpecificStreamInfo = NULL;
// Open an audio I/O stream.
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 );
if( err != paNoError )
{
printf( "Couldn't open PortAudio: %s\n", Pa_GetErrorText( err ) );
return;
}
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 );
m_stop_semaphore.acquire();
m_supportsCapture = TRUE;
_success_ful = TRUE;
}
audioPortAudio::~audioPortAudio()
{
stopProcessing();
m_stop_semaphore.release();
if( !m_wasPAInitError )
{
Pa_Terminate();
}
delete[] m_outBuf;
}
void audioPortAudio::startProcessing( void )
{
PaError err = Pa_StartStream( m_paStream );
if( err != paNoError )
{
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
return;
}
m_stopped = FALSE;
}
void audioPortAudio::stopProcessing( void )
{
if( Pa_IsStreamActive( m_paStream ) )
{
m_stop_semaphore.acquire();
PaError err = Pa_CloseStream( m_paStream );
if( err != paNoError )
{
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
}
}
}
void audioPortAudio::applyQualitySettings( void )
{
if( hqAudio() )
{
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 );
if( err != paNoError )
{
printf( "Couldn't open PortAudio: %s\n", Pa_GetErrorText( err ) );
return;
}
}
audioDevice::applyQualitySettings();
}
int audioPortAudio::process_callback(
const float *_inputBuffer,
float * _outputBuffer,
unsigned long _framesPerBuffer )
{
getMixer()->pushInputFrames( (sampleFrame*)_inputBuffer, _framesPerBuffer );
if( m_stopped )
{
memset( _outputBuffer, 0, _framesPerBuffer *
channels() * sizeof(float) );
return 0;
}
while( _framesPerBuffer )
{
if( m_outBuf_pos == 0 )
{
// frames depend on the sample rate
const fpp_t frames = getNextBuffer( m_outBuf );
if( !frames )
{
m_stopped = TRUE;
m_stop_semaphore.release();
memset( _outputBuffer, 0, _framesPerBuffer *
channels() * sizeof(float) );
return 0;
}
m_outBuf_size = frames;
}
const int min_len = tMin( (int)_framesPerBuffer,
m_outBuf_size - m_outBuf_pos );
float master_gain = getMixer()->masterGain();
for( fpp_t frame = 0; frame < min_len; ++frame )
{
for( ch_cnt_t chnl = 0; chnl < channels(); ++chnl )
{
( _outputBuffer + frame * channels() )[chnl] =
mixer::clip( m_outBuf[frame][chnl] *
master_gain );
}
}
_outputBuffer += min_len * channels();
_framesPerBuffer -= min_len;
m_outBuf_pos += min_len;
m_outBuf_pos %= m_outBuf_size;
}
}
int audioPortAudio::_process_callback(
const void *_inputBuffer,
void * _outputBuffer,
unsigned long _framesPerBuffer,
const PaStreamCallbackTimeInfo * _timeInfo,
PaStreamCallbackFlags _statusFlags,
void * _arg )
{
Q_UNUSED(_timeInfo);
Q_UNUSED(_statusFlags);
audioPortAudio * _this = static_cast<audioPortAudio *> (_arg);
_this->process_callback( (const float*)_inputBuffer,
(float*)_outputBuffer, _framesPerBuffer );
return 0;
}
void audioPortAudioSetupUtil::updateDevices( void )
{
PaError err = Pa_Initialize();
if( err != paNoError ) {
printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) );
return;
}
// get active backend
const QString& backend = m_backendModel.currentText();
int hostApi = 0;
const PaHostApiInfo * hi;
for( int i = 0; i < Pa_GetHostApiCount(); ++i )
{
hi = Pa_GetHostApiInfo( i );
if( backend == hi->name )
{
hostApi = i;
break;
}
}
// get devices for selected backend
m_deviceModel.clear();
const PaDeviceInfo * di;
for( int i = 0; i < Pa_GetDeviceCount(); ++i )
{
di = Pa_GetDeviceInfo( i );
if( di->hostApi == hostApi )
{
m_deviceModel.addItem( di->name );
}
}
Pa_Terminate();
}
void audioPortAudioSetupUtil::updateChannels( void )
{
PaError err = Pa_Initialize();
if( err != paNoError ) {
printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) );
return;
}
// get active backend
Pa_Terminate();
}
audioPortAudio::setupWidget::setupWidget( QWidget * _parent ) :
audioDevice::setupWidget( audioPortAudio::name(), _parent )
{
m_backend = new comboBox( this, "BACKEND" );
m_backend->setGeometry( 52, 15, 120, 20 );
QLabel * backend_lbl = new QLabel( tr( "BACKEND" ), this );
backend_lbl->setFont( pointSize<6>( backend_lbl->font() ) );
backend_lbl->move( 10, 17 );
m_device = new comboBox( this, "DEVICE" );
m_device->setGeometry( 52, 35, 250, 20 );
QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this );
dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) );
dev_lbl->move( 10, 37 );
lcdSpinBoxModel * m = new lcdSpinBoxModel( );
m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS );
m->setStep( 2 );
m->setValue( configManager::inst()->value( "audioportaudio",
"channels" ).toInt() );
m_channels = new lcdSpinBox( 1, this );
m_channels->setModel( m );
m_channels->setLabel( tr( "CHANNELS" ) );
m_channels->move( 308, 20 );
// Setup models
PaError err = Pa_Initialize();
if( err != paNoError ) {
printf( "Couldn't initialize PortAudio: %s\n", Pa_GetErrorText( err ) );
return;
}
// todo: setup backend model
const PaHostApiInfo * hi;
for( int i = 0; i < Pa_GetHostApiCount(); ++i )
{
hi = Pa_GetHostApiInfo( i );
m_setupUtil.m_backendModel.addItem( hi->name );
}
Pa_Terminate();
const QString& backend = configManager::inst()->value( "audioportaudio",
"backend" );
const QString& device = configManager::inst()->value( "audioportaudio",
"device" );
int i = tMax( 0, m_setupUtil.m_backendModel.findText( backend ) );
m_setupUtil.m_backendModel.setValue( i );
m_setupUtil.updateDevices();
i = tMax( 0, m_setupUtil.m_deviceModel.findText( device ) );
m_setupUtil.m_deviceModel.setValue( i );
connect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ),
&m_setupUtil, SLOT( updateDevices() ) );
connect( &m_setupUtil.m_deviceModel, SIGNAL( dataChanged() ),
&m_setupUtil, SLOT( updateChannels() ) );
m_backend->setModel( &m_setupUtil.m_backendModel );
m_device->setModel( &m_setupUtil.m_deviceModel );
}
audioPortAudio::setupWidget::~setupWidget()
{
disconnect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ),
&m_setupUtil, SLOT( updateDevices() ) );
disconnect( &m_setupUtil.m_deviceModel, SIGNAL( dataChanged() ),
&m_setupUtil, SLOT( updateChannels() ) );
}
void audioPortAudio::setupWidget::saveSettings( void )
{
configManager::inst()->setValue( "audioportaudio", "backend",
m_setupUtil.m_backendModel.currentText() );
configManager::inst()->setValue( "audioportaudio", "device",
m_setupUtil.m_deviceModel.currentText() );
configManager::inst()->setValue( "audioportaudio", "channels",
QString::number( m_channels->value<int>() ) );
}
#endif
#include "moc_audio_portaudio.cxx"
#endif

View File

@@ -55,6 +55,7 @@
#include "audio_alsa.h"
#include "audio_jack.h"
#include "audio_oss.h"
#include "audio_portaudio.h"
#include "audio_pulseaudio.h"
#include "audio_sdl.h"
#include "audio_dummy.h"
@@ -455,6 +456,11 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
new audioPulseAudio::setupWidget( asw );
#endif
#ifdef LMMS_HAVE_PORTAUDIO
m_audioIfaceSetupWidgets[audioPortAudio::name()] =
new audioPortAudio::setupWidget( asw );
#endif
#ifdef LMMS_HAVE_SDL
m_audioIfaceSetupWidgets[audioSDL::name()] =
new audioSDL::setupWidget( asw );