--- a/LastFM.pro +++ b/LastFM.pro @@ -42,12 +42,12 @@ src/libFingerprint/fplib/pro_qmake/fplib.pro \ src/libFingerprint/ \ src/Bootstrapper/ITunesDevice - SUBDIRS += src/output/RtAudio + SUBDIRS += src/output/RtAudio \ + src/output/portAudio UNAME = $$system(uname -s) contains ( UNAME, [Ll]inux ) { - SUBDIRS -= src/output/RtAudio SUBDIRS += src/output/alsa-playback } } --- a/src/AudioController.cpp +++ b/src/AudioController.cpp @@ -32,6 +32,8 @@ #include "output/RtAudio/rtaudioplayback.h" +#include + #include #include #include @@ -126,9 +128,14 @@ this, SLOT ( setStreamData( long, int ) ), Qt::DirectConnection ); - connect( m_output, SIGNAL( error( int, const QString& ) ), + // Each of the available audio plugins needs its error signal connected + QListIterator i( m_audioPlugins); + while ( i.hasNext() ) + { + connect( i.next(), SIGNAL( error( int, const QString& ) ), parent(), SLOT ( onStreamingError( int, const QString& ) ), Qt::QueuedConnection ); + } connect( m_timer, SIGNAL( timeout() ), this, SLOT ( onTimerTimeout() ), @@ -171,18 +178,104 @@ m_transcode->setBufferCapacity( kDecodedBufferMinSize ); - #ifdef WIN32 - m_output = qobject_cast( loadPlugin( "rtaudioplayback" ) ); - #elif defined REALLY_LINUX - m_output = qobject_cast( loadPlugin( "output_alsa" ) ); - #elif defined LINUX - m_output = qobject_cast( loadPlugin( "rtaudioplayback" ) ); - #else - m_output = qobject_cast( loadPlugin( "output_portaudio" ) ); - #endif + QString dirPath = MooseUtils::servicePath( "" ); + QDir audioDir ( dirPath ); + foreach ( QString fileName, audioDir.entryList( QDir::Files ) ) + { + if ( fileName.contains( "srv_output_" ) ) + { + QObject* audioPlugin = QPluginLoader( audioDir.absoluteFilePath( fileName ) ).instance(); + if ( audioPlugin ) + { + OutputInterface *oInterface = qobject_cast( audioPlugin ); + if ( oInterface ) + { + m_soundSystems << oInterface->soundSystems(); + m_audioPlugins << oInterface; + } + } + } + } + + m_soundSystems.sort(); + + bool pluginSelected = selectAudioPlugin( The::settings().soundSystem() ); + + if ( !pluginSelected ) + return false; + + return true; +} + + +QStringList +AudioControllerThread::getSoundSystems() +{ + return m_soundSystems; +} + + +bool +AudioControllerThread::selectAudioPlugin( QString system ) +{ + m_output = 0; + + // First try to get a plugin that matches the settings + QListIterator i( m_audioPlugins); + while ( i.hasNext() ) + { + OutputInterface* iface = i.next(); + + QStringListIterator s( iface->soundSystems() ); + while ( s.hasNext()) + { + QString availSys = s.next(); + if ( availSys == system ) + { + m_output = iface; + break; + } + } + if ( m_output != 0 ) + break; + } + + // The preferred plugin we want isn't there, if ( m_output == 0 ) - return false; + { + // so use the first device of the first available system + if ( m_soundSystems.size() > 0 ) + { + i.toFront(); + while ( i.hasNext() ) + { + OutputInterface* iface = i.next(); + // (and match exactly because contains isn't good enough) + QStringListIterator s( iface->soundSystems() ); + while ( s.hasNext()) + { + QString availSys = s.next(); + if ( availSys == m_soundSystems.at( 0 ) ) + { + m_output = iface; + The::settings().setSoundCard( 0 ); + The::settings().setSoundSystem( m_soundSystems.at( 0 ) ); + break; + } + } + if ( m_output != 0 ) + break; + } + } + // unless there's nothing to choose from. + else + { + emit error( Radio_PluginLoadFailed, + tr( "Couldn't load radio service '%1'. The radio will not work." ).arg( system ) ); + return false; + } + } m_proxyOutput = new ProxyOutput(); @@ -190,6 +283,25 @@ } +QStringList +AudioControllerThread::setSoundSystem( QString system ) +{ + QStringList devices; + bool pluginSelected; + + if ( m_output ) + m_output->closeAudio(); + pluginSelected = selectAudioPlugin ( system ); + if ( pluginSelected ) + { + m_output->initAudio( 44100, 2, system ); + devices = m_output->devices(); + m_output->closeAudio(); + } + return devices; +} + + QObject* AudioControllerThread::loadPlugin( QString name ) { @@ -546,11 +658,13 @@ m_thread.m_initialised.wait( &m_mutex ); locker.unlock(); + // Safe to copy these values out here + m_soundSystems = m_thread.getSoundSystems(); if ( m_thread.m_output != 0 ) { - // Safe to copy these values out here - m_soundSystems = m_thread.m_output->soundSystems(); + m_thread.m_output->initAudio( 44100, 2, m_thread.m_output->currentSoundSystem() ); m_devices = m_thread.m_output->devices(); + m_thread.m_output->closeAudio(); } } @@ -574,6 +688,14 @@ void AudioController::play() { + if ( m_thread.m_output ) + { + bool initialized = m_thread.m_output->initAudio( 44100, 2, m_thread.m_output->currentSoundSystem() ); + // This prevents an assert on invalid state in httpinput + if ( ! initialized ) + return; + } + loadNext(); } @@ -582,6 +704,14 @@ AudioController::play( RadioPlaylist& playlist ) { m_playlist = &playlist; + if ( m_thread.m_output ) + { + bool initialized = m_thread.m_output->initAudio( 44100, 2, m_thread.m_output->currentSoundSystem() ); + // This prevents an assert on invalid state in httpinput + if ( ! initialized ) + return; + } + loadNext(); // We reset the automatically managed buffer size on station change @@ -711,6 +841,21 @@ } + +void +AudioController::setSoundSystem( QString system ) +{ + m_devices = m_thread.setSoundSystem( system ); +} + + +void +AudioController::resetAudio() +{ + m_devices = m_thread.setSoundSystem( The::settings().soundSystem() ); +} + + void AudioController::loadNext() { @@ -747,6 +892,22 @@ QCoreApplication::postEvent( m_thread.eventHandler(), e ); setState( State_Stopping ); + + do + { + #ifdef WIN32 + Sleep( 10 ); + #else + usleep( 100 ); + #endif + } + while ( m_thread.state() != State_Stopped && + m_thread.state() != State_Uninitialised && + m_thread.state() != State_Handshaking && + m_thread.state() != State_Handshaken ); + + if ( m_thread.m_output ) + m_thread.m_output->closeAudio(); } --- a/src/AudioController.h +++ b/src/AudioController.h @@ -146,6 +146,9 @@ virtual bool event( QEvent* e ); + QStringList setSoundSystem( QString system ); + QStringList getSoundSystems(); + signals: /** \brief Gets emitted frequently during playback to signal the current position in the stream. * \param seconds How many seconds elapsed since this stream started. */ @@ -184,6 +187,9 @@ TranscodeInterface* m_transcode; OutputInterface* m_output; ProxyOutput* m_proxyOutput; + QListm_audioPlugins; + QStringList m_soundSystems; + bool selectAudioPlugin( QString system ); AudioControllerEventHandler* m_handler; @@ -284,6 +290,10 @@ /** \brief Returns the streamer URL of the currently playing track. */ const QString& currentTrackUrl() const { return m_currentTrackUrl; } + void setSoundSystem( QString system ); + + void resetAudio(); + public slots: /** \brief Loads and starts this file instantly. * \param url The url that you want to load. Can be a file path or --- a/src/interfaces/OutputInterface.h +++ b/src/interfaces/OutputInterface.h @@ -39,7 +39,10 @@ /** \brief Initialises the audio device. * \param sampelRate The sample-rate that will be used for audio data. * \param channels How many channels will be used. */ - virtual void initAudio( long sampleRate, int channels ) = 0; + virtual bool initAudio( long sampleRate, int channels, QString soundSystem ) = 0; + + /** \brief Closes the audio device. */ + virtual void closeAudio() = 0; /** \brief Returns the current volume. (range: 0 to 1.0) */ virtual float volume() = 0; @@ -63,6 +66,9 @@ /** \brief Returns a list of supported Sound Systems. */ virtual QStringList soundSystems() = 0; + /** \brief Returns the currently selected Sound System. */ + virtual QString currentSoundSystem() = 0; + /** \brief Returns a list of available devices. */ virtual QStringList devices() = 0; --- a/src/output/alsa-playback/alsaplayback.cpp +++ b/src/output/alsa-playback/alsaplayback.cpp @@ -28,6 +28,7 @@ #include "RadioEnums.h" +#define OUTPUT_ALSAPLAYBACK "Alsa" float AlsaPlayback::m_volume = 0.5; @@ -85,7 +86,14 @@ QStringList AlsaPlayback::soundSystems() { - return QStringList() << "Alsa"; + return QStringList() << OUTPUT_ALSAPLAYBACK; +} + + +QString +AlsaPlayback::currentSoundSystem() +{ + return OUTPUT_ALSAPLAYBACK; } @@ -137,8 +145,8 @@ } -void -AlsaPlayback::initAudio( long /*sampleRate*/, int /*channels*/ ) +bool +AlsaPlayback::initAudio( long /*sampleRate*/, int /*channels*/, QString /*soundSystem*/ ) { int channels = 2; int sampleRate = 44100; @@ -164,7 +172,17 @@ // there is no available device. emit error( Radio_NoSoundcard, tr("The ALSA soundsystem is either busy or not present.") ); + return false; } + return true; +} + + +void +AlsaPlayback::closeAudio() +{ + delete m_audio; + m_audio = 0; } --- a/src/output/alsa-playback/alsaplayback.h +++ b/src/output/alsa-playback/alsaplayback.h @@ -31,7 +31,8 @@ Q_OBJECT Q_INTERFACES( OutputInterface ) - virtual void initAudio( long sampleRate, int channels ); + virtual bool initAudio( long sampleRate, int channels, QString soundSystem ); + virtual void closeAudio(); virtual float volume() { return m_volume; } @@ -45,8 +46,9 @@ virtual int bufferSize(); virtual QStringList soundSystems(); + virtual QString currentSoundSystem(); virtual QStringList devices(); - virtual void setDevice( int n ) { m_deviceNum = n; initAudio( 44100, 2 ); } + virtual void setDevice( int n ) { m_deviceNum = n; /*initAudio( 44100, 2 );*/ } bool isActive() { return true; } --- a/src/output/portAudio/portAudioOutput.cpp +++ b/src/output/portAudio/portAudioOutput.cpp @@ -27,6 +27,14 @@ #include "logger.h" #include "RadioEnums.h" +// Linux +#define OUTPUT_PORTAUDIO_ALSA "portAudio" + +// Mac +#define OUTPUT_PORTAUDIO_COREAUDIO "CoreAudio" + +// Windows +//#define OUTPUT_PORTAUDIO_DIRECTSOUND "portAudio (DirectSound)" int audioCallback( const void*, void* outputBuffer, unsigned long frameCount, @@ -105,9 +113,10 @@ } -void -PortAudioOutput::initAudio( long sampleRate, int channels ) +bool +PortAudioOutput::initAudio( long sampleRate, int channels, QString soundSystem ) { + m_currentSoundSystem = soundSystem; if ( m_audio ) { Pa_CloseStream( m_audio ); @@ -125,7 +134,7 @@ { emit error( Radio_NoSoundcard, tr( "Your soundcard is either busy or not present. " "Try restarting the application." ) ); - return; + return false; } PaStreamParameters p; @@ -157,11 +166,26 @@ m_deviceInfo = *Pa_GetDeviceInfo( p.device ); m_sourceChannels = channels; - PaError error = Pa_OpenStream( &m_audio, 0, &p, sampleRate, bufferSize, 0, audioCallback, this ); - if ( error != paNoError ) + PaError pa_error = Pa_OpenStream( &m_audio, 0, &p, sampleRate, bufferSize, 0, audioCallback, this ); + if ( pa_error != paNoError ) { - qDebug() << "PortAudio Error:" << Pa_GetErrorText( error ); + qDebug() << "PortAudio Error:" << Pa_GetErrorText( pa_error ); + m_audio = 0; + emit error( Radio_NoSoundcard, tr("No soundcard available.") ); + return false; + } + return true; +} + + +void +PortAudioOutput::closeAudio() +{ + if ( m_audio ) + { + Pa_CloseStream( m_audio ); m_audio = 0; + m_currentSoundSystem.clear(); } } @@ -172,15 +196,15 @@ return QStringList() #ifdef WIN32 - << "DirectSound" + << OUTPUT_PORTAUDIO_DIRECTSOUND #endif #ifdef Q_WS_X11 - << "Alsa" + << OUTPUT_PORTAUDIO_ALSA; #endif #ifdef Q_WS_MAC - << "CoreAudio" + << OUTPUT_PORTAUDIO_COREAUDIO #endif ; --- a/src/output/portAudio/portAudioOutput.h +++ b/src/output/portAudio/portAudioOutput.h @@ -43,7 +43,8 @@ PortAudioOutput(); ~PortAudioOutput(); - virtual void initAudio( long sampleRate, int channels ); + virtual bool initAudio( long sampleRate, int channels, QString soundSystem ); + virtual void closeAudio(); virtual float volume() { return m_volume; } virtual void pause() { m_active = false; } virtual void resume() { m_active = true; } @@ -51,8 +52,9 @@ virtual bool needsData(); virtual void processData( const QByteArray &buffer ); virtual QStringList soundSystems(); + virtual QString currentSoundSystem() { return m_currentSoundSystem; } virtual QStringList devices(); - virtual void setDevice( int n ) { m_deviceNum = n; initAudio( SAMPLERATE, CHANNELS ); } + virtual void setDevice( int n ) { m_deviceNum = n; initAudio( SAMPLERATE, CHANNELS, m_currentSoundSystem ); } virtual void setBufferCapacity( int size ) { m_bufferCapacity = size; } virtual int bufferSize() { return m_buffer.size(); } @@ -71,12 +73,13 @@ virtual void setVolume( int volume ) { m_volume = (float)volume / 100.0; } signals: - virtual void error( int error, const QString& reason ); + void error( int error, const QString& reason ); private: PaStream* m_audio; bool m_bufferEmpty; bool m_active; + QString m_currentSoundSystem; PaDeviceInfo m_deviceInfo; float m_volume; --- a/src/output/RtAudio/rtaudio/RtAudio.cpp +++ b/src/output/RtAudio/rtaudio/RtAudio.cpp @@ -55,9 +55,10 @@ #endif #include "RtAudio.h" -#include -#include +#include +#include #include +#include #include // Static variable definitions. --- a/src/output/RtAudio/rtaudioplayback.cpp +++ b/src/output/RtAudio/rtaudioplayback.cpp @@ -26,6 +26,16 @@ #include "RadioEnums.h" +// Linux +#define OUTPUT_RTAUDIO_ALSA "Alsa (RtAudio)" +#define OUTPUT_RTAUDIO_OSS "OSS" + +// Mac +#define OUTPUT_RTAUDIO_COREAUDIO "CoreAudio" + +// Windows +#define OUTPUT_RTAUDIO_DIRECTSOUND "DirectSound" + int audioCallback( char *buffer, int bufferSize, void* data_src ) { @@ -154,15 +164,15 @@ QStringList l; #ifdef WIN32 - l << "DirectSound"; + l << OUTPUT_RTAUDIO_DIRECTSOUND; #endif #ifdef Q_WS_X11 - l << "OSS"; + l << OUTPUT_RTAUDIO_OSS; // << OUTPUT_RTAUDIO_ALSA; #endif #ifdef Q_WS_MAC - l << "CoreAudio"; + l << OUTPUT_RTAUDIO_COREAUDIO; #endif return l; @@ -174,7 +184,6 @@ { QStringList l; - initAudio( 44100, 2 ); if ( !m_audio ) return l; @@ -202,8 +211,6 @@ LOGL( 1, "Getting device names failed. RtAudio error type: " << error.getType() << " Message: " << error.getMessage() ); } - delete m_audio; - m_audio = 0; return l; } @@ -212,13 +219,6 @@ void RtAudioPlayback::startPlayback() { - if ( m_audio ) - { - delete m_audio; - m_audio = 0; - } - initAudio( 44100, 2 ); - if ( !m_audio ) { emit error( Radio_NoSoundcard, tr( "Your soundcard is either busy or not present. " @@ -252,9 +252,6 @@ m_audio->stopStream(); m_audio->cancelStreamCallback(); - delete m_audio; - m_audio = 0; - m_mutex.lock(); m_buffer.clear(); m_mutex.unlock(); @@ -277,16 +274,19 @@ } -void +bool RtAudioPlayback::initAudio( long sampleRate, - int channels ) + int channels, + QString soundSystem ) { + LOGL( 3, "Initializing RTAudio Playback" ); //int channels = 2; //int sampleRate = 44100; int nBuffers = 16; int bufferSize = 512; + m_currentSoundSystem = soundSystem; try { @@ -298,6 +298,10 @@ #ifdef Q_WS_X11 api = RtAudio::LINUX_OSS; + //if ( m_currentSoundSystem == OUTPUT_RTAUDIO_OSS ) + // api = RtAudio::LINUX_OSS; + //else if ( m_currentSoundSystem == OUTPUT_RTAUDIO_ALSA ) + // api = RtAudio::LINUX_ALSA; #endif RtAudioDeviceInfo info = m_audio->getDeviceInfo( card ); @@ -325,12 +329,24 @@ " Message: " << error.getMessage() ); // Don't delete m_audio here or it will crash. - // We don't emit an error signal here, it happens on startPlayback if - // we have no m_audio. m_audio = 0; - - return; } + + if ( m_audio ) + return true; + + // Looks like we do need to emit now + emit error( Radio_NoSoundcard, tr("The OSS soundsystem is either busy or not present.") ); + return false; +} + + +void +RtAudioPlayback::closeAudio() +{ + delete m_audio; + m_audio = 0; + m_currentSoundSystem.clear(); } --- a/src/output/RtAudio/rtaudioplayback.h +++ b/src/output/RtAudio/rtaudioplayback.h @@ -37,7 +37,8 @@ public: RtAudioPlayback(); - virtual void initAudio( long sampleRate, int channels ); + virtual bool initAudio( long sampleRate, int channels, QString soundSystem ); + virtual void closeAudio(); virtual float volume(); @@ -52,6 +53,7 @@ virtual void processData( const QByteArray& data ); QStringList soundSystems(); + QString currentSoundSystem() { return m_currentSoundSystem; } QStringList devices(); void setDevice( int n ) { m_deviceNum = n; /*initAudio( 44100, 2 );*/ } @@ -83,6 +85,7 @@ QByteArray m_buffer; int m_bufferCapacity; + QString m_currentSoundSystem; int m_deviceNum; --- a/src/output/RtAudio/RtAudio.pro +++ b/src/output/RtAudio/RtAudio.pro @@ -1,6 +1,6 @@ TEMPLATE = lib CONFIG += service -TARGET = rtaudioplayback +TARGET = output_rtaudio QT -= gui include( ../../../definitions.pro.inc ) --- a/src/Radio.cpp +++ b/src/Radio.cpp @@ -388,6 +388,13 @@ void +Radio::setSoundSystem( QString system ) +{ + m_audioController.setSoundSystem( system ); +} + + +void Radio::onPlaylistError( RadioError errorCode, const QString& message ) { @@ -654,7 +661,7 @@ } else { - if ( err == Radio_PluginLoadFailed || err == Radio_NoSoundcard ) + if ( err == Radio_PluginLoadFailed ) { m_broken = true; } --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -212,6 +212,7 @@ connect( ui_radio.resumeCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( configChanged() ) ); connect( ui_radio.cardBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( configChanged() ) ); connect( ui_radio.systemBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( configChanged() ) ); + connect( ui_radio.systemBox, SIGNAL( activated( int ) ), this, SLOT( soundSystemChanged() ) ); connect( ui_radio.automaticBufferCheck, SIGNAL( toggled( bool ) ), this, SLOT( configChanged() ) ); connect( ui_radio.bufferEdit, SIGNAL( textChanged( QString ) ), this, SLOT( configChanged() ) ); connect( ui_radio.musicProxyPort, SIGNAL( valueChanged( int ) ), this, SLOT( configChanged() ) ); @@ -249,6 +250,19 @@ } +void +SettingsDialog::soundSystemChanged() +{ + Radio& radio = The::radio(); + radio.stop(); + + radio.setSoundSystem( ui_radio.systemBox->currentText() ); + + ui_radio.cardBox->clear(); + ui_radio.cardBox->addItems( radio.devices() ); +} + + int SettingsDialog::exec( int startPage ) { @@ -375,7 +389,9 @@ ui_radio.systemBox->addItems( radio.soundSystems() ); ui_radio.cardBox->addItems( radio.devices() ); - ui_radio.systemBox->setCurrentIndex( The::settings().soundSystem() >= 0 ? The::settings().soundSystem() : 0 ); + int item = ui_radio.systemBox->findText( The::settings().soundSystem(), Qt::MatchExactly ); + if ( item >= 0 ) + ui_radio.systemBox->setCurrentIndex( item ); ui_radio.cardBox->setCurrentIndex( The::settings().soundCard() >= 0 ? The::settings().soundCard() : 0 ); ui_radio.automaticBufferCheck->setChecked( The::settings().isBufferManagedAutomatically() ); @@ -559,7 +575,7 @@ { The::settings().currentUser().setResumePlayback( ui_radio.resumeCheckBox->isChecked() ); The::settings().setSoundCard( ui_radio.cardBox->currentIndex() >= 0 ? ui_radio.cardBox->currentIndex() : 0 ); - The::settings().setSoundSystem( ui_radio.systemBox->currentIndex() >= 0 ? ui_radio.systemBox->currentIndex() : 0 ); + The::settings().setSoundSystem( ui_radio.systemBox->currentText() ); The::settings().setBufferManagedAutomatically( ui_radio.automaticBufferCheck->isChecked() ); @@ -571,7 +587,7 @@ The::settings().setMusicProxyPort( ui_radio.musicProxyPort->value() ); m_reAudio = ui_radio.cardBox->currentIndex() != originalSoundCard || - ui_radio.systemBox->currentIndex() != originalSoundSystem || + ui_radio.systemBox->currentText() != originalSoundSystem || m_reAudio; pageSaved( 1 ); @@ -679,7 +695,8 @@ if ( m_reconnect ) The::app().setUser( The::currentUsername() ); - if ( m_reAudio ) + // Not with the multiple sound system patch, you don't :) + /*if ( m_reAudio ) { LastMessageBox dlg( QMessageBox::Information, tr( "Restart needed" ), @@ -687,13 +704,29 @@ "change to take effect." ), QMessageBox::Ok, this ); dlg.exec(); - } + }*/ m_reconnect = m_reAudio = false; } } +void +SettingsDialog::reject() +{ + m_reAudio = ui_radio.cardBox->currentIndex() != originalSoundCard || + ui_radio.systemBox->currentText() != originalSoundSystem || + m_reAudio; + + if ( m_reAudio ) + { + The::audioController().resetAudio(); + m_reAudio = false; + } + QDialog::reject(); +} + + void SettingsDialog::configChanged() { --- a/src/Radio.h +++ b/src/Radio.h @@ -140,6 +140,9 @@ void setVolume( int vol ) { m_audioController.setVolume( vol ); } + void + setSoundSystem( QString system ); + signals: void --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -51,6 +51,7 @@ private slots: void configChanged(); + void soundSystemChanged(); void pageSwitched( int currentRow ); void clearCache(); void verifiedAccount( bool verified, bool bootstrap ); @@ -61,6 +62,7 @@ void clearUserIPodAssociations(); private: + virtual void reject(); void loadExtensions(); void populateAccount(); @@ -97,7 +99,7 @@ bool originalProxyUsage; int originalSoundCard; - int originalSoundSystem; + QString originalSoundSystem; bool m_reconnect; bool m_reAudio; --- a/src/libMoose/LastFmSettings.h +++ b/src/libMoose/LastFmSettings.h @@ -274,8 +274,8 @@ int soundCard() const { return QSettings().value( "soundcard", 0 ).toInt(); } void setSoundCard( int v ) { QSettings().setValue( "soundcard", v ); } - int soundSystem() const { return QSettings().value( "soundsystem", 0 ).toInt(); } - void setSoundSystem( int v ) { QSettings().setValue( "soundsystem", v ); } + QString soundSystem() const { return QSettings().value( "soundsystem", 0 ).toString(); } + void setSoundSystem( QString v ) { QSettings().setValue( "soundsystem", v ); } bool isBufferManagedAutomatically() const { return QSettings().value( "BufferManagedAutomatically", 1 ).toBool(); } void setBufferManagedAutomatically( bool v ) { QSettings().setValue( "BufferManagedAutomatically", v ); } --- a/src/container.cpp +++ b/src/container.cpp @@ -802,7 +802,7 @@ case Handshake_SessionFailed: case Radio_PluginLoadFailed: case Radio_NoSoundcard: - m_soundcardError = true; + //m_soundcardError = true; case Radio_PlaybackError: case Radio_UnknownError: { --- a/src/output/portAudio/portAudio.pro +++ b/src/output/portAudio/portAudio.pro @@ -7,38 +7,19 @@ # PortAudio = warnings-city QMAKE_CFLAGS_WARN_ON = "" -INCLUDEPATH += PortAudio/include \ - PortAudio/common - -SOURCES = portAudioOutput.cpp \ - \ - PortAudio/common/pa_skeleton.c \ - PortAudio/common/pa_process.c \ - PortAudio/common/pa_dither.c \ - PortAudio/common/pa_allocation.c \ - PortAudio/common/pa_converters.c \ - PortAudio/common/pa_cpuload.c \ - PortAudio/common/pa_front.c \ - PortAudio/common/pa_debugprint.c \ - PortAudio/common/pa_stream.c \ - PortAudio/common/pa_trace.c \ - +SOURCES = portAudioOutput.cpp + HEADERS = portAudioOutput.h -unix:linux-g++ { +unix:!mac { INCLUDEPATH += PortAudio/os/unix DEFINES += PA_USE_ALSA \ PA_USEOSS - SOURCES += PortAudio/hostapi/alsa/pa_linux_alsa.c \ - PortAudio/hostapi/oss/recplay.c \ - PortAudio/hostapi/oss/pa_unix_oss.c \ - PortAudio/os/unix/pa_unix_util.c \ - PortAudio/os/unix/pa_unix_hostapis.c - LIBS += -lasound \ + -lportaudio \ -lrt \ -lm }