diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index b8389aa4ad85a92d8b41b630d490fb298eeba488..ee5dc273501e0e12738c5f4f44226ba73356981e 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.cpp +++ b/sflphone-common/src/audio/alsa/alsalayer.cpp @@ -886,6 +886,7 @@ void AlsaLayer::audioCallback (void) memset (out, 0, playbackAvailBytes); if (out) { + _debug("Write tone (normal %d) (playbackAvail %d)", normalAvailBytes, playbackAvailBytes); tone->getNext (out, playbackAvailSmpl, spkrVolume); write (out , playbackAvailBytes, _PlaybackHandle); free (out); diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp index e2b30d630cd30753f66bf4f7409cc026d9c026c5..3f17b171d3002742067c34114b0bf0446ca74d00 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp @@ -747,9 +747,9 @@ void PulseLayer::writeToSpeaker (void) // available bytes to be written in pulseaudio internal buffer int writeableSize = pa_stream_writable_size (playback->pulseStream()); - if (writeableSize < 0) + if (writeableSize < 0) { _warn ("Audio: playback error : %s", pa_strerror (writeableSize)); - + } if (urgentAvailBytes > writeableSize) { @@ -758,7 +758,6 @@ void PulseLayer::writeToSpeaker (void) _urgentRingBuffer.Get (out, writeableSize, 100); - // spkrFile->write ( (const char *) out, writeableSize); pa_stream_write (playback->pulseStream(), out, writeableSize, NULL, 0, PA_SEEK_RELATIVE); pa_xfree (out); @@ -769,115 +768,88 @@ void PulseLayer::writeToSpeaker (void) } else { - // Get ringtone - AudioLoop* tone = _manager->getTelephoneTone(); - // We must test if data have been received from network in case of early media normalAvailBytes = getMainBuffer()->availForGet(); // flush remaining samples in _urgentRingBuffer flushUrgent(); - if ( (tone != 0) && (normalAvailBytes <= 0)) { - - if (playback->getStreamState() == PA_STREAM_READY) { - - out = (SFLDataFormat*) pa_xmalloc (writeableSize); - memset (out, 0, writeableSize); - - int copied = tone->getNext (out, writeableSize / sizeof (SFLDataFormat), 100); - - //spkrFile->write ( (const char *) out, copied*sizeof (SFLDataFormat)); - pa_stream_write (playback->pulseStream(), out, copied * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE); - - pa_xfree (out); + int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate(); - } + int maxNbBytesToGet = 0; + // test if audio resampling is needed + if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { + double upsampleFactor = (double) _mainBufferSampleRate / _audioSampleRate; + maxNbBytesToGet = ( (double) writeableSize * upsampleFactor); } else { + maxNbBytesToGet = writeableSize; + } - int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate(); - - int maxNbBytesToGet = 0; - - // test if audio resampling is needed - if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { - - // upsamplefactor is used to compute the number of bytes to get in the ring buffer - double upsampleFactor = (double) _mainBufferSampleRate / _audioSampleRate; - - maxNbBytesToGet = ( (double) writeableSize * upsampleFactor); - - } else { - - // maxNbSamplesToGet = framesPerBuffer; - maxNbBytesToGet = writeableSize; - - } - - byteToGet = (normalAvailBytes < (int) (maxNbBytesToGet)) ? normalAvailBytes : maxNbBytesToGet; - - if (byteToGet) { - - // Sending an odd number of byte breaks the audio! - // TODO, find out where the problem occurs to get rid of this hack - if ( (byteToGet%2) != 0) - byteToGet = byteToGet-1; - - out = (SFLDataFormat*) pa_xmalloc (maxNbBytesToGet); - memset (out, 0, maxNbBytesToGet); - - getMainBuffer()->getData (out, byteToGet, 100); - - // test if resampling is required - if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { + byteToGet = (normalAvailBytes < (int) (maxNbBytesToGet)) ? normalAvailBytes : maxNbBytesToGet; - SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (writeableSize); - memset (out, 0, writeableSize); + if (byteToGet) { - // Do sample rate conversion - int nb_sample_down = byteToGet / sizeof (SFLDataFormat); + // Sending an odd number of byte breaks the audio! + if ( (byteToGet%2) != 0) { + byteToGet = byteToGet-1; + } - int nbSample = _converter->upsampleData ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down); + out = (SFLDataFormat*) pa_xmalloc (maxNbBytesToGet); + memset (out, 0, maxNbBytesToGet); - if ( (nbSample*sizeof (SFLDataFormat)) > (unsigned int) writeableSize) - _warn ("Audio: Error: nbsbyte exceed buffer length"); + getMainBuffer()->getData (out, byteToGet, 100); - // spkrFile->write ( (const char *) out, nbSample*sizeof (SFLDataFormat)); - pa_stream_write (playback->pulseStream(), rsmpl_out, nbSample*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE); + // test if resampling is required + if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { - pa_xfree (rsmpl_out); + SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (writeableSize); + memset (out, 0, writeableSize); - } else { + // Do sample rate conversion + int nb_sample_down = byteToGet / sizeof (SFLDataFormat); - // spkrFile->write ( (const char *) out, byteToGet); - pa_stream_write (playback->pulseStream(), out, byteToGet, NULL, 0, PA_SEEK_RELATIVE); + int nbSample = _converter->upsampleData ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down); + if ( (nbSample*sizeof (SFLDataFormat)) > (unsigned int) writeableSize) { + _warn ("Audio: Error: nbsbyte exceed buffer length"); + } - } + // write resample data + pa_stream_write (playback->pulseStream(), rsmpl_out, nbSample*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE); - pa_xfree (out); + // free resampling buffer + pa_xfree (rsmpl_out); } else { + // write origin data + pa_stream_write (playback->pulseStream(), out, byteToGet, NULL, 0, PA_SEEK_RELATIVE); + } - if (tone == 0) { + // free audio buffer used to get data from + pa_xfree (out); - SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc (writeableSize); - bzero (zeros, writeableSize); + } else { - // spkrFile->write ( (const char *) zeros, writeableSize); - pa_stream_write (playback->pulseStream(), zeros, writeableSize, NULL, 0, PA_SEEK_RELATIVE); + // Get ringtone + AudioLoop *fileToPlay = _manager->getTelephoneTone(); - pa_xfree (zeros); + // If audio stream is open and there is realy nothing to play (i.e. audio voce is late and audio layer is underrun) + if (fileToPlay == NULL) { - } - } + SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc (writeableSize); + bzero (zeros, writeableSize); + _debug("write zeros"); + pa_stream_write (playback->pulseStream(), zeros, writeableSize, NULL, 0, PA_SEEK_RELATIVE); - _urgentRingBuffer.Discard (byteToGet); + pa_xfree (zeros); + } } + _urgentRingBuffer.Discard (byteToGet); + } } @@ -910,13 +882,9 @@ void PulseLayer::readFromMic (void) nbSample = _converter->downsampleData ( (SFLDataFormat *) data, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up); - // captureRsmplFile->write ((const char *)rsmpl_out, nbSample*sizeof(SFLDataFormat)); - // remove dc offset _audiofilter->processAudio (rsmpl_out, nbSample*sizeof (SFLDataFormat)); - // captureFilterFile->write ((const char *)rsmpl_out, nbSample*sizeof(SFLDataFormat)); - getMainBuffer()->putData (rsmpl_out, nbSample*sizeof (SFLDataFormat), 100); pa_xfree (rsmpl_out); @@ -930,15 +898,10 @@ void PulseLayer::readFromMic (void) // remove dc offset _audiofilter->processAudio ( (SFLDataFormat *) data, filter_out, r); - // captureFile->write ( (const char *) filter_out, r); - getMainBuffer()->putData (filter_out, r, 100); pa_xfree (filter_out); } - - - } if (pa_stream_drop (record->pulseStream()) < 0) { @@ -950,41 +913,41 @@ void PulseLayer::readFromMic (void) void PulseLayer::ringtoneToSpeaker (void) { - AudioLoop* file_tone = _manager->getTelephoneFile(); + AudioLoop* fileToPlay = _manager->getTelephoneFile(); SFLDataFormat* out; int writableSize = pa_stream_writable_size (ringtone->pulseStream()); - if (file_tone) { + if (fileToPlay) { if (ringtone->getStreamState() != PA_STREAM_READY) { - _error("PulseAudio: Error: Ringtone stream not in state ready"); - return; + _error("PulseAudio: Error: Ringtone stream not in state ready"); + return; } out = (SFLDataFormat *) pa_xmalloc (writableSize); if(out == NULL) { - _error("PulseAudio: Error: Could not allocate memory for buffer"); - return; + _error("PulseAudio: Error: Could not allocate memory for buffer"); + return; } memset (out, 0, writableSize); - int copied = file_tone->getNext (out, writableSize/sizeof (SFLDataFormat), 100); - + int copied = fileToPlay->getNext (out, writableSize/sizeof (SFLDataFormat), 100); if(copied == 0) { - copied = writableSize/sizeof(SFLDataFormat); + copied = writableSize/sizeof(SFLDataFormat); } pa_stream_write (ringtone->pulseStream(), out, copied*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE); pa_xfree (out); - } else { + } + else { if (ringtone->getStreamState() != PA_STREAM_READY) { - _error("PulseAudio: Error: Ringtone stream not in state ready"); - return; + _error("PulseAudio: Error: Ringtone stream not in state ready"); + return; } out = (SFLDataFormat*) pa_xmalloc (writableSize); @@ -998,8 +961,6 @@ void PulseLayer::ringtoneToSpeaker (void) pa_xfree (out); } - - } static void retrieve_server_info (pa_context *c UNUSED, const pa_server_info *i, void *userdata UNUSED) diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp index e49b2947036a22b495d329baf13b6f599cc65d19..b847d6bd2226033f5aeecce25f31cc7534ff7b33 100644 --- a/sflphone-common/src/audio/sound/audiofile.cpp +++ b/sflphone-common/src/audio/sound/audiofile.cpp @@ -56,6 +56,8 @@ RawFile::~RawFile() // load file in mono format void RawFile::loadFile (const std::string& name, sfl::AudioCodec* codec, unsigned int sampleRate = 8000) throw(AudioFileException) { + _debug("RawFile: Load new file %s", name.c_str()); + audioCodec = codec; // if the filename was already load, with the same samplerate @@ -437,6 +439,8 @@ void WaveFile::openExistingWaveFile (const std::string& fileName, int audioSampl void WaveFile::loadFile (const std::string& filename, sfl::AudioCodec * /*codec*/, unsigned int sampleRate) throw(AudioFileException) { + _debug("WaveFile: Load new file %s", filename.c_str()); + try { openFile (filename, sampleRate); } diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 215e06ee490eecc569eb2ebb9618a105b3cbcfb4..80d13a72fc1709ac94c8ba3d0858a568b4ae643a 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -2306,7 +2306,6 @@ void ManagerImpl::ringtone (const AccountID& accountID) std::string ringchoice; sfl::AudioCodec *codecForTone; int layer, samplerate; - bool loadFile; _debug ("Manager: Ringtone"); @@ -2358,22 +2357,23 @@ void ManagerImpl::ringtone (const AccountID& accountID) std::string wave (".wav"); size_t found = ringchoice.find (wave); - if (found != std::string::npos) - _audiofile = static_cast<AudioFile *> (new WaveFile()); - else - _audiofile = static_cast<AudioFile *> (new RawFile()); + try { + if (found != std::string::npos) { + _audiofile = static_cast<AudioFile *> (new WaveFile()); + } + else { + _audiofile = static_cast<AudioFile *> (new RawFile()); + } - _debug ("Manager: ringChoice: %s, codecForTone: %d, samplerate %d", ringchoice.c_str(), codecForTone->getPayloadType(), samplerate); + _debug ("Manager: ringChoice: %s, codecForTone: %d, samplerate %d", ringchoice.c_str(), codecForTone->getPayloadType(), samplerate); - if (_audiofile) { _audiofile->loadFile (ringchoice, codecForTone, samplerate); } + catch (AudioFileException &e) { + _error("Manager: Exception: %s", e.what()); + } - _toneMutex.leaveMutex(); - - - _toneMutex.enterMutex(); _audiofile->start(); _toneMutex.leaveMutex();