Commit 2c49fa13 authored by alexandresavard's avatar alexandresavard

Record interface complete (on hold erase previous recording)

parent 6cafd5a6
......@@ -2,6 +2,6 @@ icondir = $(datadir)/pixmaps
icon_DATA = sflphone.png
buttons_DATA = accept.svg current.svg transfert.svg hang_up.svg hold.svg unhold.svg refuse.svg call.svg ring.svg dial.svg mic.svg mic_25.svg mic_50.svg mic_75.svg speaker.svg speaker_25.svg speaker_50.svg speaker_75.svg fail.svg incoming.svg outgoing.svg missed.svg mailbox.svg busy.svg icon_accept.svg icon_hold.svg icon_unhold.svg icon_hangup.svg icon_call.svg icon_dialpad.svg icon_volume.svg icon_dialpad_off.svg icon_volume_off.svg history.svg history2.svg sflphone.png stock_person.svg rec_call.svg record.svg
buttons_DATA = accept.svg current.svg transfert.svg hang_up.svg hold.svg unhold.svg refuse.svg call.svg ring.svg dial.svg mic.svg mic_25.svg mic_50.svg mic_75.svg speaker.svg speaker_25.svg speaker_50.svg speaker_75.svg fail.svg incoming.svg outgoing.svg missed.svg mailbox.svg busy.svg icon_accept.svg icon_hold.svg icon_unhold.svg icon_hangup.svg icon_call.svg icon_dialpad.svg icon_volume.svg icon_dialpad_off.svg icon_volume_off.svg history.svg history2.svg sflphone.png stock_person.svg rec_call.svg record.svg icon_rec.svg
buttonsdir = $(datadir)/sflphone
EXTRA_DIST = $(buttons_DATA) $(icon_DATA)
This diff is collapsed.
This diff is collapsed.
......@@ -708,6 +708,23 @@ sflphone_rec_call()
{
call_t * selectedCall = call_get_selected(current_calls);
dbus_set_record(selectedCall);
switch(selectedCall->state)
{
case CALL_STATE_CURRENT:
selectedCall->state = CALL_STATE_RECORD;
update_call_tree(current_calls,selectedCall);
update_menus();
break;
case CALL_STATE_RECORD:
selectedCall->state = CALL_STATE_CURRENT;
update_call_tree(current_calls,selectedCall);
update_menus();
break;
default:
break;
}
}
/* Internal to action - set the __CURRENT_ACCOUNT variable */
......
......@@ -47,7 +47,9 @@ typedef enum
/** Call is busy */
CALL_STATE_BUSY,
/** Call is being transfert. During this state, the user can enter the new number. */
CALL_STATE_TRANSFERT
CALL_STATE_TRANSFERT,
/** Call is on hold */
CALL_STATE_RECORD
} call_state_t;
/**
......
......@@ -282,7 +282,6 @@ toolbar_update_buttons ()
case CALL_STATE_RINGING:
gtk_widget_set_sensitive( GTK_WIDGET(hangupButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(callButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(recButton), TRUE);
break;
case CALL_STATE_DIALING:
if( active_calltree != history ) gtk_widget_set_sensitive( GTK_WIDGET(hangupButton), TRUE);
......@@ -302,7 +301,7 @@ toolbar_update_buttons ()
case CALL_STATE_FAILURE:
gtk_widget_set_sensitive( GTK_WIDGET(hangupButton), TRUE);
break;
case CALL_STATE_TRANSFERT:
case CALL_STATE_TRANSFERT:
gtk_signal_handler_block(GTK_OBJECT(transfertButton),transfertButtonConnId);
gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transfertButton), TRUE);
gtk_signal_handler_unblock(transfertButton, transfertButtonConnId);
......@@ -311,6 +310,13 @@ toolbar_update_buttons ()
gtk_widget_set_sensitive( GTK_WIDGET(holdButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(transfertButton), TRUE);
break;
case CALL_STATE_RECORD:
gtk_widget_set_sensitive( GTK_WIDGET(hangupButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(holdButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(transfertButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(callButton), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(recButton), TRUE);
break;
default:
g_warning("Should not happen!");
break;
......@@ -513,6 +519,7 @@ create_toolbar ()
#if GTK_CHECK_VERSION(2,12,0)
gtk_widget_set_tooltip_text(GTK_WIDGET(recButton), _("Record a call"));
#endif
gtk_widget_set_state( GTK_WIDGET(recButton), GTK_STATE_INSENSITIVE);
g_signal_connect (G_OBJECT (recButton), "clicked",
G_CALLBACK (rec_button), NULL);
gtk_toolbar_insert(GTK_TOOLBAR(ret), GTK_TOOL_ITEM(recButton), -1);
......@@ -710,6 +717,9 @@ update_call_tree (calltab_t* tab, call_t * c)
break;
case CALL_STATE_TRANSFERT:
pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/transfert.svg", NULL);
break;
case CALL_STATE_RECORD:
pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/rec_call.svg", NULL);
break;
default:
g_warning("Should not happen!");
......
......@@ -101,7 +101,7 @@ create_main_window ()
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_window_set_title (GTK_WINDOW (window), PACKAGE);
gtk_window_set_default_size (GTK_WINDOW (window), 230, 320);
gtk_window_set_default_size (GTK_WINDOW (window), 260, 320);
gtk_window_set_default_icon_from_file (ICONS_DIR "/sflphone.png",
NULL);
gtk_window_set_position( GTK_WINDOW( window ) , GTK_WIN_POS_MOUSE);
......
......@@ -92,6 +92,11 @@ void update_menus()
case CALL_STATE_FAILURE:
gtk_widget_set_sensitive( GTK_WIDGET(hangUpMenu), TRUE);
break;
case CALL_STATE_RECORD:
gtk_widget_set_sensitive( GTK_WIDGET(hangUpMenu), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(holdMenu), TRUE);
gtk_widget_set_sensitive( GTK_WIDGET(newCallMenu),TRUE);
break;
default:
g_warning("Should not happen in update_menus()!");
break;
......
......@@ -29,6 +29,7 @@
#include <math.h>
#include <dlfcn.h>
#include <iostream>
#include <sstream>
#include "../global.h"
#include "../manager.h"
......@@ -190,7 +191,21 @@ AudioRtpRTX::initAudioRtpSession (void)
return;
}
// Initialization
// Initialization
printf("AudioRTPX::initAudioRtpSession: CallID to be used: %s \n",_ca->getCallId().c_str());
printf("AudioRTPX::initAudioRtpSession: Account %s \n",Manager::instance().getAccountFromCall(_ca->getCallId()).c_str());
printf("AudioRTPX::initAudioSRtpSession: FileName from call class: %s \n", _ca->getFileName().c_str());
_debug("Opening the wave file\n");
FILE_TYPE ft = FILE_WAV;
SOUND_FORMAT sf = INT16;
recAudio.setSndSamplingRate(44100);
recAudio.openFile(_ca->getFileName(),ft,sf,_ca->getCallId());
if (!_sym) {
_sessionRecv->setSchedulingTimeout (10000);
_sessionRecv->setExpireTimeout(1000000);
......@@ -239,12 +254,7 @@ AudioRtpRTX::initAudioRtpSession (void)
}
}
}
_debug("Opening the wave file\n");
FILE_TYPE ft = FILE_WAV;
SOUND_FORMAT sf = INT16;
recAudio.setSndSamplingRate(44100);
recAudio.openFile("SFLWavFile.wav",ft,sf);
} catch(...) {
_debugException("! ARTP Failure: initialisation failed");
......@@ -450,7 +460,7 @@ AudioRtpRTX::run () {
recAudio.recData(spkrDataConverted,micData,_nSamplesSpkr,_nSamplesMic);
Thread::sleep(TimerPort::getTimer());
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
}
......
......@@ -121,7 +121,7 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
/** Speaker buffer length in samples once the data are resampled
* (used for mixing and recording)
*/
int _nSamplesSpkr;
int _nSamplesSpkr;
/** Mic buffer length in samples once the data are resampled
* (used for mixing and recording)
......
......@@ -36,6 +36,25 @@ Call::Call(const CallID& id, Call::CallType type)
, _peerName()
, _peerNumber()
{
time_t rawtime;
struct tm * timeinfo;
rawtime = std::time(NULL);
timeinfo = localtime ( &rawtime );
std::stringstream out;
out << timeinfo->tm_year+1900;
if (timeinfo->tm_mon < 9) // january is 01, not 1
out << 0;
out << timeinfo->tm_mon+1;
if (timeinfo->tm_mday < 10) // 01 02 03, not 1 2 3
out << 0;
out << timeinfo->tm_mday;
_filename = out.str();
printf("Call::constructor filename for tis call %s \n",_filename.c_str());
}
......
......@@ -21,8 +21,10 @@
#define CALL_H
#include <cc++/thread.h> // for mutex
#include <sstream>
#include "audio/codecDescriptor.h"
#include "plug-in/audiorecorder/audiorecord.h"
/*
* @file call.h
......@@ -208,6 +210,16 @@ class Call{
*/
AudioCodecType getAudioCodec();
/**
* @return Return the file name for this call
*/
std::string getFileName() {return _filename;}
/**
* A recorder fro this call
*/
AudioRecord audioRec;
protected:
/** Protect every attribute that can be changed by two threads */
ost::Mutex _callMutex;
......@@ -273,6 +285,8 @@ class Call{
/** Number of the peer */
std::string _peerNumber;
/** File name for his call : time YY-MM-DD */
std::string _filename;
};
#endif
......@@ -62,6 +62,9 @@ typedef std::map<CallID, AccountID> CallAccountMap;
/** Define a type for CallID vector (waiting list, incoming not answered) */
typedef std::set<CallID> CallIDSet;
/** Define a type for recorded audio file names vector */
typedef std::map<CallID, std::string> RecFileNames;
/** To send multiple string */
typedef std::list<std::string> TokenList;
......@@ -980,7 +983,8 @@ class ManagerImpl {
*/
bool removeCallAccount(const CallID& callID);
/** Contains a list of account (sip, aix, etc) and their respective voiplink/calls */
/**
*Contains a list of account (sip, aix, etc) and their respective voiplink/calls */
AccountMap _accountMap;
/**
......@@ -1002,6 +1006,12 @@ class ManagerImpl {
*/
bool accountExists(const AccountID& accountID);
/**
* Map the call id to coresponding call
*/
RecFileNames _fileNamesMap;
public:
/**
* Get an account pointer
......
......@@ -4,4 +4,4 @@ noinst_LTLIBRARIES = libaudiorecorder.la
libaudiorecorder_la_SOURCES = \
audiorecord.cpp
libsndfile.h
......@@ -19,6 +19,8 @@
#include "audiorecord.h"
AudioRecord::AudioRecord(){
sndSmplRate_ = 44100;
......@@ -34,22 +36,52 @@ void AudioRecord::setSndSamplingRate(int smplRate){
}
void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
channels_ =1;
fileType_ = type;
byteCounter_ = 0;
sndFormat_ = format;
bool result = false;
void AudioRecord::openFile(std::string name, FILE_TYPE type, SOUND_FORMAT format, CallID& id){
_debug("AudioRecord::openFile()\n");
bool result = false;
if(fileType_ == FILE_RAW){
result = setRawFile( fileName.c_str() );
strncpy(fileName_, name.c_str(), 8192);
fileType_ = type;
if (fileType_ == FILE_RAW){
if ( strstr(fileName_, ".raw") == NULL){
printf("AudioRecord::openFile::concatenate .raw file extension: name : %s \n", fileName_);
strcat(fileName_, ".raw");
}
}
else if (fileType_ == FILE_WAV){
if ( strstr(fileName_, ".wav") == NULL){
printf("AudioRecord::openFile::concatenate .wav file extension: name : %s \n", fileName_);
strcat(fileName_, ".wav");
}
}
if(isFileExist()) {
_debug("AudioRecord::Filename does not exist, creating one \n");
channels_ = 1;
byteCounter_ = 0;
sndFormat_ = format;
if(fileType_ == FILE_RAW){
result = setRawFile();
}
else if (fileType_ == FILE_WAV){
result = setWavFile();
}
}
else if (fileType_ == FILE_WAV){
result = setWavFile( fileName.c_str() );
else {
fileType_ = type;
_debug("AudioRecord::Filename already exist opening it \n");
if(fileType_ == FILE_RAW){
result = openExistingRawFile();
}
else if (fileType_ == FILE_WAV){
result = openExistingWavFile();
}
}
}
......@@ -74,8 +106,19 @@ bool AudioRecord::isOpenFile() {
}
bool AudioRecord::isFileExist() {
printf("AudioRecord::isFileExist(): try to open name : %s \n", fileName_);
if(fopen(fileName_,"rb")==0) {
return true;
}
return false;
}
bool AudioRecord::setRecording() {
printf("AudioRecord::setRecording()");
_debug("AudioRecord::setRecording()");
if(!recordingEnabled_)
recordingEnabled_ = true;
......@@ -85,35 +128,29 @@ bool AudioRecord::setRecording() {
}
bool AudioRecord::setRawFile(const char *fileName) {
bool AudioRecord::setRawFile() {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
fp = fopen(name, "wb");
fp = fopen(fileName_, "wb");
if ( !fp ) {
_debug("AudioRecord: could not create RAW file!\n");
_debug("AudioRecord::setRawFile() : could not create RAW file!\n");
return false;
}
if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
sndFormat_ = INT16;
_debug("AudioRecord: using 16-bit signed integer data format for file.\n");
_debug("AudioRecord::setRawFile() : using 16-bit signed integer data format for file.\n");
}
_debug("AudioRecord: creating RAW file.\n");
_debug("AudioRecord:setRawFile() : created RAW file.\n");
return true;
}
bool AudioRecord::setWavFile(const char *fileName) {
bool AudioRecord::setWavFile() {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
fp = fopen(name, "wb");
fp = fopen(fileName_, "wb");
if ( !fp ) {
_debug("AudioRecord: could not create WAV file.\n");
_debug("AudioRecord::setWavFile() : could not create WAV file.\n");
return false;
}
......@@ -132,63 +169,141 @@ bool AudioRecord::setWavFile(const char *fileName) {
if ( fwrite(&hdr, 4, 11, fp) != 11) {
_debug("AudioRecord: could not write WAV header for file.\n");
_debug("AudioRecord::setWavFile() : could not write WAV header for file. \n");
return false;
}
_debug("AudioRecord: creating WAV file.\n");
_debug("AudioRecord::setWavFile() : created WAV file. \n");
return true;
}
void AudioRecord::closeWavFile()
{
int bytes_per_sample = 1;
if ( sndFormat_ == INT16 )
bytes_per_sample = 2;
bool AudioRecord::openExistingRawFile()
{
fp = fopen(fileName_, "ab+");
if ( !fp ) {
_debug("AudioRecord::openExistingRawFile() : could not create RAW file!\n");
return false;
}
}
SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
fseek(fp, 40, SEEK_SET); // jump to data length
fwrite(&bytes, 4, 1, fp);
bool AudioRecord::openExistingWavFile()
{
_debug("AudioRecord::openExistingWavFile() \n");
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 );
}
fp = fopen(fileName_, "rb+");
if ( !fp ) {
_debug("AudioRecord::openExistingWavFile() : could not open WAV file rb+!\n");
return false;
}
printf("AudioRecord::openExistingWavFile()::Tried to open %s \n",fileName_);
if(fseek(fp, 40, SEEK_SET) != 0) // jump to data length
_debug("AudioRecord::OpenExistingWavFile: 1.Couldn't seek offset 40 in the file \n");
if(fread(&byteCounter_, 4, 1, fp))
_debug("AudioRecord::OpenExistingWavFile : bytecounter Read successfully \n");
if(fseek (fp, 0 , SEEK_END) != 0)
_debug("AudioRecors::OpenExistingWavFile : 2.Couldn't seek at the en of the file \n");
printf("AudioRecord::OpenExistingWavFile : Byte counter after oppening : %d \n",(int)byteCounter_);
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
if ( fclose( fp ) != 0)
_debug("AudioRecord::openExistingWavFile()::ERROR: can't close file r+ \n");
fp = fopen(fileName_, "ab+");
if ( !fp ) {
_debug("AudioRecord::openExistingWavFile() : could not createopen WAV file ab+!\n");
return false;
}
if(fseek (fp, 4 , SEEK_END) != 0)
_debug("AudioRecors::OpenExistingWavFile : 2.Couldn't seek at the en of the file \n");
}
void AudioRecord::closeWavFile()
{
if (fp == 0){
_debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
_debug("AudioRecord:: Can't closeWavFile, a file has not yet been opened!\n");
return;
}
// int size = nSamples * (sizeof(SFLDataFormat));
// int size = sizeof(buffer);
// int count = sizeof(buffer) / sizeof(SFLDataFormat);
// printf("AudioRecord : sizeof(buffer) : %d \n",size);
// printf("AudioRecord : sizeof(buffer) / sizeof(SFLDataFormat) : %d \n",count);
// printf("AudioRecord : nSamples : %d \n",nSamples);
// printf("AudioRecord : buffer: %x : ", buffer);
if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
if ( fwrite(buffer, sizeof(SFLDataFormat), nSamples, fp) != nSamples)
_debug("AudioRecord: Could not record data!\n");
else {
// printf("Buffer : %x \n",*buffer);
fflush(fp);
// _debug("Flushing!\n");
}
_debug("AudioRecord::closeWavFile() \n");
if ( fclose( fp ) != 0)
_debug("AudioRecord::closeWavFile()::ERROR: can't close file ab \n");
fp = fopen(fileName_, "rb+");
if ( !fp ) {
_debug("AudioRecord::closeWavFile() : could not open WAV file rb+!\n");
return;
}
SINT32 bytes = byteCounter_ * channels_;
fseek(fp, 40, SEEK_SET); // jump to data length
if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 40\n");
fwrite(&bytes, sizeof(SINT32), 1, fp);
if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't write bytes for data length \n");
printf("AudioRecord::closeWavFile : data bytes: %i \n",(int)bytes);
bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header
fseek(fp, 4, SEEK_SET); // jump to file size
if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 4\n");
fwrite(&bytes, 4, 1, fp);
if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 4\n");
printf("AudioRecord::closeWavFile : bytes : %i \n",(int)bytes);
if ( fclose( fp ) != 0)
_debug("AudioRecord::closeWavFile()::ERROR: can't close file\n");
// i = fclose(fp);
// printf("AudioRecord::closeWavFile : indicator i : %i \n",i);
}
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
byteCounter_ += (unsigned long)(nSamples*sizeof(SFLDataFormat));
if (recordingEnabled_) {
if (fp == 0){
_debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
return;
}
// int size = nSamples * (sizeof(SFLDataFormat));
// int size = sizeof(buffer);
// int count = sizeof(buffer) / sizeof(SFLDataFormat);
// printf("AudioRecord : sizeof(buffer) : %d \n",size);
// printf("AudioRecord : sizeof(buffer) / sizeof(SFLDataFormat) : %d \n",count);
// printf("AudioRecord : nSamples : %d \n",nSamples);
// printf("AudioRecord : buffer: %x : ", buffer);
if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
if ( fwrite(buffer, sizeof(SFLDataFormat), nSamples, fp) != nSamples)
_debug("AudioRecord: Could not record data! \n");
else {
// printf("Buffer : %x \n",*buffer);
fflush(fp);
// _debug("Flushing!\n");
byteCounter_ += (unsigned long)(nSamples*sizeof(SFLDataFormat));
}
}
}
return;
}
......@@ -196,22 +311,23 @@ void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
void AudioRecord::recData(SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2) {
if (fp == 0){
_debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
return;
}
if (recordingEnabled_) {
mixBuffer_ = new SFLDataFormat[nSamples_1];
if (fp == 0){
_debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
return;
}