Commit 9963c8ff authored by Tristan Matthews's avatar Tristan Matthews

* #11269: merged master into video

parent 1cbb4291
......@@ -2,6 +2,8 @@
# SFLphone
################################################
* 2012-05-17: 1.1.0 has been released
* 2011-11-18: 1.0.1 has been released
* 2011-09-30: 1.0.0 has been released
......
......@@ -21,8 +21,7 @@ endif
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libs src ringtones man $(TESTS_DIR) doc
EXTRA_DIST = README.gentoo \
m4/libtool.m4 \
EXTRA_DIST = m4/libtool.m4 \
m4/lt~obsolete.m4 \
m4/ltoptions.m4 \
m4/ltsugar.m4 \
......
......@@ -2,7 +2,7 @@ dnl SFLPhone - configure.ac for automake 1.9 and autoconf 2.59
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65])
AC_INIT([sflphone],[1.0.2],[sflphoneteam@savoirfairelinux.com],[sflphone])
AC_INIT([sflphone],[1.1.0],[sflphoneteam@savoirfairelinux.com],[sflphone])
AC_COPYRIGHT([[Copyright (c) Savoir-Faire Linux 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012]])
AC_REVISION([$Revision$])
......
......@@ -56,7 +56,7 @@ Account::Account(const std::string &accountID, const std::string &type) :
, userAgent_("SFLphone")
, mailBox_()
{
// Initialize the codec list, used when creating a new account
// Initialize the codec order, used when creating a new account
loadDefaultCodecs();
}
......@@ -77,25 +77,25 @@ void Account::setRegistrationState(const RegistrationState &state)
void Account::loadDefaultCodecs()
{
// Initialize codec
std::vector<std::string> codecList;
codecList.push_back("0");
codecList.push_back("3");
codecList.push_back("8");
codecList.push_back("9");
codecList.push_back("110");
codecList.push_back("111");
codecList.push_back("112");
std::vector<std::string> result;
result.push_back("0");
result.push_back("3");
result.push_back("8");
result.push_back("9");
result.push_back("110");
result.push_back("111");
result.push_back("112");
setActiveCodecs(codecList);
setActiveCodecs(result);
#ifdef SFL_VIDEO
setActiveVideoCodecs(sfl_video::getCodecList());
#endif
}
#ifdef SFL_VIDEO
void Account::setActiveVideoCodecs (const std::vector <std::string> &list)
void Account::setActiveVideoCodecs(const std::vector<std::string> &list)
{
videoCodecList_ = !list.empty() ? list : sfl_video::getCodecList();
videoCodecList_ = !list.empty() ? list : sfl_video::getCodecList();
}
#endif
......@@ -105,14 +105,15 @@ void Account::setActiveCodecs(const std::vector <std::string> &list)
codecList_.clear();
// list contains the ordered payload of active codecs picked by the user for this account
// we used the CodecList vector to save the order.
for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i) {
int payload = std::atoi(i->c_str());
// we used the CodecOrder vector to save the order.
for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end();
++iter) {
int payload = std::atoi(iter->c_str());
codecList_.push_back(static_cast<int>(payload));
}
// update the codec string according to new codec selection
codecStr_ = ManagerImpl::serialize(list);
codecStr_ = ManagerImpl::join_string(list);
}
std::string Account::mapStateNumberToString(RegistrationState state)
......
......@@ -76,10 +76,14 @@ static const char *const CONFIG_ACCOUNT_ALIAS = "Account.alias";
static const char *const CONFIG_ACCOUNT_MAILBOX = "Account.mailbox";
static const char *const CONFIG_ACCOUNT_ENABLE = "Account.enable";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.registrationExpire";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
static const char *const CONFIG_CREDENTIAL_NUMBER = "Credential.count";
static const char *const CONFIG_ACCOUNT_DTMF_TYPE = "Account.dtmfType";
static const char *const CONFIG_RINGTONE_PATH = "Account.ringtonePath";
static const char *const CONFIG_RINGTONE_ENABLED = "Account.ringtoneEnabled";
static const char *const CONFIG_KEEP_ALIVE_ENABLED = "Account.keepAliveEnabled";
static const char *const CONFIG_ACCOUNT_HOSTNAME = "Account.hostname";
static const char *const CONFIG_ACCOUNT_USERNAME = "Account.username";
......@@ -128,10 +132,6 @@ static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireCli
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC = "TLS.negotiationTimeoutSec";
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
static const char *const CONFIG_REGISTRATION_STATUS = "Registration.Status";
static const char *const CONFIG_REGISTRATION_STATE_CODE = "Registration.code";
static const char *const CONFIG_REGISTRATION_STATE_DESCRIPTION = "Registration.description";
// General configuration keys for accounts
static const char * const ALIAS_KEY = "alias";
static const char * const TYPE_KEY = "type";
......@@ -295,7 +295,7 @@ class Account : public Serializable {
/**
* Helper function used to load the default codec order from the codec factory
* setActiveCodecs is called to sync both codecOrder_ and codecStr_
* setActiveCodecs is called to sync both codecList_ and codecStr_
*/
void loadDefaultCodecs();
......
......@@ -219,7 +219,7 @@ AlsaLayer::stopStream()
#define ALSA_CALL(call, error) ({ \
int err_code = call; \
if (err_code < 0) \
ERROR("ALSA: "error": %s", snd_strerror(err_code)); \
ERROR(error ": %s", snd_strerror(err_code)); \
err_code; \
})
......@@ -314,16 +314,16 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
TRY(snd_pcm_hw_params_any(HW), "hwparams init");
TRY(snd_pcm_hw_params_set_access(HW, SND_PCM_ACCESS_RW_INTERLEAVED), "access type");
TRY(snd_pcm_hw_params_set_format(HW, SND_PCM_FORMAT_S16_LE), "sample format");
TRY(snd_pcm_hw_params_set_rate_near(HW, &audioSampleRate_, NULL), "sample rate");
TRY(snd_pcm_hw_params_set_rate_near(HW, &sampleRate_, NULL), "sample rate");
TRY(snd_pcm_hw_params_set_channels(HW, 1), "channel count");
TRY(snd_pcm_hw_params_set_period_size_near(HW, &periodSize, NULL), "period time");
TRY(snd_pcm_hw_params_set_periods_near(HW, &periods, NULL), "periods number");
TRY(snd_pcm_hw_params(HW), "hwparams");
#undef HW
DEBUG("ALSA: %s using sampling rate %dHz",
DEBUG("%s using sampling rate %dHz",
(snd_pcm_stream(pcm_handle) == SND_PCM_STREAM_PLAYBACK) ? "playback" : "capture",
audioSampleRate_);
sampleRate_);
snd_pcm_sw_params_t *swparams = NULL;
snd_pcm_sw_params_alloca(&swparams);
......@@ -370,7 +370,7 @@ AlsaLayer::write(void* buffer, int length, snd_pcm_t * handle)
}
default:
ERROR("ALSA: unknown write error, dropping frames: %s", snd_strerror(err));
ERROR("Unknown write error, dropping frames: %s", snd_strerror(err));
stopPlaybackStream();
break;
}
......@@ -405,12 +405,12 @@ AlsaLayer::read(void* buffer, int toCopy)
startCaptureStream();
}
ERROR("ALSA: XRUN capture ignored (%s)", snd_strerror(err));
ERROR("XRUN capture ignored (%s)", snd_strerror(err));
break;
}
case EPERM:
ERROR("ALSA: Can't capture, EPERM (%s)", snd_strerror(err));
ERROR("Can't capture, EPERM (%s)", snd_strerror(err));
prepareCaptureStream();
startCaptureStream();
break;
......@@ -456,7 +456,7 @@ AlsaLayer::getAudioDeviceIndexMap(AudioStreamDirection dir) const
snd_ctl_card_info_alloca(&info);
snd_pcm_info_alloca(&pcminfo);
int numCard = -1 ;
int numCard = -1;
std::vector<HwIDPair> audioDevice;
......@@ -541,7 +541,7 @@ AlsaLayer::getAudioDeviceIndex(const std::string &description) const
void AlsaLayer::capture()
{
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
bool resample = sampleRate_ != mainBufferSampleRate;
int toGetSamples = snd_pcm_avail_update(captureHandle_);
......@@ -567,10 +567,11 @@ void AlsaLayer::capture()
AudioLayer::applyGain(&(*in.begin()), toGetSamples, getCaptureGain());
if (resample) {
int outSamples = toGetSamples * ((double) audioSampleRate_ / mainBufferSampleRate);
int outSamples = toGetSamples * ((double) sampleRate_ / mainBufferSampleRate);
std::vector<SFLDataFormat> rsmpl_out(outSamples);
converter_->resample(&(*in.begin()), &(*rsmpl_out.begin()),
mainBufferSampleRate, audioSampleRate_, toGetSamples);
converter_.resample(&(*in.begin()), &(*rsmpl_out.begin()),
rsmpl_out.size(), mainBufferSampleRate, sampleRate_,
toGetSamples);
dcblocker_.process(&(*rsmpl_out.begin()), &(*rsmpl_out.begin()), outSamples);
Manager::instance().getMainBuffer()->putData(&(*rsmpl_out.begin()),
rsmpl_out.size() * sizeof(rsmpl_out[0]), MainBuffer::DEFAULT_ID);
......@@ -585,7 +586,7 @@ void AlsaLayer::playback(int maxSamples)
{
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
bool resample = sampleRate_ != mainBufferSampleRate;
int toGet = Manager::instance().getMainBuffer()->availForGet(MainBuffer::DEFAULT_ID);
int toPut = maxSamples * sizeof(SFLDataFormat);
......@@ -617,7 +618,7 @@ void AlsaLayer::playback(int maxSamples)
double resampleFactor = 1.0;
if (resample) {
resampleFactor = (double) audioSampleRate_ / mainBufferSampleRate;
resampleFactor = (double) sampleRate_ / mainBufferSampleRate;
maxNbBytesToGet = (double) toGet / resampleFactor;
}
......@@ -631,10 +632,10 @@ void AlsaLayer::playback(int maxSamples)
if (resample) {
int inSamples = toGet / sizeof(SFLDataFormat);
int outSamples = inSamples * resampleFactor;
SFLDataFormat *rsmpl_out = (SFLDataFormat*) malloc(outSamples * sizeof(SFLDataFormat));
converter_->resample(out, rsmpl_out, mainBufferSampleRate, audioSampleRate_, inSamples);
write(rsmpl_out, outSamples * sizeof(SFLDataFormat), playbackHandle_);
free(rsmpl_out);
std::vector<SFLDataFormat> rsmpl_out(outSamples);
converter_.resample(out, &(*rsmpl_out.begin()), rsmpl_out.size(),
mainBufferSampleRate, sampleRate_, inSamples);
write(&(*rsmpl_out.begin()), outSamples * sizeof(SFLDataFormat), playbackHandle_);
} else {
write(out, toGet, playbackHandle_);
}
......
......@@ -40,25 +40,16 @@ unsigned int AudioLayer::playbackGain_ = 100;
AudioLayer::AudioLayer()
: isStarted_(false)
, urgentRingBuffer_(SIZEBUF, MainBuffer::DEFAULT_ID)
, audioSampleRate_(Manager::instance().getMainBuffer()->getInternalSamplingRate())
, sampleRate_(Manager::instance().getMainBuffer()->getInternalSamplingRate())
, mutex_()
, dcblocker_()
, audioPref(Manager::instance().audioPreference)
, converter_(new SamplerateConverter(audioSampleRate_))
, converter_(sampleRate_)
, lastNotificationTime_(0)
{
urgentRingBuffer_.createReadPointer(MainBuffer::DEFAULT_ID);
}
AudioLayer::~AudioLayer()
{
if(converter_) {
delete converter_;
converter_ = NULL;
}
}
void AudioLayer::flushMain()
{
ost::MutexLock guard(mutex_);
......
......@@ -62,7 +62,7 @@ class AudioLayer {
public:
AudioLayer();
virtual ~AudioLayer();
virtual ~AudioLayer() {}
virtual std::vector<std::string> getAudioDeviceList(AudioStreamDirection dir) const = 0;
......@@ -158,7 +158,7 @@ class AudioLayer {
* default: 44100 HZ
*/
unsigned int getSampleRate() const {
return audioSampleRate_;
return sampleRate_;
}
/**
......@@ -199,7 +199,7 @@ class AudioLayer {
* 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_;
unsigned int sampleRate_;
/**
* Lock for the entire audio layer
......@@ -219,7 +219,7 @@ class AudioLayer {
/**
* Manage sampling rate conversion
*/
SamplerateConverter *converter_;
SamplerateConverter converter_;
private:
/**
......
......@@ -53,10 +53,10 @@ AudioLoop::getNext(SFLDataFormat* output, size_t total_samples, short volume)
size_t pos = pos_;
if (size_ == 0) {
ERROR("AudioLoop: Error: Audio loop size is 0");
ERROR("Audio loop size is 0");
return;
} else if (pos >= size_) {
ERROR("AudioLoop: Error: Invalid loop position %d", pos);
ERROR("Invalid loop position %d", pos);
return;
}
......
......@@ -28,6 +28,10 @@
* as that of the covered work.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "audiorecord.h"
#include <unistd.h>
#include <sstream> // for stringstream
......@@ -98,16 +102,16 @@ void AudioRecord::setRecordingOption(FILE_TYPE type, int sndSmplRate, const std:
void AudioRecord::initFilename(const std::string &peerNumber)
{
std::string fName(filename_);
fName.append("-" + peerNumber);
fName.append("-" + peerNumber + "-" PACKAGE);
if (fileType_ == FILE_RAW) {
if (filename_.find(".raw") == std::string::npos) {
DEBUG("AudioRecord: concatenate .raw file extension: name : %s", filename_.c_str());
DEBUG("Concatenate .raw file extension: name : %s", filename_.c_str());
fName.append(".raw");
}
} else if (fileType_ == FILE_WAV) {
if (filename_.find(".wav") == std::string::npos) {
DEBUG("AudioRecord: concatenate .wav file extension: name : %s", filename_.c_str());
DEBUG("Concatenate .wav file extension: name : %s", filename_.c_str());
fName.append(".wav");
}
}
......@@ -125,7 +129,7 @@ bool AudioRecord::openFile()
bool result = false;
if (not fileExists()) {
DEBUG("AudioRecord: Filename does not exist, creating one");
DEBUG("Filename does not exist, creating one");
byteCounter_ = 0;
if (fileType_ == FILE_RAW)
......@@ -133,7 +137,7 @@ bool AudioRecord::openFile()
else if (fileType_ == FILE_WAV)
result = setWavFile();
} else {
DEBUG("AudioRecord: Filename already exists, opening it");
DEBUG("Filename already exists, opening it");
if (fileType_ == FILE_RAW)
result = openExistingRawFile();
else if (fileType_ == FILE_WAV)
......@@ -180,7 +184,7 @@ void AudioRecord::setRecording()
void AudioRecord::stopRecording()
{
DEBUG("AudioRecording: Stop recording");
DEBUG("Stop recording");
recordingEnabled_ = false;
}
......@@ -227,7 +231,7 @@ void AudioRecord::createFilename()
out << timeinfo->tm_sec;
filename_ = out.str();
DEBUG("AudioRecord: Generate filename for this call %s ", filename_.c_str());
DEBUG("Generate filename for this call %s ", filename_.c_str());
}
bool AudioRecord::setRawFile()
......@@ -235,11 +239,11 @@ bool AudioRecord::setRawFile()
fileHandle_ = fopen(savePath_.c_str(), "wb");
if (!fileHandle_) {
WARN("AudioRecord: Could not create RAW file!");
WARN("Could not create RAW file!");
return false;
}
DEBUG("AudioRecord:setRawFile() : created RAW file.");
DEBUG("created RAW file.");
return true;
}
......@@ -267,12 +271,12 @@ namespace {
bool AudioRecord::setWavFile()
{
DEBUG("AudioRecord: Create new wave file %s, sampling rate: %d", savePath_.c_str(), sndSmplRate_);
DEBUG("Create new wave file %s, sampling rate: %d", savePath_.c_str(), sndSmplRate_);
fileHandle_ = fopen(savePath_.c_str(), "wb");
if (!fileHandle_) {
WARN("AudioRecord: Error: could not create WAV file.");
WARN("Could not create WAV file.");
return false;
}
......@@ -297,11 +301,11 @@ bool AudioRecord::setWavFile()
hdr.bytes_per_sec = hdr.sample_rate * hdr.bytes_per_samp;
if (fwrite(&hdr, 4, 11, fileHandle_) != 11) {
WARN("AudioRecord: Error: could not write WAV header for file. ");
WARN("Could not write WAV header for file. ");
return false;
}
DEBUG("AudioRecord: Wrote wave header \"%s\"", header_to_string(hdr).c_str());
DEBUG("Wrote wave header \"%s\"", header_to_string(hdr).c_str());
return true;
}
......@@ -310,7 +314,7 @@ bool AudioRecord::openExistingRawFile()
fileHandle_ = fopen(filename_.c_str(), "ab+");
if (!fileHandle_) {
WARN("AudioRecord: could not create RAW file!");
WARN("could not create RAW file!");
return false;
}
......@@ -319,37 +323,37 @@ bool AudioRecord::openExistingRawFile()
bool AudioRecord::openExistingWavFile()
{
DEBUG("%s(%s)\n", __PRETTY_FUNCTION__, filename_.c_str());
DEBUG("Opening %s", filename_.c_str());
fileHandle_ = fopen(filename_.c_str(), "rb+");
if (!fileHandle_) {
WARN("AudioRecord: Error: could not open WAV file!");
WARN("Could not open WAV file!");
return false;
}
if (fseek(fileHandle_, 40, SEEK_SET) != 0) // jump to data length
WARN("AudioRecord: Error: Couldn't seek offset 40 in the file ");
WARN("Couldn't seek offset 40 in the file ");
if (fread(&byteCounter_, 4, 1, fileHandle_))
WARN("AudioRecord: Error: bytecounter Read successfully ");
WARN("bytecounter Read successfully ");
if (fseek(fileHandle_, 0 , SEEK_END) != 0)
WARN("AudioRecord: Error: Couldn't seek at the en of the file ");
WARN("Couldn't seek at the en of the file ");
if (fclose(fileHandle_) != 0)
WARN("AudioRecord: Error: Can't close file r+ ");
WARN("Can't close file r+ ");
fileHandle_ = fopen(filename_.c_str(), "ab+");
if (!fileHandle_) {
WARN("AudioRecord: Error: Could not createopen WAV file ab+!");
WARN("Could not createopen WAV file ab+!");
return false;
}
if (fseek(fileHandle_, 4 , SEEK_END) != 0)
WARN("AudioRecord: Error: Couldn't seek at the en of the file ");
WARN("Couldn't seek at the en of the file ");
return true;
......@@ -358,50 +362,50 @@ bool AudioRecord::openExistingWavFile()
void AudioRecord::closeWavFile()
{
if (fileHandle_ == 0) {
DEBUG("AudioRecord: Can't closeWavFile, a file has not yet been opened!");
DEBUG("Can't closeWavFile, a file has not yet been opened!");
return;
}
DEBUG("AudioRecord: Close wave file");
DEBUG("Close wave file");
SINT32 bytes = byteCounter_ * channels_;
fseek(fileHandle_, 40, SEEK_SET); // jump to data length
if (ferror(fileHandle_))
WARN("AudioRecord: Error: can't reach offset 40 while closing");
WARN("Can't reach offset 40 while closing");
fwrite(&bytes, sizeof(SINT32), 1, fileHandle_);
if (ferror(fileHandle_))
WARN("AudioRecord: Error: can't write bytes for data length ");
WARN("Can't write bytes for data length ");
bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header
fseek(fileHandle_, 4, SEEK_SET); // jump to file size
if (ferror(fileHandle_))
WARN("AudioRecord: Error: can't reach offset 4");
WARN("Can't reach offset 4");
fwrite(&bytes, 4, 1, fileHandle_);
if (ferror(fileHandle_))
WARN("AudioRecord: Error: can't reach offset 4");
WARN("Can't reach offset 4");
if (fclose(fileHandle_) != 0)
WARN("AudioRecord: Error: can't close file");
WARN("Can't close file");
}
void AudioRecord::recData(SFLDataFormat* buffer, size_t nSamples)
{
if (recordingEnabled_) {
if (fileHandle_ == 0) {
DEBUG("AudioRecord: Can't record data, a file has not yet been opened!");
DEBUG("Can't record data, a file has not yet been opened!");
return;
}
if (fwrite(buffer, sizeof(SFLDataFormat), nSamples, fileHandle_) != nSamples)
WARN("AudioRecord: Could not record data! ");
WARN("Could not record data! ");
else {
fflush(fileHandle_);
byteCounter_ += nSamples * sizeof(SFLDataFormat);
......
......@@ -30,13 +30,15 @@
#include "audiorecorder.h"
#include "mainbuffer.h"
#include "logger.h"
#include <sstream>
#include <cassert>
#include <tr1/array>
int AudioRecorder::count_ = 0;
AudioRecorder::AudioRecorder(AudioRecord *arec, MainBuffer *mb) : ost::Thread(),
recorderId_(), mbuffer_(mb), arecord_(arec)
recorderId_(), mbuffer_(mb), arecord_(arec), running_(true)
{
assert(mb);
......@@ -59,16 +61,16 @@ AudioRecorder::AudioRecorder(AudioRecord *arec, MainBuffer *mb) : ost::Thread()
void AudioRecorder::run()
{
const size_t BUFFER_LENGTH = 10000;
SFLDataFormat buffer[BUFFER_LENGTH];
std::tr1::array<SFLDataFormat, BUFFER_LENGTH> buffer;
buffer.assign(0);
while (isRunning()) {
while (running_) {
size_t availBytes = mbuffer_->availForGet(recorderId_);
mbuffer_->getData(buffer, std::min(availBytes, BUFFER_LENGTH), recorderId_);
mbuffer_->getData(buffer.data(), std::min(availBytes, buffer.size()), recorderId_);
if (availBytes > 0)
arecord_->recData(buffer, availBytes / sizeof(SFLDataFormat));
arecord_->recData(buffer.data(), availBytes / sizeof(SFLDataFormat));
sleep(20);
Thread::sleep(20);
}
}
......@@ -44,6 +44,7 @@ class AudioRecorder : public ost::Thread {
AudioRecorder(AudioRecord *arec, MainBuffer *mb);
~AudioRecorder() {
running_ = false;
terminate();
}
......@@ -61,6 +62,7 @@ class AudioRecorder : public ost::Thread {
std::string recorderId_;
MainBuffer *mbuffer_;
AudioRecord *arecord_;
bool running_;