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

Merge branch 'debug_threads'

Conflicts:

	configure.ac
	src/Makefile.am
	src/audio/alsalayer.cpp
	src/audio/audiortp.cpp
parents 971c3106 aadb2a64
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
aclocal -I m4 aclocal -I m4
libtoolize --force libtoolize --force
autoheader autoheader
autoconf -f autoconf -v -f
automake -a automake -a
./configure $@ ./configure $@
...@@ -36,7 +36,10 @@ AC_CONFIG_FILES([src/Makefile \ ...@@ -36,7 +36,10 @@ AC_CONFIG_FILES([src/Makefile \
src/audio/codecs/Makefile src/audio/codecs/Makefile
src/audio/codecs/ilbc/Makefile \ src/audio/codecs/ilbc/Makefile \
src/config/Makefile \ src/config/Makefile \
src/dbus/Makefile ]) src/dbus/Makefile \
src/plug-in/audiorecorder/Makefile \
src/plug-in/Makefile \
src/plug-in/test/Makefile])
dnl Unitary test section dnl Unitary test section
AC_CONFIG_FILES([test/Makefile]) AC_CONFIG_FILES([test/Makefile])
......
# Global variables # Global variables
src=$(top_srcdir) src=$(top_srcdir)
sflcodecdir=$(libdir)/sflphone/codecs sflcodecdir=$(libdir)/sflphone/codecs
sflplugindir=$(libdir)/sflphone/plugins
PJSIP_LIBS = -lpjnath-sfl -lpjsua-sfl -lpjsip-sfl -lpjmedia-sfl -lpjsip-simple-sfl -lpjsip-ua-sfl -lpjmedia-codec-sfl -lpjlib-util-sfl -lpj-sfl PJSIP_LIBS = -lpjnath-sfl -lpjsua-sfl -lpjsip-sfl -lpjmedia-sfl -lpjsip-simple-sfl -lpjsip-ua-sfl -lpjmedia-codec-sfl -lpjlib-util-sfl -lpj-sfl
...@@ -16,5 +17,6 @@ AM_CPPFLAGS = \ ...@@ -16,5 +17,6 @@ AM_CPPFLAGS = \
@SIP_CFLAGS@ \ @SIP_CFLAGS@ \
@DBUSCPP_CFLAGS@ \ @DBUSCPP_CFLAGS@ \
-DCODECS_DIR=\""$(sflcodecdir)"\" \ -DCODECS_DIR=\""$(sflcodecdir)"\" \
-DPLUGINS_DIR=\""$(sflplugindir)"\" \
-DENABLE_TRACE -DENABLE_TRACE
...@@ -13,7 +13,7 @@ IAXSOURCES = ...@@ -13,7 +13,7 @@ IAXSOURCES =
IAXHEADERS = IAXHEADERS =
endif endif
SUBDIRS = audio config dbus SUBDIRS = audio config dbus plug-in
# Add here the cpp files to be build with sflphone # Add here the cpp files to be build with sflphone
sflphoned_SOURCES = \ sflphoned_SOURCES = \
...@@ -75,6 +75,8 @@ libsflphone_la_LIBADD = \ ...@@ -75,6 +75,8 @@ libsflphone_la_LIBADD = \
./audio/libaudio.la \ ./audio/libaudio.la \
./dbus/libdbus.la \ ./dbus/libdbus.la \
./config/libconfig.la \ ./config/libconfig.la \
./plug-in/libplugin.la \
./plug-in/audiorecorder/libaudiorecorder.la \
$(IAX_LIBS) $(IAX_LIBS)
libsflphone_la_SOURCES = libsflphone_la_SOURCES =
...@@ -96,6 +96,8 @@ class Account{ ...@@ -96,6 +96,8 @@ class Account{
*/ */
inline VoIPLink* getVoIPLink() { return _link; } inline VoIPLink* getVoIPLink() { return _link; }
inline void setVoIPLink (VoIPLink *link) { _link = link; }
/** /**
* Register the underlying VoIPLink. Launch the event listener. * Register the underlying VoIPLink. Launch the event listener.
* This should update the getRegistrationState() return value. * This should update the getRegistrationState() return value.
......
...@@ -193,9 +193,10 @@ void AlsaLayer::startCaptureStream (void) ...@@ -193,9 +193,10 @@ void AlsaLayer::startCaptureStream (void)
void AlsaLayer::prepareCaptureStream (void) void AlsaLayer::prepareCaptureStream (void)
{ {
if (is_capture_open() ) { if (is_capture_open() ) {
_debug("Prepare the capture\n"); if(snd_pcm_prepare (_CaptureHandle) < 0)
if(snd_pcm_prepare (_CaptureHandle) < 0) _debug("Error preparing the device\n"); _debug("");
prepare_capture (); else
prepare_capture ();
} }
} }
...@@ -383,11 +384,11 @@ AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag) ...@@ -383,11 +384,11 @@ AlsaLayer::open_device(std::string pcm_p, std::string pcm_c, int flag)
} }
/* Start the secondary audio thread for callbacks */ /* Start the secondary audio thread for callbacks */
try { try{
_audioThread->start(); _audioThread->start();
} }
catch(...){ catch (...) {
_debug("Fail to start audio thread\n"); _debugException("Fail to start audio thread\n");
} }
return true; return true;
......
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Alexandre Savard <alexandre.savard@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 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "audiorecord.h"
AudioRecord::AudioRecord(){
sndSmplRate_ = 44100;
channels_ = 1;
byteCounter_ = 0;
}
void AudioRecord::setSndSamplingRate(int smplRate){
sndSmplRate_ = smplRate;
}
void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
channels_ =1;
fileType_ = type;
byteCounter_ = 0;
sndFormat_ = format;
bool result = false;
if(fileType_ == FILE_RAW){
result = setRawFile( fileName.c_str() );
}
else if (fileType_ == FILE_WAV){
result = setWavFile( fileName.c_str() );
}
}
void AudioRecord::closeFile() {
if (fp == 0) return;
if (fileType_ == FILE_RAW)
fclose(fp);
else if (fileType_ == FILE_WAV)
this->closeWavFile();
}
bool AudioRecord::isOpenFile() {
if(fp)
return true;
else
return false;
}
bool AudioRecord::setRawFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create RAW file: " << name << '.';
return false;
}
if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
sndFormat_ = INT16;
cout << "AudioRecord: using 16-bit signed integer data format for file " << name << '.';
}
cout << "AudioRecord: creating RAW file: " << name;
return true;
}
bool AudioRecord::setWavFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create WAV file: " << name;
return false;
}
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
44100, 0, 2, 16, "dat", 0};
hdr.riff[3] = 'F';
hdr.wave[3] = 'E';
hdr.fmt[3] = ' ';
hdr.data[3] = 'a';
hdr.num_chans = channels_;
if ( sndFormat_ == INT16 ) { // TODO need to write INT16 to SINT16
hdr.bits_per_samp = 16;
}
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
if ( fwrite(&hdr, 4, 11, fp) != 11 ) {
cout << "AudioRecord: could not write WAV header for file " << name << '.';
return false;
}
cout << "AudioRecord: creating WAV file: " << name;
return true;
}
void AudioRecord::closeWavFile()
{
int bytes_per_sample = 1;
if ( sndFormat_ == INT16 )
bytes_per_sample = 2;
SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
fseek(fp, 40, SEEK_SET); // jump to data length
fwrite(&bytes, 4, 1, fp);
bytes = byteCounter_ * channels_ * bytes_per_sample + 44; // + 44 for the wave header
fseek(fp, 4, SEEK_SET); // jump to file size
fwrite(&bytes, 4, 1, fp);
fclose( fp );
}
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
if (fp == 0){
cout << "AudioRecord: Can't record data, a file has not yet been opened!";
return;
}
if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
if (nSamples <= 1){
if ( fwrite(buffer, 2, 1, fp) != 1)
cout << "AudioRecord: Could not record data!";
}
else {
for ( int k=0; k<nSamples; k++ ) {
cout << "Buffer[" << k << "] : " << buffer[k] << "\n";
if ( fwrite(&buffer[k], 2, 1, fp) != 1 )
cout << "AudioRecord: Could not record data!";
}
}
}
byteCounter_ += (unsigned long)(sizeof(buffer) / sizeof(SINT16));
return;
}
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Author: Alexandre Savard <alexandre.savard@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 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <iostream>
#include <string.h>
#include "global.h"
using namespace std;
// structure for the wave header
struct wavhdr {
char riff[4]; // "RIFF"
SINT32 file_size; // in bytes
char wave[4]; // "WAVE"
char fmt[4]; // "fmt "
SINT32 chunk_size; // in bytes (16 for PCM)
SINT16 format_tag; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
SINT16 num_chans; // 1=mono, 2=stereo
SINT32 sample_rate;
SINT32 bytes_per_sec;
SINT16 bytes_per_samp; // 2=16-bit mono, 4=16-bit stereo
SINT16 bits_per_samp;
char data[4]; // "data"
SINT32 data_length; // in bytes
};
class AudioRecord
{
public:
AudioRecord();
void setSndSamplingRate(int smplRate);
/**
* Check if no otehr file is opened, then create a new one
* @param fileName A string containing teh file (with/without extension)
* @param type The sound file format (FILE_RAW, FILE_WAVE)
* @param format Internal sound format (INT16 / INT32)
*/
void openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format);
/**
* Close the opend recording file. If wave: cout the number of byte
*/
void closeFile();
/**
* Check if a file is already opened
*/
bool isOpenFile();
/**
* Record a chunk of data in an openend file
* @param buffer The data chunk to be recorded
* @param nSamples Number of samples (number of bytes) to be recorded
*/
void recData(SFLDataFormat* buffer, int nSamples); // TODO ad the data to rec
protected:
/**
* Set the header for raw files
*/
bool setRawFile(const char* fileName);
/**
* Set the header for wave files
*/
bool setWavFile(const char* fileName);
/**
* Compute the number of byte recorded and close the file
*/
void closeWavFile();
/**
* Pointer to the recorded file
*/
FILE *fp; //file pointer
/**
* File format (RAW / WAVE)
*/
FILE_TYPE fileType_;
/**
* Sound format (SINT16/SINT32)
*/
SOUND_FORMAT sndFormat_;
/**
* Number of channels
*/
int channels_;
/**
* Number f byte recorded
*/
unsigned long byteCounter_;
/**
* Sampling rate
*/
int sndSmplRate_;
};
...@@ -82,7 +82,7 @@ void ...@@ -82,7 +82,7 @@ void
AudioRtp::closeRtpSession () { AudioRtp::closeRtpSession () {
ost::MutexLock m(_threadMutex); ost::MutexLock m(_threadMutex);
// This will make RTP threads finish. // This will make RTP threads finish.
// _debug("Stopping AudioRTP\n"); _debug("Stopping AudioRTP\n");
try { try {
delete _RTXThread; _RTXThread = 0; delete _RTXThread; _RTXThread = 0;
} catch(...) { } catch(...) {
...@@ -126,7 +126,6 @@ AudioRtpRTX::~AudioRtpRTX () { ...@@ -126,7 +126,6 @@ AudioRtpRTX::~AudioRtpRTX () {
_debugException("! ARTP: Thread destructor didn't terminate correctly"); _debugException("! ARTP: Thread destructor didn't terminate correctly");
throw; throw;
} }
//_debug("terminate audiortprtx ended...\n");
_ca = 0; _ca = 0;
if (!_sym) { if (!_sym) {
delete _sessionRecv; _sessionRecv = NULL; delete _sessionRecv; _sessionRecv = NULL;
...@@ -145,6 +144,7 @@ AudioRtpRTX::~AudioRtpRTX () { ...@@ -145,6 +144,7 @@ AudioRtpRTX::~AudioRtpRTX () {
delete time; time = NULL; delete time; time = NULL;
delete converter; converter = NULL; delete converter; converter = NULL;
} }
void void
......
...@@ -44,16 +44,10 @@ static void audioCallback ( pa_stream* s, size_t bytes, void* userdata ) ...@@ -44,16 +44,10 @@ static void audioCallback ( pa_stream* s, size_t bytes, void* userdata )
// Destructor // Destructor
PulseLayer::~PulseLayer (void) PulseLayer::~PulseLayer (void)
{ {
//closeLayer(); closeLayer ();
/* Delete the pointer streams */
delete playback;
delete record;
pa_context_disconnect( context ); pa_context_disconnect( context );
pa_context_unref( context ); pa_context_unref( context );
sleep(2);
} }
void void
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "audiolayer.h" #include "audiolayer.h"
#include "audiostream.h" #include "audiostream.h"
#include "plug-in/audiorecorder/audiorecord.h"
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
......
...@@ -54,6 +54,7 @@ void AudioThread::run (void) ...@@ -54,6 +54,7 @@ void AudioThread::run (void)
{ {
while(!testCancel()) { while(!testCancel()) {
_alsa->audioCallback(); _alsa->audioCallback();
Thread::sleep(3);
} }
} }
...@@ -37,6 +37,19 @@ ...@@ -37,6 +37,19 @@
typedef float float32; typedef float float32;
typedef short int16; typedef short int16;
//useful typedefs.
typedef signed short SINT16;
typedef signed int SINT32;
typedef unsigned long FILE_TYPE;
typedef unsigned long SOUND_FORMAT;
const FILE_TYPE FILE_RAW = 1;
const FILE_TYPE FILE_WAV = 2;
static const SOUND_FORMAT INT16 = 0x2; // TODO shold change these symbols
static const SOUND_FORMAT INT32 = 0x8;
#define SUCCESS 0 #define SUCCESS 0
#define ASSERT( expected , value) if( value == expected ) return SUCCESS; \ #define ASSERT( expected , value) if( value == expected ) return SUCCESS; \
......
...@@ -249,6 +249,7 @@ ManagerImpl::answerCall(const CallID& id) ...@@ -249,6 +249,7 @@ ManagerImpl::answerCall(const CallID& id)
bool bool
ManagerImpl::hangupCall(const CallID& id) ManagerImpl::hangupCall(const CallID& id)
{ {
_debug("ManagerImpl::hangupCall(): This function is called when user hangup \n");
PulseLayer *pulselayer; PulseLayer *pulselayer;
AccountID accountid; AccountID accountid;
bool returnValue; bool returnValue;
...@@ -370,6 +371,7 @@ ManagerImpl::transferCall(const CallID& id, const std::string& to) ...@@ -370,6 +371,7 @@ ManagerImpl::transferCall(const CallID& id, const std::string& to)
bool bool
ManagerImpl::refuseCall (const CallID& id) ManagerImpl::refuseCall (const CallID& id)
{ {
_debug("ManagerImpl::refuseCall(): method called");
stopTone(true); stopTone(true);
AccountID accountid = getAccountFromCall( id ); AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) { if (accountid == AccountNULL) {
...@@ -510,6 +512,7 @@ ManagerImpl::playDtmf(char code, bool isTalking) ...@@ -510,6 +512,7 @@ ManagerImpl::playDtmf(char code, bool isTalking)
// Put buffer to urgentRingBuffer // Put buffer to urgentRingBuffer
// put the size in bytes... // put the size in bytes...
// so size * 1 channel (mono) * sizeof (bytes for the data) // so size * 1 channel (mono) * sizeof (bytes for the data)
audiolayer->startStream();
audiolayer->putUrgent (buf, size * sizeof(SFLDataFormat)); audiolayer->putUrgent (buf, size * sizeof(SFLDataFormat));
} }
ret = true; ret = true;
...@@ -631,8 +634,10 @@ ManagerImpl::peerRingingCall(const CallID& id) ...@@ -631,8 +634,10 @@ ManagerImpl::peerRingingCall(const CallID& id)
void void
ManagerImpl::peerHungupCall(const CallID& id) ManagerImpl::peerHungupCall(const CallID& id)
{ {
_debug("ManagerImpl::peerHungupCall():this function is called when peer hangup \n");
PulseLayer *pulselayer; PulseLayer *pulselayer;
AccountID accountid; AccountID accountid;
bool returnValue;
accountid = getAccountFromCall( id ); accountid = getAccountFromCall( id );
if (accountid == AccountNULL) { if (accountid == AccountNULL) {
...@@ -648,6 +653,8 @@ ManagerImpl::peerHungupCall(const CallID& id) ...@@ -648,6 +653,8 @@ ManagerImpl::peerHungupCall(const CallID& id)
switchCall(""); switchCall("");
} }
returnValue = getAccountLink(accountid)->hangup(id);
removeWaitingCall(id); removeWaitingCall(id);
removeCallAccount(id); removeCallAccount(id);
...@@ -1408,9 +1415,14 @@ int ManagerImpl::isStunEnabled (void) ...@@ -1408,9 +1415,14 @@ int ManagerImpl::isStunEnabled (void)
void ManagerImpl::enableStun (void) void ManagerImpl::enableStun (void)
{ {
( getConfigInt( SIGNALISATION , STUN_ENABLE ) == STUN_ENABLED )? setConfig(SIGNALISATION , STUN_ENABLE , NO_STR ) : setConfig( SIGNALISATION , STUN_ENABLE , YES_STR ); /* Update the config */