Commit fa57bac5 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

use sampling frequency and frame size from the user config

Sampling rate values are no more hardcoded. The sampling rate of the audio layer
 and the frame size can be set in the user config file. The clock rate of the codec we use
in the rtp session is set with his actual value, but can be changed by modifying
the available codec in the user config file (only G711 for now)
parent 9c76e463
......@@ -2,10 +2,11 @@
* Copyright (C) 2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com>
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
......@@ -108,13 +109,15 @@ AudioLayer::hasStream(void) {
void
AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate)
AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize)
{
closeStream();
_sampleRate = sampleRate;
_frameSize = frameSize;
int portaudioFramePerBuffer = FRAME_PER_BUFFER; //=FRAME_PER_BUFFER; //= paFramesPerBufferUnspecified;
//int portaudioFramePerBuffer = (int) (8000 * frameSize / 1000);
//= paFramesPerBufferUnspecified;
int nbDevice = getDeviceCount();
if (nbDevice == 0) {
......
......@@ -2,10 +2,11 @@
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com>
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
......@@ -35,96 +36,103 @@ class RingBuffer;
class ManagerImpl;
class AudioLayer {
public:
AudioLayer(ManagerImpl* manager);
~AudioLayer(void);
/*
* @param indexIn
* @param indexOut
* @param sampleRate
*/
void openDevice(int, int, int);
void startStream(void);
void stopStream(void);
void sleep(int);
bool hasStream(void);
bool isStreamActive(void);
bool isStreamStopped(void);
void flushMain();
int putMain(void* buffer, int toCopy);
int putUrgent(void* buffer, int toCopy);
int canGetMic();
int getMic(void *, int);
void flushMic();
int audioCallback (const void *, void *, unsigned long,
const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
int miniAudioCallback (const void *, void *, unsigned long,
const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
void setErrorMessage(const std::string& error) { _errorMessage = error; }
std::string getErrorMessage() { return _errorMessage; }
/**
* Get the sample rate of audiolayer
* accessor only
*/
unsigned int getSampleRate() { return _sampleRate; }
int getDeviceCount();
AudioDevice* getAudioDeviceInfo(int index, int ioDeviceMask);
enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 };
/**
* Toggle echo testing on/off
*/
void toggleEchoTesting();
private:
void closeStream (void);
RingBuffer _urgentRingBuffer;
RingBuffer _mainSndRingBuffer;
RingBuffer _micRingBuffer;
ManagerImpl* _manager; // augment coupling, reduce indirect access
// a audiolayer can't live without manager
portaudio::MemFunCallbackStream<AudioLayer> *_stream;
/**
* Sample Rate of SFLphone : should be 8000 for 8khz
* Added because we could change it in the futur
*/
unsigned int _sampleRate;
/**
* Input channel (mic) should be 1 mono
*/
unsigned int _inChannel; // mic
/**
* Output channel (stereo) should be 1 mono
*/
unsigned int _outChannel; // speaker
/**
* Default volume for incoming RTP and Urgent sounds.
*/
unsigned short _defaultVolume; // 100
/**
* Echo testing or not
*/
bool _echoTesting;
std::string _errorMessage;
ost::Mutex _mutex;
float *table_;
int tableSize_;
int leftPhase_;
public:
AudioLayer(ManagerImpl* manager);
~AudioLayer(void);
/*
* @param indexIn
* @param indexOut
* @param sampleRate
* @param frameSize
*/
void openDevice(int, int, int, int);
void startStream(void);
void stopStream(void);
void sleep(int);
bool hasStream(void);
bool isStreamActive(void);
bool isStreamStopped(void);
void flushMain();
int putMain(void* buffer, int toCopy);
int putUrgent(void* buffer, int toCopy);
int canGetMic();
int getMic(void *, int);
void flushMic();
int audioCallback (const void *, void *, unsigned long,
const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
int miniAudioCallback (const void *, void *, unsigned long,
const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
void setErrorMessage(const std::string& error) { _errorMessage = error; }
std::string getErrorMessage() { return _errorMessage; }
/**
* Get the sample rate of audiolayer
* accessor only
*/
unsigned int getSampleRate() { return _sampleRate; }
unsigned int getFrameSize() { return _frameSize; }
int getDeviceCount();
AudioDevice* getAudioDeviceInfo(int index, int ioDeviceMask);
enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 };
/**
* Toggle echo testing on/off
*/
void toggleEchoTesting();
private:
void closeStream (void);
RingBuffer _urgentRingBuffer;
RingBuffer _mainSndRingBuffer;
RingBuffer _micRingBuffer;
ManagerImpl* _manager; // augment coupling, reduce indirect access
// a audiolayer can't live without manager
portaudio::MemFunCallbackStream<AudioLayer> *_stream;
/**
* 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 _sampleRate;
/**
* Length of the sound frame we capture or read in ms
* The value can be set in the user config file - now: 20ms
*/
unsigned int _frameSize;
/**
* Input channel (mic) should be 1 mono
*/
unsigned int _inChannel; // mic
/**
* Output channel (stereo) should be 1 mono
*/
unsigned int _outChannel; // speaker
/**
* Default volume for incoming RTP and Urgent sounds.
*/
unsigned short _defaultVolume; // 100
/**
* Echo testing or not
*/
bool _echoTesting;
std::string _errorMessage;
ost::Mutex _mutex;
float *table_;
int tableSize_;
int leftPhase_;
};
#endif // _AUDIO_LAYER_H_
......
This diff is collapsed.
/*
* Copyright (C) 2004-2007 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
......@@ -33,81 +34,108 @@
#include "../global.h"
/** maximum bytes inside an incoming packet
* 8000 sampling/s * 20s/1000 = 160
*/
#define RTP_20S_8KHZ_MAX 160
#define RTP_20S_48KHZ_MAX 960
#define UP_SAMPLING 0
#define DOWN_SAMPLING 1
class SIPCall;
///////////////////////////////////////////////////////////////////////////////
// Two pair of sockets
///////////////////////////////////////////////////////////////////////////////
class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
public:
AudioRtpRTX (SIPCall *, bool);
~AudioRtpRTX();
ost::Time *time; // For incoming call notification
virtual void run ();
private:
SIPCall* _ca;
ost::RTPSession *_sessionSend;
ost::RTPSession *_sessionRecv;
ost::SymmetricRTPSession *_session;
ost::Semaphore _start;
bool _sym;
/** When we receive data, we decode it inside this buffer */
int16* _receiveDataDecoded;
/** When we send data, we encode it inside this buffer*/
unsigned char* _sendDataEncoded;
/** After that we send the data inside this buffer if there is a format conversion or rate conversion */
/** Also use for getting mic-ringbuffer data */
SFLDataFormat* _dataAudioLayer;
/** Buffer for 8000hz samples in conversion */
float32* _floatBuffer8000;
/** Buffer for 48000hz samples in conversion */
float32* _floatBuffer48000;
/** Buffer for 8000Hz samples for mic conversion */
int16* _intBuffer8000;
/** Debugging output file */
//std::ofstream _fstream;
/** libsamplerate converter for incoming voice */
SRC_STATE* _src_state_spkr;
/** libsamplerate converter for outgoing voice */
SRC_STATE* _src_state_mic;
/** libsamplerate error */
int _src_err;
void initAudioRtpSession(void);
void sendSessionFromMic(int);
void receiveSessionForSpkr(int&);
public:
AudioRtpRTX (SIPCall *, bool);
~AudioRtpRTX();
ost::Time *time; // For incoming call notification
virtual void run ();
private:
SIPCall* _ca;
ost::RTPSession *_sessionSend;
ost::RTPSession *_sessionRecv;
ost::SymmetricRTPSession *_session;
ost::Semaphore _start;
bool _sym;
/** When we receive data, we decode it inside this buffer */
int16* _receiveDataDecoded;
/** Buffers used for send data from the mic */
unsigned char* _sendDataEncoded;
int16* _intBufferDown;
/** After that we send the data inside this buffer if there is a format conversion or rate conversion */
/** Also use for getting mic-ringbuffer data */
SFLDataFormat* _dataAudioLayer;
/** Buffers used for sample rate conversion */
float32* _floatBufferDown;
float32* _floatBufferUp;
/** Debugging output file */
//std::ofstream _fstream;
/** libsamplerate converter for incoming voice */
SRC_STATE* _src_state_spkr;
/** libsamplerate converter for outgoing voice */
SRC_STATE* _src_state_mic;
/** libsamplerate error */
int _src_err;
// Variables to process audio stream
int _layerSampleRate; // sample rate for playing sound (typically 44100HZ)
int _codecSampleRate; // sample rate of the codec we use to encode and decode (most of time 8000HZ)
int _layerFrameSize; // length of the sound frame we capture in ms(typically 20ms)
void initAudioRtpSession(void);
/**
* Get the data from the mic, encode it and send it through the RTP session
*/
void sendSessionFromMic(int);
/**
* Get the data from the RTP packets, decode it and send it to the sound card
*/
void receiveSessionForSpkr(int&);
/**
* Init the buffers used for processing sound data
*/
void initBuffers(void);
/**
* Call the appropriate function, up or downsampling
*/
int reSampleData(int, int ,int);
/**
* Upsample the data from the clock rate of the codec to the sample rate of the layer
* @param int The clock rate of the codec
* @param int The number of samples we have in the buffer
* @return int The number of samples after the operation
*/
int upSampleData(int, int);
/**
* Downsample the data from the sample rate of the layer to the clock rate of the codec
* @param int The clock rate of the codec
* @param int The number of samples we have in the buffer
* @return int The number of samples after the operation
*/
int downSampleData(int, int);
};
///////////////////////////////////////////////////////////////////////////////
// Main class rtp
///////////////////////////////////////////////////////////////////////////////
class AudioRtp {
public:
AudioRtp();
~AudioRtp();
public:
AudioRtp();
~AudioRtp();
int createNewSession (SIPCall *);
void closeRtpSession ();
int createNewSession (SIPCall *);
void closeRtpSession ();
private:
AudioRtpRTX* _RTXThread;
bool _symmetric;
ost::Mutex _threadMutex;
private:
AudioRtpRTX* _RTXThread;
bool _symmetric;
ost::Mutex _threadMutex;
};
#endif // __AUDIO_RTP_H__
......@@ -1050,7 +1050,8 @@ ManagerImpl::initConfigFile (void)
//fill_config_int(DRIVER_NAME, DFT_DRIVER_STR);
fill_config_int(DRIVER_NAME_IN, DFT_DRIVER_STR);
fill_config_int(DRIVER_NAME_OUT, DFT_DRIVER_STR);
fill_config_int(DRIVER_SAMPLE_RATE, DRIVER_SAMPLE_RATE_DEFAULT);
fill_config_int(DRIVER_SAMPLE_RATE, DFT_SAMPLE_RATE);
fill_config_int(DRIVER_FRAME_SIZE, DFT_FRAME_SIZE);
fill_config_str(CODEC1, DFT_CODEC);
fill_config_str(CODEC2, DFT_CODEC);
fill_config_str(CODEC3, DFT_CODEC);
......@@ -1118,6 +1119,7 @@ ManagerImpl::selectAudioDriver (void)
if (sampleRate <=0 || sampleRate > 48000) {
sampleRate = 8000;
}
int frameSize = getConfigInt(AUDIO, DRIVER_FRAME_SIZE);
// this is when no audio device in/out are set
// or the audio device in/out are set to 0
......@@ -1128,7 +1130,7 @@ ManagerImpl::selectAudioDriver (void)
//}
_debugInit(" AudioLayer Opening Device");
_audiodriver->setErrorMessage("");
_audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate);
_audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate, frameSize);
}
/**
......@@ -1787,10 +1789,11 @@ ManagerImpl::removeAccount(const AccountID& accountID)
std::string
ManagerImpl::getDefaultAccount()
{
std::string id;
id = getConfigString(PREFERENCES, "DefaultAccount");
_debug("Default Account = %s\n",id.c_str());
return id;
return id;
}
void
......
......@@ -62,7 +62,7 @@
#define DRIVER_NAME_IN "Drivers.driverNameIn"
#define DRIVER_NAME_OUT "Drivers.driverNameOut"
#define DRIVER_SAMPLE_RATE "Drivers.sampleRate"
#define DRIVER_SAMPLE_RATE_DEFAULT "8000"
#define DRIVER_FRAME_SIZE "Drivers.framesize"
#define NB_CODEC "Codecs.nbCodec"
#define CODEC1 "Codecs.codec1"
#define CODEC2 "Codecs.codec2"
......@@ -102,6 +102,8 @@
#define DFT_SKIN "metal"
#define DFT_ZONE "North America"
#define DFT_VOICEMAIL "888"
#define DFT_FRAME_SIZE "20"
#define DFT_SAMPLE_RATE "44100"
// zeroconfig default value
#ifdef USE_ZEROCONF
#define CONFIG_ZEROCONF_DEFAULT_STR "1"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment