Skip to content
Snippets Groups Projects
Commit 041947ea authored by Alexandre Bourget's avatar Alexandre Bourget
Browse files

Fix audio glitch with mic and spkr.

This was due to libsamplerate's call to src_simple, which created glitches.
Now we use src_process, the 'Full API' as written on the SRC (libsamplerate)
website: http://www.mega-nerd.com/SRC/api_full.html
parent 20b924da
No related branches found
No related tags found
No related merge requests found
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
#include <assert.h> #include <assert.h>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <fstream> // fstream + iostream pour fstream debugging.. //#include <fstream> // fstream + iostream pour fstream debugging..
#include <iostream> // removeable... //#include <iostream> // removeable...
#include <math.h>
#include "../global.h" #include "../global.h"
#include "../manager.h" #include "../manager.h"
...@@ -94,7 +95,7 @@ AudioRtp::closeRtpSession () { ...@@ -94,7 +95,7 @@ AudioRtp::closeRtpSession () {
// AudioRtpRTX Class // // AudioRtpRTX Class //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
: _fstream("/tmp/audio.dat", std::ofstream::binary) // : _fstream("/tmp/audio.dat", std::ofstream::binary)
{ {
setCancel(cancelDeferred); setCancel(cancelDeferred);
time = new ost::Time(); time = new ost::Time();
...@@ -126,6 +127,10 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) ...@@ -126,6 +127,10 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
_sessionSend = NULL; _sessionSend = NULL;
} }
// libsamplerate-related
_src_state_mic = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
_src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
} }
AudioRtpRTX::~AudioRtpRTX () { AudioRtpRTX::~AudioRtpRTX () {
...@@ -155,8 +160,11 @@ AudioRtpRTX::~AudioRtpRTX () { ...@@ -155,8 +160,11 @@ AudioRtpRTX::~AudioRtpRTX () {
delete [] _sendDataEncoded; _sendDataEncoded = NULL; delete [] _sendDataEncoded; _sendDataEncoded = NULL;
delete [] _receiveDataDecoded; _receiveDataDecoded = NULL; delete [] _receiveDataDecoded; _receiveDataDecoded = NULL;
delete time; time = NULL; delete time; time = NULL;
// libsamplerate-related
_src_state_mic = src_delete(_src_state_mic);
_src_state_spkr = src_delete(_src_state_spkr);
} }
void void
...@@ -269,14 +277,26 @@ AudioRtpRTX::sendSessionFromMic(int timestamp) ...@@ -269,14 +277,26 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
src_short_to_float_array(_dataAudioLayer, _floatBuffer48000, nbSample); src_short_to_float_array(_dataAudioLayer, _floatBuffer48000, nbSample);
src_data.data_in = _floatBuffer48000; src_data.data_in = _floatBuffer48000;
#endif #endif
double factord = (double) audiocodec->getClockRate() / audiolayer->getSampleRate(); double factord = (double) audiocodec->getClockRate() / audiolayer->getSampleRate();
src_data.src_ratio = factord; src_data.src_ratio = factord;
src_data.input_frames = nbSample; src_data.input_frames = nbSample;
src_data.output_frames = RTP_20S_8KHZ_MAX; src_data.output_frames = (int) floor(factord * nbSample);
src_data.data_out = _floatBuffer8000; src_data.data_out = _floatBuffer8000;
src_simple (&src_data, SRC_SINC_BEST_QUALITY/*SRC_SINC_MEDIUM_QUALITY*/, 1); // 1 = channel src_data.end_of_input = 0; /* More data to come */
src_process(_src_state_mic, &src_data);
nbSample = src_data.output_frames_gen; nbSample = src_data.output_frames_gen;
/* WRITE IN A FILE FOR DEBUG */
//_fstream.write((char *) _floatBuffer48000, src_data.output_frames_gen * sizeof(float));
//_fstream.flush();
//if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); } //if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); }
src_float_to_short_array (_floatBuffer8000, _intBuffer8000, nbSample); src_float_to_short_array (_floatBuffer8000, _intBuffer8000, nbSample);
toSIP = _intBuffer8000; toSIP = _intBuffer8000;
} else { } else {
...@@ -343,14 +363,14 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) ...@@ -343,14 +363,14 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
unsigned char* data = (unsigned char*)adu->getData(); // data in char unsigned char* data = (unsigned char*)adu->getData(); // data in char
unsigned int size = adu->getSize(); // size in char unsigned int size = adu->getSize(); // size in char
//_debug("PACKET SIZE: %d bytes\n", size);
if ( size > RTP_20S_8KHZ_MAX ) { if ( size > RTP_20S_8KHZ_MAX ) {
_debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, RTP_20S_8KHZ_MAX); _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, RTP_20S_8KHZ_MAX);
_debug("The packet size has been cropped\n"); _debug("The packet size has been cropped\n");
size=RTP_20S_8KHZ_MAX; size=RTP_20S_8KHZ_MAX;
} }
// NOTE: L'audio rendu ici (dans data/size) est parfait.
// Decode data with relevant codec // Decode data with relevant codec
AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload); AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
if (audiocodec != NULL) { if (audiocodec != NULL) {
...@@ -364,18 +384,14 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) ...@@ -364,18 +384,14 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
nbInt16=RTP_20S_8KHZ_MAX; nbInt16=RTP_20S_8KHZ_MAX;
} }
/* WRITE IN A FILE FOR DEBUG */ // NOTE: l'audio arrivé ici (dans _receiveDataDecoded/expandedSize) est parfait.
// crache _receiveDataDecoded sur le disque pour analyse avec autre chose.
_fstream.write((char *) _receiveDataDecoded, size);
_fstream.flush();
SFLDataFormat* toAudioLayer; SFLDataFormat* toAudioLayer;
int nbSample = nbInt16; int nbSample = nbInt16;
// 48000 / 8000 = 6, the number of samples for the maximum rate conversion. // 48000 / 8000 = 6, the number of samples for the maximum rate conversion.
int nbSampleMaxRate = nbInt16 * 6; // TODO: change it int nbSampleMaxRate = nbInt16 * 6; // TODO: change it
// We assume over here that we pass from a lower rate to a higher one. Bad bad.
if ( audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) { if ( audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {
// Do sample rate conversion // Do sample rate conversion
...@@ -385,12 +401,15 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime) ...@@ -385,12 +401,15 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
SRC_DATA src_data; SRC_DATA src_data;
src_data.data_in = _floatBuffer8000; src_data.data_in = _floatBuffer8000;
src_data.data_out = _floatBuffer48000; src_data.data_out = _floatBuffer48000;
src_data.input_frames = RTP_20S_8KHZ_MAX; src_data.input_frames = nbSample;
src_data.output_frames = RTP_20S_48KHZ_MAX; src_data.output_frames = (int) floor(factord * nbSample);
src_data.src_ratio = factord; src_data.src_ratio = factord;
src_data.end_of_input = 0; /* More data will come */
src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample); src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
int err = src_simple (&src_data, SRC_SINC_BEST_QUALITY /* SRC_SINC_MEDIUM_QUALITY*/, 1); // 1=mono channel // NOTE: L'audio arrivé ici (dans _floatBuffer8000/nbSample*sizeof(float) est parfait.
src_process(_src_state_spkr, &src_data);
// Truncate number of samples if too high (ouch!) // Truncate number of samples if too high (ouch!)
nbSample = ( src_data.output_frames_gen > RTP_20S_48KHZ_MAX) ? RTP_20S_48KHZ_MAX : src_data.output_frames_gen; nbSample = ( src_data.output_frames_gen > RTP_20S_48KHZ_MAX) ? RTP_20S_48KHZ_MAX : src_data.output_frames_gen;
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <ccrtp/rtp.h> #include <ccrtp/rtp.h>
#include <cc++/numbers.h> #include <cc++/numbers.h>
#include <samplerate.h>
#include "../global.h" #include "../global.h"
/** maximum of byte inside an incoming packet /** maximum of byte inside an incoming packet
* 8000 sampling/s * 20s/1000 = 160 * 8000 sampling/s * 20s/1000 = 160
...@@ -73,7 +75,12 @@ private: ...@@ -73,7 +75,12 @@ private:
int16* _intBuffer8000; int16* _intBuffer8000;
/** Debugging output file */ /** Debugging output file */
std::ofstream _fstream; //std::ofstream _fstream;
/** libsamplerate-related */
SRC_STATE* _src_state_spkr;
SRC_STATE* _src_state_mic;
int _src_err;
void initAudioRtpSession(void); void initAudioRtpSession(void);
void sendSessionFromMic(int); void sendSessionFromMic(int);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment