From e32ac62fbb47038f10335c48d9b85dbda3489682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?= <rafael.carre@savoirfairelinux.com> Date: Tue, 30 Aug 2011 10:00:38 -0400 Subject: [PATCH] * #6629 : simplify AudioLayer creation Move ALSA specific options to alsalayer only --- daemon/src/audio/alsa/alsalayer.cpp | 225 ++++++++------------- daemon/src/audio/alsa/alsalayer.h | 82 ++++---- daemon/src/audio/audiolayer.cpp | 12 +- daemon/src/audio/audiolayer.h | 79 +------- daemon/src/audio/pulseaudio/pulselayer.cpp | 117 ++--------- daemon/src/audio/pulseaudio/pulselayer.h | 26 --- daemon/src/audio/samplerateconverter.cpp | 1 + daemon/src/managerimpl.cpp | 183 +++++------------ daemon/test/audiolayertest.cpp | 6 - 9 files changed, 215 insertions(+), 516 deletions(-) diff --git a/daemon/src/audio/alsa/alsalayer.cpp b/daemon/src/audio/alsa/alsalayer.cpp index 3201c117da..1ab1574e4c 100644 --- a/daemon/src/audio/alsa/alsalayer.cpp +++ b/daemon/src/audio/alsa/alsalayer.cpp @@ -74,11 +74,14 @@ void AlsaThread::run (void) // Constructor AlsaLayer::AlsaLayer () : AudioLayer (ALSA) + , indexIn_ (audioPref.getCardin()) + , indexOut_ (audioPref.getCardout()) + , indexRing_ (audioPref.getCardring()) , playbackHandle_ (NULL) , ringtoneHandle_ (NULL) , captureHandle_ (NULL) , periodSize_ (160) - , audioPlugin_ ("default") + , audioPlugin_ (audioPref.getPlugin()) , IDSoundCards_ () , is_playback_prepared_ (false) , is_capture_prepared_ (false) @@ -88,85 +91,30 @@ AlsaLayer::AlsaLayer () , is_capture_open_ (false) , trigger_request_ (false) , audioThread_ (NULL) - , converter_ (0) - { - _debug ("Audio: Build ALSA layer"); - urgentRingBuffer_.createReadPointer(); - - audioPlugin_ = audioPref.getPlugin(); } // Destructor AlsaLayer::~AlsaLayer (void) { - _debug ("Audio: Destroy of ALSA layer"); - closeLayer(); - - delete converter_; -} - -void -AlsaLayer::closeLayer() -{ - _debug ("Audio: Close ALSA streams"); - - try { - /* Stop the audio thread first */ - if (audioThread_) { - _debug ("Audio: Stop Audio Thread"); - delete audioThread_; - audioThread_ = NULL; - } - } catch (...) { - _debug ("Audio: Exception: when stopping audiortp"); - throw; - } + delete audioThread_; /* Then close the audio devices */ closeCaptureStream(); closePlaybackStream(); - - captureHandle_ = NULL; - playbackHandle_ = NULL; - ringtoneHandle_ = NULL; } -void -AlsaLayer::openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int stream , const std::string &plugin) +void AlsaLayer::setPlugin(const std::string &plugin) { - /* Close the devices before open it */ - if (stream == SFL_PCM_BOTH and is_capture_open_ and is_playback_open_) { - closeCaptureStream(); - closePlaybackStream(); - } else if ( (stream == SFL_PCM_CAPTURE or stream == SFL_PCM_BOTH) and is_capture_open_) - closeCaptureStream (); - else if ( (stream == SFL_PCM_PLAYBACK or stream == SFL_PCM_BOTH) and is_playback_open_) - closePlaybackStream (); - - indexIn_ = indexIn; - indexOut_ = indexOut; - indexRing_ = indexRing; - - audioSampleRate_ = sampleRate; - audioPlugin_ = plugin; - - _debug (" Setting AlsaLayer: device in=%2d, out=%2d, ring=%2d", indexIn_, indexOut_, indexRing_); - _debug (" : alsa plugin=%s", audioPlugin_.c_str()); - _debug (" : sample rate=%5d, format=%s", audioSampleRate_, SFLDataFormatString); - - audioThread_ = NULL; - - // use 1 sec buffer for resampling - converter_ = new SamplerateConverter (audioSampleRate_); + delete audioThread_; + audioThread_ = NULL; + // FIXME : restart audio thread } void AlsaLayer::startStream (void) { - _debug ("Audio: Start stream"); - dcblocker_.reset(); if (is_playback_running_ and is_capture_running_) @@ -190,12 +138,55 @@ AlsaLayer::startStream (void) _debug ("pcmr: %s, index %d", pcmr.c_str(), indexRing_); _debug ("pcmc: %s, index %d", pcmc.c_str(), indexIn_); - if (not is_capture_open_) - open_device (pcmp, pcmc, pcmr, SFL_PCM_CAPTURE); + if (not is_capture_open_) { + _debug ("Audio: Open capture device"); - if (not is_playback_open_) - open_device (pcmp, pcmc, pcmr, SFL_PCM_PLAYBACK); + if (snd_pcm_open (&captureHandle_, pcmc.c_str(), SND_PCM_STREAM_CAPTURE, 0) < 0) { + _warn ("Audio: Error: Opening capture device %s", pcmc.c_str()); + Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE); + is_capture_open_ = false; + } + + if (!alsa_set_params (captureHandle_, 0)) { + _warn ("Audio: Error: Capture failed"); + snd_pcm_close (captureHandle_); + is_capture_open_ = false; + } + + is_capture_open_ = true; + } + + if (not is_playback_open_) { + + _debug ("Audio: Open playback device (and ringtone)"); + + int err; + if ((err = snd_pcm_open (&playbackHandle_, pcmp.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) { + _warn ("Audio: Error while opening playback device %s", pcmp.c_str()); + Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE); + is_playback_open_ = false; + } + + if (!alsa_set_params (playbackHandle_, 1)) { + _warn ("Audio: Error: Playback failed"); + snd_pcm_close (playbackHandle_); + is_playback_open_ = false; + } + + if (getIndexOut() != getIndexRing()) { + + if ((err = snd_pcm_open (&ringtoneHandle_, pcmr.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) + _warn ("Audio: Error: Opening ringtone device %s", pcmr.c_str()); + + if (!alsa_set_params (ringtoneHandle_, 1)) { + _warn ("Audio: Error: Ringtone failed"); + snd_pcm_close (ringtoneHandle_); + } + } + + is_playback_open_ = true; + } prepareCaptureStream (); preparePlaybackStream (); @@ -225,17 +216,8 @@ AlsaLayer::stopStream (void) isStarted_ = false; - try { - /* Stop the audio thread first */ - if (audioThread_) { - _debug ("Audio: Stop audio thread"); - delete audioThread_; - audioThread_ = NULL; - } - } catch (...) { - _debug ("Audio: Exception: when stopping audiortp"); - throw; - } + delete audioThread_; + audioThread_ = NULL; closeCaptureStream (); closePlaybackStream (); @@ -268,6 +250,32 @@ void AlsaLayer::stopCaptureStream (void) } } +void AlsaLayer::setIndexRing(int index) +{ + indexRing_ = index; + delete audioThread_; + audioThread_ = NULL; +} + + +void AlsaLayer::setIndexOut(int index) +{ + indexOut_ = index; + if (is_playback_open_) + closePlaybackStream (); + delete audioThread_; + audioThread_ = NULL; +} + +void AlsaLayer::setIndexIn(int index) +{ + indexIn_ = index; + if (is_capture_open_) + closeCaptureStream (); + delete audioThread_; + audioThread_ = NULL; +} + void AlsaLayer::closeCaptureStream (void) { if (is_capture_prepared_ and is_capture_running_) @@ -427,7 +435,8 @@ bool AlsaLayer::alsa_set_params (snd_pcm_t *pcm_handle, int type) if (dir != 0) { _debug ("Audio: Error: (%i) The chosen rate %d Hz is not supported by your hardware.Using %d Hz instead. ", type , audioSampleRate_, exact_ivalue); - audioSampleRate_ = exact_ivalue; + //audioSampleRate_ = exact_ivalue; + // FIXME } /* Set the number of channels */ @@ -493,68 +502,6 @@ bool AlsaLayer::alsa_set_params (snd_pcm_t *pcm_handle, int type) return true; } - -bool -AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, std::string pcm_r, int flag) -{ - if (flag == SFL_PCM_BOTH or flag == SFL_PCM_PLAYBACK) { - - _debug ("Audio: Open playback device (and ringtone)"); - - int err; - if ((err = snd_pcm_open (&playbackHandle_, pcm_p.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) { - _warn ("Audio: Error while opening playback device %s", pcm_p.c_str()); - Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE); - is_playback_open_ = false; - return false; - } - - if (!alsa_set_params (playbackHandle_, 1)) { - _warn ("Audio: Error: Playback failed"); - snd_pcm_close (playbackHandle_); - is_playback_open_ = false; - return false; - } - - if (getIndexOut() != getIndexRing()) { - - if ((err = snd_pcm_open (&ringtoneHandle_, pcm_r.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) - _warn ("Audio: Error: Opening ringtone device %s", pcm_r.c_str()); - - if (!alsa_set_params (ringtoneHandle_, 1)) { - _warn ("Audio: Error: Ringtone failed"); - snd_pcm_close (ringtoneHandle_); - } - } - - is_playback_open_ = true; - } - - if (flag == SFL_PCM_BOTH or flag == SFL_PCM_CAPTURE) { - - _debug ("Audio: Open capture device"); - - if (snd_pcm_open (&captureHandle_, pcm_c.c_str(), SND_PCM_STREAM_CAPTURE, 0) < 0) { - _warn ("Audio: Error: Opening capture device %s", pcm_c.c_str()); - - Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE); - is_capture_open_ = false; - return false; - } - - if (!alsa_set_params (captureHandle_, 0)) { - _warn ("Audio: Error: Capture failed"); - snd_pcm_close (captureHandle_); - is_capture_open_ = false; - return false; - } - - is_capture_open_ = true; - } - - return true; -} - //TODO first frame causes broken pipe (underrun) because not enough data are send --> make the handle wait to be ready int AlsaLayer::write (void* buffer, int length, snd_pcm_t * handle) diff --git a/daemon/src/audio/alsa/alsalayer.h b/daemon/src/audio/alsa/alsalayer.h index 49d2382bf1..c29ccda940 100644 --- a/daemon/src/audio/alsa/alsalayer.h +++ b/daemon/src/audio/alsa/alsalayer.h @@ -35,7 +35,6 @@ #include "audio/audiolayer.h" #include <alsa/asoundlib.h> -class SamplerateConverter; class RingBuffer; class ManagerImpl; class AlsaThread; @@ -58,20 +57,6 @@ class AlsaLayer : public AudioLayer */ ~AlsaLayer (void); - /** - * Check if no devices are opened, otherwise close them. - * Then open the specified devices by calling the private functions open_device - * @param indexIn The number of the card chosen for capture - * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate - * @param stream To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @param plugin The alsa plugin ( dmix , default , front , surround , ...) - */ - void openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int stream, const std::string &plugin); - /** * Start the capture stream and prepare the playback stream. * The playback starts accordingly to its threshold @@ -123,7 +108,7 @@ class AlsaLayer : public AudioLayer * @return bool True if it exists and supports the mode * false otherwise */ - bool soundCardIndexExist (int card , int stream); + static bool soundCardIndexExist (int card , int stream); /** * An index is associated with its string description @@ -142,9 +127,55 @@ class AlsaLayer : public AudioLayer void audioCallback (void); + /** + * Get the index of the audio card for capture + * @return int The index of the card used for capture + * 0 for the first available card on the system, 1 ... + */ + int getIndexIn() const { + return indexIn_; + } + void setIndexIn(int); + + /** + * Get the index of the audio card for playback + * @return int The index of the card used for playback + * 0 for the first available card on the system, 1 ... + */ + int getIndexOut() const { + return indexOut_; + } + void setIndexOut(int); + + /** + * Get the index of the audio card for ringtone (could be differnet from playback) + * @return int The index of the card used for ringtone + * 0 for the first available card on the system, 1 ... + */ + int getIndexRing() const { + return indexRing_; + } + void setIndexRing(int); + + void setPlugin(const std::string &plugin); private: - void closeLayer (void); + + + /** + * Number of audio cards on which capture stream has been opened + */ + int indexIn_; + + /** + * Number of audio cards on which playback stream has been opened + */ + int indexOut_; + + /** + * Number of audio cards on which ringtone stream has been opened + */ + int indexRing_; /** Associate a sound card index to its string description */ typedef std::pair<int , std::string> HwIDPair; @@ -170,20 +201,6 @@ class AlsaLayer : public AudioLayer void startPlaybackStream (void); void preparePlaybackStream (void); - /** - * Open the specified device. - * ALSA Library API - * @param pcm_p The string name for the playback device - * @param pcm_c The string name for the capture device - * @param flag To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @return true if successful - * false otherwise - */ - bool open_device (std::string pcm_p, std::string pcm_c, std::string pcm_r, int flag); - bool alsa_set_params (snd_pcm_t *pcm_handle, int type); /** @@ -256,9 +273,6 @@ class AlsaLayer : public AudioLayer bool trigger_request_; AlsaThread* audioThread_; - - /** Sample rate converter object */ - SamplerateConverter* converter_; }; #endif // _ALSA_LAYER_H_ diff --git a/daemon/src/audio/audiolayer.cpp b/daemon/src/audio/audiolayer.cpp index 1edee1a967..cb2c30df80 100644 --- a/daemon/src/audio/audiolayer.cpp +++ b/daemon/src/audio/audiolayer.cpp @@ -37,20 +37,20 @@ AudioLayer::AudioLayer (int type) : isStarted_ (false) , urgentRingBuffer_ (SIZEBUF, Call::DEFAULT_ID) - , recorder_ (0) - , indexIn_ (0) - , indexOut_ (0) - , indexRing_ (0) - , audioSampleRate_ (0) + , audioSampleRate_(Manager::instance().getMainBuffer()->getInternalSamplingRate()) , mutex_ () , audioPref(Manager::instance().audioPreference) + , converter_ (new SamplerateConverter(audioSampleRate_)) , layerType_ (type) , lastNotificationTime_ (0) -{} +{ + urgentRingBuffer_.createReadPointer(); +} AudioLayer::~AudioLayer () { + delete converter_; } void AudioLayer::flushMain (void) diff --git a/daemon/src/audio/audiolayer.h b/daemon/src/audio/audiolayer.h index 27a2cdedb1..56b47e2a8c 100644 --- a/daemon/src/audio/audiolayer.h +++ b/daemon/src/audio/audiolayer.h @@ -40,6 +40,7 @@ #include "manager.h" #include "ringbuffer.h" #include "dcblocker.h" +#include "samplerateconverter.h" /** * @file audiolayer.h @@ -72,20 +73,6 @@ class AudioLayer */ virtual ~AudioLayer (void); - /** - * Check if no devices are opened, otherwise close them. - * Then open the specified devices by calling the private functions open_device - * @param indexIn The number of the card chosen for capture - * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate - * @param stream To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @param plugin The alsa plugin ( dmix , default , front , surround , ...) - */ - virtual void openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int stream , const std::string &plugin) = 0; - /** * Start the capture stream and prepare the playback stream. * The playback starts accordingly to its threshold @@ -114,32 +101,6 @@ class AudioLayer void flushUrgent (void); - /** - * Get the index of the audio card for capture - * @return int The index of the card used for capture - * 0 for the first available card on the system, 1 ... - */ - int getIndexIn() const { - return indexIn_; - } - - /** - * Get the index of the audio card for playback - * @return int The index of the card used for playback - * 0 for the first available card on the system, 1 ... - */ - int getIndexOut() const { - return indexOut_; - } - - /** - * Get the index of the audio card for ringtone (could be differnet from playback) - * @return int The index of the card used for ringtone - * 0 for the first available card on the system, 1 ... - */ - int getIndexRing() const { - return indexRing_; - } /** * Get the sample rate of the audio layer @@ -171,20 +132,6 @@ class AudioLayer return Manager::instance().getMainBuffer(); } - /** - * Set the audio recorder - */ - void setRecorderInstance (Recordable* rec) { - recorder_ = rec; - } - - /** - * Get the audio recorder - */ - Recordable* getRecorderInstance (void) const { - return recorder_; - } - /** * Get the mutex lock for the entire audio layer */ @@ -216,31 +163,11 @@ class AudioLayer */ RingBuffer urgentRingBuffer_; - /** - * A pointer to the recordable instance (may be a call or a conference) - */ - Recordable* recorder_; - - /** - * Number of audio cards on which capture stream has been opened - */ - int indexIn_; - - /** - * Number of audio cards on which playback stream has been opened - */ - int indexOut_; - - /** - * Number of audio cards on which ringtone stream has been opened - */ - int indexRing_; - /** * Sample Rate SFLphone should send sound data to the sound card * The value can be set in the user config file- now: 44100HZ */ - unsigned int audioSampleRate_; + const unsigned int audioSampleRate_; /** * Lock for the entire audio layer @@ -251,6 +178,8 @@ class AudioLayer AudioPreference &audioPref; + SamplerateConverter *converter_; + private: const int layerType_; diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp index cbdff8273f..90f09b3e19 100644 --- a/daemon/src/audio/pulseaudio/pulselayer.cpp +++ b/daemon/src/audio/pulseaudio/pulselayer.cpp @@ -219,45 +219,41 @@ void playback_overflow_callback (pa_stream* s UNUSED, void* userdata UNUSED) PulseLayer::PulseLayer () : AudioLayer (PULSEAUDIO) - , context_(0) - , mainloop_(0) , playback_(0) , record_(0) , ringtone_(0) - , converter_(0) { - urgentRingBuffer_.createReadPointer(); + setenv ("PULSE_PROP_media.role", "phone", 1); - openLayer(); -} + mainloop_ = pa_threaded_mainloop_new(); + if (!mainloop_) + _error("Couldn't create pulseaudio mainloop"); -// Destructor -PulseLayer::~PulseLayer (void) -{ - closeLayer (); - delete converter_; -} + context_ = pa_context_new (pa_threaded_mainloop_get_api (mainloop_) , "SFLphone"); + if (!context_) + _error("Couldn't create pulseaudio context"); -void -PulseLayer::openLayer (void) -{ - if (isStarted_) - return; + pa_context_set_state_callback (context_, context_state_callback, this); + + if (pa_context_connect (context_, NULL , PA_CONTEXT_NOAUTOSPAWN , NULL) < 0) + _error("Could not connect pulseaudio context to the server"); + + pa_threaded_mainloop_lock (mainloop_); + + if (pa_threaded_mainloop_start (mainloop_) < 0) + _error("Failed to start pulseaudio mainloop"); + pa_threaded_mainloop_wait (mainloop_); - _info ("Audio: Open Pulseaudio layer"); + if (pa_context_get_state (context_) != PA_CONTEXT_READY) + _error("Couldn't connect to pulse audio server"); - connectPulseAudioServer(); + pa_threaded_mainloop_unlock (mainloop_); isStarted_ = true; } -void -PulseLayer::closeLayer (void) +PulseLayer::~PulseLayer (void) { - _info ("Audio: Close Pulseaudio layer"); - - isStarted_ = false; - disconnectAudioStream(); if (mainloop_) @@ -266,69 +262,10 @@ PulseLayer::closeLayer (void) if (context_) { pa_context_disconnect (context_); pa_context_unref (context_); - context_ = NULL; } - if (mainloop_) { + if (mainloop_) pa_threaded_mainloop_free (mainloop_); - mainloop_ = NULL; - } -} - -void -PulseLayer::connectPulseAudioServer (void) -{ - _info ("Audio: Connect to Pulseaudio server"); - - setenv ("PULSE_PROP_media.role", "phone", 1); - - pa_context_flags_t flag = PA_CONTEXT_NOAUTOSPAWN ; - - if (!mainloop_) { - - // Instantiate a mainloop - _info ("Audio: Creating PulseAudio mainloop"); - - if (! (mainloop_ = pa_threaded_mainloop_new())) - _warn ("Audio: Error: while creating pulseaudio mainloop"); - - assert (mainloop_); - } - - if (!context_) { - - // Instantiate a context - if (! (context_ = pa_context_new (pa_threaded_mainloop_get_api (mainloop_) , "SFLphone"))) - _warn ("Audio: Error: while creating pulseaudio context"); - - assert (context_); - } - - // set context state callback before starting the mainloop - pa_context_set_state_callback (context_, context_state_callback, this); - - _info ("Audio: Connect the context to the server"); - - if (pa_context_connect (context_, NULL , flag , NULL) < 0) { - _warn ("Audio: Error: Could not connect context to the server"); - } - - // Lock the loop before starting it - pa_threaded_mainloop_lock (mainloop_); - - if (pa_threaded_mainloop_start (mainloop_) < 0) - _warn ("Audio: Error: Failed to start pulseaudio mainloop"); - - pa_threaded_mainloop_wait (mainloop_); - - // Run the main loop - if (pa_context_get_state (context_) != PA_CONTEXT_READY) { - _warn ("Audio: Error: connecting to pulse audio server"); - } - - pa_threaded_mainloop_unlock (mainloop_); - - _info ("Audio: Context creation done"); } void PulseLayer::context_state_callback (pa_context* c, void* user_data) @@ -370,16 +307,6 @@ void PulseLayer::context_state_callback (pa_context* c, void* user_data) } } -void PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int indexRing UNUSED, int sampleRate, int stream UNUSED, const std::string &plugin UNUSED) -{ - audioSampleRate_ = sampleRate; - - flushUrgent(); - - // use 1 sec buffer for resampling - converter_ = new SamplerateConverter (audioSampleRate_); -} - void PulseLayer::updateSinkList (void) { diff --git a/daemon/src/audio/pulseaudio/pulselayer.h b/daemon/src/audio/pulseaudio/pulselayer.h index 290f6b8c7e..f06ce86539 100644 --- a/daemon/src/audio/pulseaudio/pulselayer.h +++ b/daemon/src/audio/pulseaudio/pulselayer.h @@ -56,19 +56,6 @@ class PulseLayer : public AudioLayer public: PulseLayer (); ~PulseLayer (void); - /** - * Check if no devices are opened, otherwise close them. - * Then open the specified devices by calling the private functions open_device - * @param indexIn The number of the card chosen for capture - * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate - * @param stream To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @param plugin The alsa plugin ( dmix , default , front , surround , ...) - */ - void openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int stream, const std::string &plugin) ; DeviceList* getSinkList (void) { return &sinkList_; @@ -203,11 +190,6 @@ class PulseLayer : public AudioLayer */ void closePlaybackStream (void); - /** - * Establishes the connection with the local pulseaudio server - */ - void connectPulseAudioServer (void); - /** * Close the connection with the local pulseaudio server */ @@ -218,11 +200,6 @@ class PulseLayer : public AudioLayer */ void serverinfo (void); - void openLayer (void); - - void closeLayer (void); - - /** PulseAudio context and asynchronous loop */ pa_context* context_; pa_threaded_mainloop* mainloop_; @@ -242,9 +219,6 @@ class PulseLayer : public AudioLayer */ AudioStream* ringtone_; - /** Sample rate converter object */ - SamplerateConverter * converter_; - int spkrVolume_; int micVolume_; diff --git a/daemon/src/audio/samplerateconverter.cpp b/daemon/src/audio/samplerateconverter.cpp index 8bfcbeb687..d9fae5b7ba 100644 --- a/daemon/src/audio/samplerateconverter.cpp +++ b/daemon/src/audio/samplerateconverter.cpp @@ -34,6 +34,7 @@ SamplerateConverter::SamplerateConverter (int freq) : _maxFreq(freq) { + printf("FREQ %d\n", freq); int err; _src_state = src_new (SRC_LINEAR, 1, &err); diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp index e6ed18e229..9ad7b54b9c 100644 --- a/daemon/src/managerimpl.cpp +++ b/daemon/src/managerimpl.cpp @@ -116,7 +116,6 @@ void ManagerImpl::init (std::string config_file) initVolume(); initAudioDriver(); - selectAudioDriver(); // Initialize the list of supported audio codecs _audioCodecFactory.init(); @@ -2053,11 +2052,10 @@ void ManagerImpl::setAudioPlugin (const std::string& audioPlugin) audioPreference.setPlugin (audioPlugin); - if (_audiodriver -> getLayerType() == ALSA) { - _audiodriver -> openDevice (_audiodriver->getIndexIn(), _audiodriver->getIndexOut(), - _audiodriver->getIndexRing(), _audiodriver -> getSampleRate(), - SFL_PCM_BOTH, audioPlugin); - } + AlsaLayer *alsa = dynamic_cast<AlsaLayer*>(_audiodriver); + if (alsa) + alsa->setPlugin(audioPlugin); + audioLayerMutexUnlock(); } @@ -2066,46 +2064,30 @@ void ManagerImpl::setAudioPlugin (const std::string& audioPlugin) */ void ManagerImpl::setAudioDevice (const int index, int streamType) { - _debug ("Manager: Set audio device: %d", index); audioLayerMutexLock(); - if(_audiodriver == NULL) { - _warn ("Manager: Error: No audio driver"); - audioLayerMutexUnlock(); - return; - } - AlsaLayer *alsaLayer = dynamic_cast<AlsaLayer*>(_audiodriver); if (!alsaLayer) { - _error("Cannot set audio output for non-alsa device"); + _error("Can't find alsa device"); audioLayerMutexUnlock(); return ; } - const std::string alsaplugin(alsaLayer->getAudioPlugin()); - - _debug ("Manager: Set ALSA plugin: %s", alsaplugin.c_str()); switch (streamType) { case SFL_PCM_PLAYBACK: - _debug ("Manager: Set output device"); - _audiodriver->openDevice (_audiodriver->getIndexIn(), index, _audiodriver->getIndexRing(), - _audiodriver->getSampleRate(), SFL_PCM_PLAYBACK, alsaplugin); + alsaLayer->setIndexOut(index); audioPreference.setCardout (index); break; case SFL_PCM_CAPTURE: - _debug ("Manager: Set input device"); - _audiodriver->openDevice (index, _audiodriver->getIndexOut(), _audiodriver->getIndexRing(), - _audiodriver->getSampleRate(), SFL_PCM_CAPTURE, alsaplugin); + alsaLayer->setIndexIn(index); audioPreference.setCardin (index); break; case SFL_PCM_RINGTONE: - _debug ("Manager: Set ringtone device"); - _audiodriver->openDevice (_audiodriver->getIndexOut(), _audiodriver->getIndexOut(), index, - _audiodriver->getSampleRate(), SFL_PCM_RINGTONE, alsaplugin); + alsaLayer->setIndexRing(index); audioPreference.setCardring (index); break; default: - _warn ("Unknown stream type"); + break; } audioLayerMutexUnlock(); @@ -2116,7 +2098,6 @@ void ManagerImpl::setAudioDevice (const int index, int streamType) */ std::vector<std::string> ManagerImpl::getAudioOutputDeviceList (void) { - _debug ("Manager: Get audio output device list"); std::vector<std::string> devices; audioLayerMutexLock(); @@ -2141,15 +2122,9 @@ std::vector<std::string> ManagerImpl::getAudioInputDeviceList (void) audioLayerMutexLock(); - AlsaLayer *alsalayer = dynamic_cast<AlsaLayer *>(_audiodriver); - - if (alsalayer == NULL) { - _error("Manager: Error: Audio layer not initialized"); - audioLayerMutexUnlock(); - return devices; - } - - devices = alsalayer->getSoundCardsInfo (SFL_PCM_CAPTURE); + AlsaLayer *alsalayer = dynamic_cast<AlsaLayer *> (_audiodriver); + if (alsalayer) + devices = alsalayer->getSoundCardsInfo (SFL_PCM_CAPTURE); audioLayerMutexUnlock(); @@ -2165,20 +2140,17 @@ std::vector<std::string> ManagerImpl::getCurrentAudioDevicesIndex () std::vector<std::string> v; - if (_audiodriver == NULL) { - _error("Manager: Error: Audio layer not initialized"); - audioLayerMutexUnlock(); - return v; + AlsaLayer *alsa = dynamic_cast<AlsaLayer*>(_audiodriver); + if (alsa) { + std::stringstream ssi, sso, ssr; + sso << alsa->getIndexOut(); + v.push_back (sso.str()); + ssi << alsa->getIndexIn(); + v.push_back (ssi.str()); + ssr << alsa->getIndexRing(); + v.push_back (ssr.str()); } - std::stringstream ssi, sso, ssr; - sso << _audiodriver->getIndexOut(); - v.push_back (sso.str()); - ssi << _audiodriver->getIndexIn(); - v.push_back (ssi.str()); - ssr << _audiodriver->getIndexRing(); - v.push_back (ssr.str()); - audioLayerMutexUnlock(); return v; @@ -2205,7 +2177,6 @@ void ManagerImpl::ringtoneEnabled (const std::string& id) } account->getRingtoneEnabled() ? account->setRingtoneEnabled (false) : account->setRingtoneEnabled (true); - } std::string ManagerImpl::getRecordPath (void) const @@ -2458,63 +2429,35 @@ void ManagerImpl::initAudioDriver (void) { audioLayerMutexLock(); - if (preferences.getAudioApi() == PULSEAUDIO && system("ps -C pulseaudio") == 0) { - _audiodriver = new PulseLayer; - } else { - preferences.setAudioApi (ALSA); - _audiodriver = new AlsaLayer; - } - - audioLayerMutexUnlock(); -} - -/** - * Initialization: Main Thread and gui - */ -void ManagerImpl::selectAudioDriver (void) -{ - audioLayerMutexLock(); - - if (_audiodriver == NULL) { - _debug("Manager: Audio layer not initialized"); - audioLayerMutexUnlock(); - return; - } - /* Retrieve the global devices info from the user config */ - std::string alsaPlugin(audioPreference.getPlugin()); int numCardIn = audioPreference.getCardin(); int numCardOut = audioPreference.getCardout(); int numCardRing = audioPreference.getCardring(); - int sampleRate = getMainBuffer()->getInternalSamplingRate(); - - /* Only for the ALSA layer, we check the sound card information */ - - AlsaLayer *alsalayer = dynamic_cast<AlsaLayer*>(_audiodriver); - if (alsalayer) { - - if (!alsalayer->soundCardIndexExist (numCardIn, SFL_PCM_CAPTURE)) { - _debug (" Card with index %d doesn't exist or cannot capture. Switch to 0.", numCardIn); - numCardIn = ALSA_DFT_CARD_ID; - audioPreference.setCardin (ALSA_DFT_CARD_ID); - } + if (!AlsaLayer::soundCardIndexExist (numCardIn, SFL_PCM_CAPTURE)) { + _debug (" Card with index %d doesn't exist or cannot capture. Switch to 0.", numCardIn); + numCardIn = ALSA_DFT_CARD_ID; + audioPreference.setCardin (ALSA_DFT_CARD_ID); + } - if (!alsalayer->soundCardIndexExist (numCardOut, SFL_PCM_PLAYBACK)) { - _debug (" Card with index %d doesn't exist or cannot playback. Switch to 0.", numCardOut); - numCardOut = ALSA_DFT_CARD_ID; - audioPreference.setCardout (ALSA_DFT_CARD_ID); - } + if (!AlsaLayer::soundCardIndexExist (numCardOut, SFL_PCM_PLAYBACK)) { + _debug (" Card with index %d doesn't exist or cannot playback. Switch to 0.", numCardOut); + numCardOut = ALSA_DFT_CARD_ID; + audioPreference.setCardout (ALSA_DFT_CARD_ID); + } - if (!alsalayer->soundCardIndexExist (numCardRing, SFL_PCM_RINGTONE)) { - _debug (" Card with index %d doesn't exist or cannot ringtone. Switch to 0.", numCardRing); - numCardRing = ALSA_DFT_CARD_ID; - audioPreference.setCardring (ALSA_DFT_CARD_ID); - } + if (!AlsaLayer::soundCardIndexExist (numCardRing, SFL_PCM_RINGTONE)) { + _debug (" Card with index %d doesn't exist or cannot ringtone. Switch to 0.", numCardRing); + numCardRing = ALSA_DFT_CARD_ID; + audioPreference.setCardring (ALSA_DFT_CARD_ID); } - /* Open the audio devices */ - _audiodriver->openDevice (numCardIn, numCardOut, numCardRing, sampleRate, SFL_PCM_BOTH, alsaPlugin); + if (preferences.getAudioApi() == PULSEAUDIO && system("ps -C pulseaudio") == 0) { + _audiodriver = new PulseLayer; + } else { + preferences.setAudioApi (ALSA); + _audiodriver = new AlsaLayer; + } audioLayerMutexUnlock(); } @@ -2525,34 +2468,15 @@ void ManagerImpl::switchAudioManager (void) audioLayerMutexLock(); - if (_audiodriver == NULL) { - audioLayerMutexUnlock(); - return; - } - bool wasStarted = _audiodriver->isStarted(); - int type = _audiodriver->getLayerType(); - - int samplerate = _mainBuffer.getInternalSamplingRate(); - - std::string alsaPlugin(audioPreference.getPlugin()); - - int numCardIn = audioPreference.getCardin(); - int numCardOut = audioPreference.getCardout(); - int numCardRing = audioPreference.getCardring(); - - _debug ("Manager: Deleting current layer... "); - + int newType = (_audiodriver->getLayerType()) == PULSEAUDIO ? ALSA : PULSEAUDIO; delete _audiodriver; - if (type == PULSEAUDIO) - _audiodriver = new PulseLayer(); - else - _audiodriver = new AlsaLayer(); - _audiodriver->openDevice (numCardIn, numCardOut, numCardRing, samplerate, SFL_PCM_BOTH, alsaPlugin); - - _debug ("Manager: Current device: %d ", type); + if (newType == ALSA) + _audiodriver = new AlsaLayer; + else + _audiodriver = new PulseLayer(); if (wasStarted) _audiodriver->startStream(); @@ -2585,15 +2509,10 @@ void ManagerImpl::audioSamplingRateChanged (int samplerate) _debug ("Manager: New samplerate: %d", samplerate); - std::string alsaPlugin(audioPreference.getPlugin()); - - int numCardIn = audioPreference.getCardin(); - int numCardOut = audioPreference.getCardout(); - int numCardRing = audioPreference.getCardring(); + bool wasActive = _audiodriver->isStarted(); - _debug ("Manager: Deleting current layer..."); - bool wasActive = _audiodriver->isStarted(); + _mainBuffer.setInternalSamplingRate(samplerate); delete _audiodriver; if (type == PULSEAUDIO) @@ -2601,12 +2520,6 @@ void ManagerImpl::audioSamplingRateChanged (int samplerate) else _audiodriver = new PulseLayer; - _audiodriver->openDevice (numCardIn, numCardOut, numCardRing, samplerate, SFL_PCM_BOTH, alsaPlugin); - - _debug ("Manager: Current device: %d ", type); - - _mainBuffer.setInternalSamplingRate(samplerate); - unsigned int sampleRate = _audiodriver->getSampleRate(); delete _telephoneTone; diff --git a/daemon/test/audiolayertest.cpp b/daemon/test/audiolayertest.cpp index ca177d06e6..258916a162 100644 --- a/daemon/test/audiolayertest.cpp +++ b/daemon/test/audiolayertest.cpp @@ -108,12 +108,6 @@ void AudioLayerTest::testPulseConnect() CPPUNIT_ASSERT (_pulselayer->getPlaybackStream() == NULL); CPPUNIT_ASSERT (_pulselayer->getRecordStream() == NULL); - try { - _pulselayer->openDevice (sampleRate); - } catch (...) { - _debug ("Exception occured wile opening device! "); - } - sleep (1); CPPUNIT_ASSERT (_pulselayer->getPlaybackStream() == NULL); -- GitLab