diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index b7f95cb122af7084dacb46057188ec32fc135be3..2602b3f4f00552a3611788577c49c3658667187a 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.cpp +++ b/sflphone-common/src/audio/alsa/alsalayer.cpp @@ -37,14 +37,14 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager) , _is_running_capture (false) , _is_open_playback (false) , _is_open_capture (false) - , _trigger_request (false) - , _converterSamplingRate(0) + , _trigger_request (false) + , _audioThread(NULL) { _debug (" Constructor of AlsaLayer called\n"); /* Instanciate the audio thread */ - _audioThread = new AudioThread (this); - + // _audioThread = new AudioThread (this); + // _audioThread = NULL; _urgentRingBuffer.createReadPointer(); dcblocker = new DcBlocker(); @@ -60,7 +60,9 @@ AlsaLayer::~AlsaLayer (void) delete _converter; _converter = NULL; } - delete dcblocker; dcblocker = NULL; + if(dcblocker) { + delete dcblocker; dcblocker = NULL; + } } bool @@ -71,6 +73,7 @@ AlsaLayer::closeLayer() try { /* Stop the audio thread first */ if (_audioThread) { + _debug("Stop Audio Thread\n"); delete _audioThread; _audioThread=NULL; } @@ -112,7 +115,7 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, _frameSize = frameSize; - _audioPlugin = plugin; + _audioPlugin = std::string(plugin); _debugAlsa (" Setting AlsaLayer: device in=%2d, out=%2d\n", _indexIn, _indexOut); @@ -122,6 +125,8 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize, _debugAlsa (" : sample rate=%5d, format=%s\n", _audioSampleRate, SFLDataFormatString); + _audioThread = NULL; + ost::MutexLock lock (_mutex); std::string pcmp = buildDeviceTopo (plugin, indexOut, 0); @@ -137,6 +142,18 @@ void AlsaLayer::startStream (void) { _debug ("AlsaLayer:: startStream\n"); + + std::string pcmp = buildDeviceTopo (_audioPlugin, _indexOut, 0); + std::string pcmc = buildDeviceTopo (_audioPlugin, _indexIn, 0); + + if(!is_playback_open()){ + open_device (pcmp, pcmc, SFL_PCM_PLAYBACK); + } + + if(!is_capture_open()){ + open_device (pcmp, pcmc, SFL_PCM_CAPTURE); + } + prepareCaptureStream (); _debug("------------------------------\n"); preparePlaybackStream (); @@ -150,14 +167,39 @@ AlsaLayer::startStream (void) _mainBuffer.flush(); _mainBuffer.flushDefault(); + + _debug("audiothread %p\n", _audioThread); + if(_audioThread == NULL) { + try { + _debug("Start Audio Thread\n"); + _audioThread = new AudioThread (this); + _audioThread->start(); + } catch (...) { + _debugException ("Fail to start audio thread\n"); + } + } + } void AlsaLayer::stopStream (void) { _debug ("AlsaLayer:: stopStream\n"); - stopCaptureStream (); - stopPlaybackStream (); + + try { + /* Stop the audio thread first */ + if (_audioThread) { + _debug("Stop Audio Thread\n"); + delete _audioThread; + _audioThread=NULL; + } + } catch (...) { + _debugException ("! ARTP Exception: when stopping audiortp\n"); + throw; + } + + closeCaptureStream (); + closePlaybackStream (); /* Flush the ring buffers */ flushUrgent (); @@ -245,12 +287,11 @@ void AlsaLayer::closeCaptureStream (void) { int err; - _debug("AlsaLayer:: close ALSA capture\n"); - if (is_capture_prepared() == true && is_capture_running() == true) stopCaptureStream (); if (is_capture_open()) { + _debug("AlsaLayer:: close ALSA capture\n"); if ((err = snd_pcm_close (_CaptureHandle)) < 0) _debug("Error closing ALSA capture: %s\n", snd_strerror(err)); else @@ -306,6 +347,7 @@ void AlsaLayer::closePlaybackStream (void) stopPlaybackStream (); if (is_playback_open()) { + _debug("AlsaLayer:: close ALSA playback\n"); if ((err = snd_pcm_close (_PlaybackHandle)) < 0) _debug("Error closing ALSA playback: %s\n", snd_strerror(err)); else @@ -469,6 +511,8 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag) int err; if (flag == SFL_PCM_BOTH || flag == SFL_PCM_PLAYBACK) { + + _debug("AlsaLayer:: open playback device\n"); // if((err = snd_pcm_open(&_PlaybackHandle, pcm_p.c_str(), SND_PCM_STREAM_PLAYBACK, 0 )) < 0){ if ( (err = snd_pcm_open (&_PlaybackHandle, pcm_p.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) { _debugAlsa ("Error while opening playback device %s\n", pcm_p.c_str()); @@ -488,6 +532,8 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag) } if (flag == SFL_PCM_BOTH || flag == SFL_PCM_CAPTURE) { + + _debug("AlsaLayer:: open capture device\n"); if ( (err = snd_pcm_open (&_CaptureHandle, pcm_c.c_str(), SND_PCM_STREAM_CAPTURE, 0)) < 0) { _debugAlsa ("Error while opening capture device %s\n", pcm_c.c_str()); setErrorMessage (ALSA_CAPTURE_DEVICE); @@ -508,11 +554,13 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag) } /* Start the secondary audio thread for callbacks */ + /* try { _audioThread->start(); } catch (...) { _debugException ("Fail to start audio thread\n"); } + */ return true; } @@ -608,6 +656,8 @@ AlsaLayer::read (void* buffer, int toCopy) void AlsaLayer::handle_xrun_capture (void) { + _debugAlsa("handle_xrun_capture\n"); + snd_pcm_status_t* status; snd_pcm_status_alloca (&status); @@ -626,6 +676,8 @@ AlsaLayer::handle_xrun_capture (void) void AlsaLayer::handle_xrun_playback (void) { + _debugAlsa("handle_xrun_playback\n"); + int state; snd_pcm_status_t* status; snd_pcm_status_alloca (&status); @@ -767,6 +819,7 @@ void AlsaLayer::audioCallback (void) int toGet, urgentAvailBytes, normalAvailBytes, maxBytes; unsigned short spkrVolume, micVolume; AudioLoop *tone; + AudioLoop *file_tone; SFLDataFormat *out; SFLDataFormat *rsmpl_out; @@ -797,8 +850,10 @@ void AlsaLayer::audioCallback (void) } else { tone = _manager->getTelephoneTone(); - toGet = 940 ; - maxBytes = toGet * sizeof (SFLDataFormat) ; + file_tone = _manager->getTelephoneFile(); + + toGet = framesPerBufferAlsa; + maxBytes = toGet * sizeof (SFLDataFormat); if (tone != 0) { @@ -809,7 +864,7 @@ void AlsaLayer::audioCallback (void) free(out); out = 0; - } else if ( (tone=_manager->getTelephoneFile()) != 0) { + } else if (file_tone != 0) { out = (SFLDataFormat*) malloc (maxBytes * sizeof (SFLDataFormat)); tone->getNext (out, toGet, spkrVolume); @@ -846,6 +901,8 @@ void AlsaLayer::audioCallback (void) normalAvailBytes = _mainBuffer.availForGet(); toGet = (normalAvailBytes < (int)maxNbBytesToGet) ? normalAvailBytes : maxNbBytesToGet; + + _debug("maxNbByteToGet %i\n", maxNbBytesToGet); out = (SFLDataFormat*) malloc (maxNbBytesToGet); if (normalAvailBytes) { @@ -860,7 +917,7 @@ void AlsaLayer::audioCallback (void) // Do sample rate conversion int nb_sample_down = toGet / sizeof(SFLDataFormat); - + _debug("nb_sample_down %i\n", nb_sample_down); int nbSample = _converter->upsampleData((SFLDataFormat*)out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down); @@ -878,7 +935,12 @@ void AlsaLayer::audioCallback (void) } else { - bzero (out, maxNbBytesToGet); + if((tone == 0) && (file_tone == 0)) { + + _debug("Write Zeros ......................\n"); + bzero (out, maxNbBytesToGet); + write (out, maxNbBytesToGet); + } } _urgentRingBuffer.Discard (toGet); @@ -903,11 +965,11 @@ void AlsaLayer::audioCallback (void) { micAvailBytes = snd_pcm_avail_update(_CaptureHandle); - + // _debug("micAvailBytes %i\n", micAvailBytes); if(micAvailBytes > 0) { micAvailPut = _mainBuffer.availForPut(); - toPut = (micAvailBytes <= micAvailPut) ? micAvailBytes : micAvailPut; + toPut = (micAvailBytes <= framesPerBufferAlsa) ? micAvailBytes : framesPerBufferAlsa; in = (SFLDataFormat*)malloc(toPut * sizeof(SFLDataFormat)); toPut = read (in, toPut* sizeof(SFLDataFormat)); @@ -924,6 +986,7 @@ void AlsaLayer::audioCallback (void) int nbSample = toPut / sizeof(SFLDataFormat); int nb_sample_up = nbSample; + // _debug("nb_sample_up %i\n", nb_sample_up); nbSample = _converter->downsampleData ((SFLDataFormat*)in, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up); dcblocker->filter_signal(rsmpl_out, nbSample); diff --git a/sflphone-common/src/audio/alsa/alsalayer.h b/sflphone-common/src/audio/alsa/alsalayer.h index e1d4b189b78d3b79c7ae5194a3751e04fc4e7044..1f5167ede252b9516c55df316e10763c3dfcd036 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.h +++ b/sflphone-common/src/audio/alsa/alsalayer.h @@ -265,13 +265,12 @@ class AlsaLayer : public AudioLayer { bool _is_open_capture; bool _trigger_request; - AudioThread *_audioThread; + AudioThread* _audioThread; /** Sample rate converter object */ - SamplerateConverter * _converter; - - int _converterSamplingRate; + SamplerateConverter* _converter; + // Allpass filter to remove DC offset DcBlocker* dcblocker; };