Commit 7d458ece authored by Emmanuel Milou's avatar Emmanuel Milou

Merge branch 'recording'

parents 86d09ae8 8a3b73d2
......@@ -135,6 +135,8 @@ sflphone_hung_up( call_t * c)
#if GTK_CHECK_VERSION(2,10,0)
status_tray_icon_blink( FALSE );
#endif
statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
}
/** Internal to actions: Fill account list */
......@@ -449,6 +451,10 @@ process_dialing(call_t * c, guint keyval, gchar * key)
dbus_start_tone( FALSE , 0 );
//dbus_play_dtmf( key );
}
g_print("process_dialing : keyval : %i \n",keyval);
g_print("process_dialing : key : %s \n",key);
switch (keyval)
{
case 65293: /* ENTER */
......@@ -462,9 +468,10 @@ process_dialing(call_t * c, guint keyval, gchar * key)
{ /* Brackets mandatory because of local vars */
gchar * before = c->to;
if(strlen(c->to) >= 1){
c->to = g_strndup(c->to, strlen(c->to) -1);
g_free(before);
g_print("TO: %s\n", c->to);
g_print("TO: backspace %s\n", c->to);
if(c->state == CALL_STATE_DIALING)
{
......@@ -487,14 +494,16 @@ process_dialing(call_t * c, guint keyval, gchar * key)
case 65509: /* CAPS */
break;
default:
if (keyval < 255 || (keyval >65453 && keyval < 65466))
// if (keyval < 255 || (keyval >65453 && keyval < 65466))
if (keyval < 127)
{
if(c->state != CALL_STATE_TRANSFERT)
if(c->state != CALL_STATE_TRANSFERT)
dbus_play_dtmf( key );
gchar * before = c->to;
c->to = g_strconcat(c->to, key, NULL);
g_free(before);
g_print("TO: %s\n", c->to);
g_print("TO:default %s\n", c->to);
if(c->state == CALL_STATE_DIALING)
{
......@@ -512,6 +521,9 @@ process_dialing(call_t * c, guint keyval, gchar * key)
call_t *
sflphone_new_call()
{
sflphone_on_hold();
// Play a tone when creating a new call
if( call_list_get_size(current_calls) == 0 )
dbus_start_tone( TRUE , ( voice_mails > 0 )? TONE_WITH_MESSAGE : TONE_WITHOUT_MESSAGE) ;
......@@ -539,7 +551,7 @@ sflphone_new_call()
void
sflphone_keypad( guint keyval, gchar * key)
{
call_t * c = call_get_selected(current_calls);
if(c)
{
......@@ -548,6 +560,7 @@ sflphone_keypad( guint keyval, gchar * key)
case CALL_STATE_DIALING: // Currently dialing => edit number
process_dialing(c, keyval, key);
break;
case CALL_STATE_RECORD:
case CALL_STATE_CURRENT:
switch (keyval)
{
......@@ -681,7 +694,17 @@ sflphone_place_call ( call_t * c )
else
{
account_t * current = account_list_get_current();
account_t * current;
if(c->accountID != 0)
current = account_list_get_by_id(c->accountID);
else
current = account_list_get_current();
// printf("sflphone_place_call :: c->accountID : %i \n",c->accountID);
// account_t * current = c->accountID;
if( current )
{
if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0)
......@@ -724,6 +747,31 @@ sflphone_place_call ( call_t * c )
}
void
sflphone_display_selected_codec (const gchar* codecName)
{
call_t * selectedCall = call_get_selected(current_calls);
gchar* msg;
account_t* acc;
if(selectedCall->accountID != NULL){
acc = account_list_get_by_id(selectedCall->accountID);
msg = g_markup_printf_escaped(_("%s account- %s %s") ,
(gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE),
(gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
codecName);
statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
g_free(msg);
}
}
gchar*
sflphone_get_current_codec_name()
{
call_t * selectedCall = call_get_selected(current_calls);
return dbus_get_current_codec_name(selectedCall);
}
void
sflphone_rec_call()
{
......@@ -745,6 +793,9 @@ sflphone_rec_call()
}
update_call_tree(current_calls,selectedCall);
update_menus();
// gchar* codname = sflphone_get_current_codec_name();
// printf("sflphone_get_current_codec_name: %s \n",codname);
}
/* Internal to action - set the __CURRENT_ACCOUNT variable */
......@@ -807,3 +858,4 @@ sflphone_fill_codec_list()
exit(0);
}
}
......@@ -168,4 +168,8 @@ void sflphone_fill_codec_list();
void sflphone_record (call_t *c);
void sflphone_rec_call (void);
gchar* sflphone_get_current_codec_name();
void sflphone_display_selected_codec (const gchar* codecName);
#endif
......@@ -529,6 +529,44 @@ org_sflphone_SFLphone_CallManager_get_current_call_id_async (DBusGProxy *proxy,
stuff->userdata = userdata;
return dbus_g_proxy_begin_call (proxy, "getCurrentCallID", org_sflphone_SFLphone_CallManager_get_current_call_id_async_callback, stuff, g_free, G_TYPE_INVALID);
}
static
#ifdef G_HAVE_INLINE
inline
#endif
gboolean
org_sflphone_SFLphone_CallManager_get_current_codec_name (DBusGProxy *proxy, const char * IN_callID, char ** OUT_codecName, GError **error)
{
return dbus_g_proxy_call (proxy, "getCurrentCodecName", error, G_TYPE_STRING, IN_callID, G_TYPE_INVALID, G_TYPE_STRING, OUT_codecName, G_TYPE_INVALID);
}
typedef void (*org_sflphone_SFLphone_CallManager_get_current_codec_name_reply) (DBusGProxy *proxy, char * OUT_codecName, GError *error, gpointer userdata);
static void
org_sflphone_SFLphone_CallManager_get_current_codec_name_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
{
DBusGAsyncData *data = (DBusGAsyncData*) user_data;
GError *error = NULL;
char * OUT_codecName;
dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_codecName, G_TYPE_INVALID);
(*(org_sflphone_SFLphone_CallManager_get_current_codec_name_reply)data->cb) (proxy, OUT_codecName, error, data->userdata);
return;
}
static
#ifdef G_HAVE_INLINE
inline
#endif
DBusGProxyCall*
org_sflphone_SFLphone_CallManager_get_current_codec_name_async (DBusGProxy *proxy, const char * IN_callID, org_sflphone_SFLphone_CallManager_get_current_codec_name_reply callback, gpointer userdata)
{
DBusGAsyncData *stuff;
stuff = g_new (DBusGAsyncData, 1);
stuff->cb = G_CALLBACK (callback);
stuff->userdata = userdata;
return dbus_g_proxy_begin_call (proxy, "getCurrentCodecName", org_sflphone_SFLphone_CallManager_get_current_codec_name_async_callback, stuff, g_free, G_TYPE_STRING, IN_callID, G_TYPE_INVALID);
}
#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_sflphone_SFLphone_CallManager */
G_END_DECLS
......@@ -37,7 +37,7 @@ GtkToolItem * hangupButton;
GtkToolItem * holdButton;
GtkToolItem * transfertButton;
GtkToolItem * unholdButton;
GtkToolItem * historyButton;
// GtkToolItem * historyButton;
GtkToolItem * mailboxButton;
GtkToolItem * recButton;
guint transfertButtonConnId; //The button toggled signal connection ID
......@@ -395,6 +395,7 @@ void row_activated(GtkTreeView *tree_view UNUSED,
break;
}
}
// if history
else
{
newCall = g_new0( call_t, 1 );
......@@ -405,7 +406,8 @@ void row_activated(GtkTreeView *tree_view UNUSED,
g_sprintf(newCall->callID, "%d", rand());
newCall->_start = 0;
newCall->_stop = 0;
printf("call : account : %s \n", selectedCall->accountID);
newCall->accountID = selectedCall->accountID;
printf("call : from : %s to %s\n", newCall->from, newCall->to);
call_list_add(current_calls, newCall);
update_call_tree_add(current_calls, newCall);
......@@ -689,6 +691,7 @@ update_call_tree (calltab_t* tab, call_t * c)
}
else
{
g_print("Stuff to be printed %s %s \n",call_get_number(c),call_get_name(c));
description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>",
call_get_number(c),
call_get_name(c));
......
......@@ -60,6 +60,15 @@ incoming_call_cb (DBusGProxy *proxy UNUSED,
sflphone_incoming_call (c);
}
static void
curent_selected_codec (DBusGProxy *proxy UNUSED,
const gchar* callID,
const gchar* codecName,
void * foo UNUSED )
{
g_print ("Codec decided! %s\n",codecName);
sflphone_display_selected_codec (codecName);
}
static void
volume_changed_cb (DBusGProxy *proxy UNUSED,
......@@ -232,6 +241,14 @@ dbus_connect ()
dbus_g_proxy_connect_signal (callManagerProxy,
"incomingCall", G_CALLBACK(incoming_call_cb), NULL, NULL);
/* Current codec */
dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING_STRING_STRING,
G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (callManagerProxy,
"currentSelectedCodec", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (callManagerProxy,
"currentSelectedCodec", G_CALLBACK(curent_selected_codec), NULL, NULL);
/* Register a marshaller for STRING,STRING */
dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING_STRING,
G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
......@@ -649,6 +666,30 @@ dbus_codec_details( int payload )
return array;
}
gchar*
dbus_get_current_codec_name(const call_t * c)
{
printf("dbus_get_current_codec_name : CallID : %s \n", c->callID);
gchar* codecName;
GError* error = NULL;
org_sflphone_SFLphone_CallManager_get_current_codec_name (
callManagerProxy,
c->callID,
&codecName,
&error);
if(error)
{
g_error_free(error);
}
printf("dbus_get_current_codec_name : codecName : %s \n", codecName);
return codecName;
}
gchar**
......
......@@ -177,6 +177,12 @@ gchar** dbus_get_active_codec_list( void );
*/
void dbus_set_active_codec_list( const gchar** list );
/**
* CallManager - return the codec name
* @param call_t* current call
*/
gchar* dbus_get_current_codec_name(const call_t * c);
/**
* ConfigurationManager - Get the list of available input audio plugins
* @return gchar** The list of plugins
......
......@@ -104,7 +104,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), 260, 320);
gtk_window_set_default_size (GTK_WINDOW (window), 258, 320);
gtk_window_set_default_icon_from_file (ICONS_DIR "/sflphone.png",
NULL);
gtk_window_set_position( GTK_WINDOW( window ) , GTK_WIN_POS_MOUSE);
......
......@@ -38,6 +38,7 @@ GtkWidget * newCallMenu;
GtkWidget * holdMenu;
GtkWidget * copyMenu;
GtkWidget * pasteMenu;
GtkWidget * recordMenu;
guint holdConnId; //The hold_menu signal connection ID
......@@ -55,6 +56,7 @@ void update_menus()
gtk_widget_set_sensitive( GTK_WIDGET(hangUpMenu), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(newCallMenu),FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(holdMenu), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(recordMenu), FALSE);
gtk_widget_set_sensitive( GTK_WIDGET(copyMenu), FALSE);
call_t * selectedCall = call_get_selected(active_calltree);
......@@ -83,20 +85,17 @@ void update_menus()
gtk_widget_set_sensitive( GTK_WIDGET(newCallMenu),TRUE);
break;
case CALL_STATE_CURRENT:
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);
gtk_widget_set_sensitive( GTK_WIDGET(recordMenu), TRUE);
gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM ( holdMenu ), gtk_image_new_from_file( ICONS_DIR "/icon_hold.svg"));
break;
case CALL_STATE_BUSY:
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;
......@@ -225,6 +224,12 @@ call_hang_up ( void * foo UNUSED)
sflphone_hang_up();
}
static void
call_record ( void * foo UNUSED)
{
sflphone_rec_call();
}
static void
call_wizard ( void * foo UNUSED)
{
......@@ -318,6 +323,16 @@ create_call_menu()
NULL);
gtk_widget_show (menu_items);
image = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD);
recordMenu = gtk_image_menu_item_new_with_mnemonic(_("_Record"));
gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM ( recordMenu ), image );
gtk_menu_shell_append (GTK_MENU_SHELL (menu), recordMenu);
gtk_widget_set_sensitive( GTK_WIDGET(recordMenu), FALSE);
g_signal_connect_swapped (G_OBJECT (recordMenu), "activate",
G_CALLBACK (call_record),
NULL);
gtk_widget_show (recordMenu);
// Separator
menu_items = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);
......@@ -682,7 +697,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
{
// TODO update the selection to make sure the call under the mouse is the call selected
gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE;
gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE, record = FALSE;
gboolean accounts = FALSE;
call_t * selectedCall = call_get_selected(current_calls);
......@@ -707,9 +722,11 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
hangup = TRUE;
accounts = TRUE;
break;
case CALL_STATE_RECORD:
case CALL_STATE_CURRENT:
hangup = TRUE;
hold = TRUE;
record = TRUE;
break;
case CALL_STATE_BUSY:
case CALL_STATE_FAILURE:
......@@ -791,6 +808,18 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
gtk_widget_show (menu_items);
}
if(record)
{
menu_items = gtk_image_menu_item_new_with_mnemonic(_("_Record"));
image = gtk_tool_button_new_from_stock (GTK_STOCK_MEDIA_RECORD);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_items), image);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);
g_signal_connect (G_OBJECT (menu_items), "activate",
G_CALLBACK (call_record),
NULL);
gtk_widget_show (menu_items);
}
if(accounts)
{
menu_items = gtk_separator_menu_item_new ();
......
......@@ -205,8 +205,10 @@ notify_no_registered_accounts( )
gchar* body="";
notify_init("sflphone");
body = g_markup_printf_escaped(_("You have no registered accounts"));
title = g_markup_printf_escaped(_("Error"));
pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/sflphone.png", NULL);
......@@ -223,9 +225,10 @@ notify_no_registered_accounts( )
notify_notification_set_timeout( notification , NOTIFY_EXPIRES_DEFAULT );
notify_notification_add_action( notification , "setup" , _("Setup Accounts") , (NotifyActionCallback) setup_accounts_cb , NULL , NULL );
if (!notify_notification_show (notification, NULL)) {
g_print("notify(), failed to send notification\n");
}
if (!notify_notification_show (notification, NULL)) {
g_print("notify(), failed to send notification\n");
}
}
void
......
......@@ -116,6 +116,7 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) : time(new ost::Time()), _
_sym(sym), micData(NULL), micDataConverted(NULL), micDataEncoded(NULL), spkrDataDecoded(NULL), spkrDataConverted(NULL),
converter(NULL), _layerSampleRate(),_codecSampleRate(), _layerFrameSize(), _audiocodec(NULL)
{
setCancel(cancelDefault);
// AudioRtpRTX should be close if we change sample rate
// TODO: Change bind address according to user settings.
......@@ -150,6 +151,7 @@ AudioRtpRTX::~AudioRtpRTX () {
delete _session; _session = NULL;
}
delete [] micData; micData = NULL;
delete [] micDataConverted; micDataConverted = NULL;
delete [] micDataEncoded; micDataEncoded = NULL;
......@@ -163,6 +165,8 @@ AudioRtpRTX::~AudioRtpRTX () {
}
void
AudioRtpRTX::initBuffers()
{
......@@ -248,6 +252,7 @@ AudioRtpRTX::initAudioRtpSession (void)
_debugException("! ARTP Failure: initialisation failed");
throw;
}
}
void
......@@ -312,14 +317,18 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
{
if (_ca == 0) { return; }
//try {
AudioLayer* audiolayer = Manager::instance().getAudioDriver();
if (!audiolayer) { return; }
const ost::AppDataUnit* adu = NULL;
// Get audio data stream
// printf("AudioRtpRTX::receiveSessionForSpkr() %i \n",_session->getFirstTimestamp());
if (!_sym) {
adu = _sessionRecv->getData(_sessionRecv->getFirstTimestamp());
} else {
......@@ -330,10 +339,14 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
return;
}
//int payload = adu->getType(); // codec type
unsigned char* spkrData = (unsigned char*)adu->getData(); // data in char
unsigned int size = adu->getSize(); // size in char
// printf("AudioRtpRTX::receiveSessionForSpkr() Size of data from %i \n",size);
// Decode data with relevant codec
unsigned int max = (unsigned int)(_codecSampleRate * _layerFrameSize / 1000);
......@@ -359,6 +372,7 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
// Do sample rate conversion
int nb_sample_down = nbSample;
nbSample = reSampleData(_codecSampleRate , nb_sample_down, UP_SAMPLING);
#ifdef DATAFORMAT_IS_FLOAT
#else
#endif
......@@ -403,17 +417,23 @@ AudioRtpRTX::reSampleData(int sampleRate_codec, int nbSamples, int status)
return 0;
}
void
AudioRtpRTX::run () {
//mic, we receive from soundcard in stereo, and we send encoded
//encoding before sending
AudioLayer *audiolayer = Manager::instance().getAudioDriver();
_layerFrameSize = audiolayer->getFrameSize(); // en ms
_layerSampleRate = audiolayer->getSampleRate();
initBuffers();
int step;
//try {
//mic, we receive from soundcard in stereo, and we send encoded
//encoding before sending
AudioLayer *audiolayer = Manager::instance().getAudioDriver();
_layerFrameSize = audiolayer->getFrameSize(); // en ms
_layerSampleRate = audiolayer->getSampleRate();
initBuffers();
int step;
int sessionWaiting;
//try {
// Init the session
initAudioRtpSession();
step = (int) (_layerFrameSize * _codecSampleRate / 1000);
......@@ -433,27 +453,58 @@ AudioRtpRTX::run () {
audiolayer->startStream();
_start.post();
_debug("- ARTP Action: Start\n");
_debug("- ARTP Action: Start call %s\n",_ca->getCallId().c_str());
while (!testCancel()) {
////////////////////////////
// Send session
////////////////////////////
sendSessionFromMic(timestamp);
timestamp += step;
////////////////////////////
// Recv session
////////////////////////////
receiveSessionForSpkr(countTime);
// Let's wait for the next transmit cycle
// printf("AudioRtpRTX::run() _session->getFirstTimestamp() %i \n",_session->getFirstTimestamp());
// printf("AudioRtpRTX::run() _session->isWaiting() %i \n",_session->isWaiting());
/////////////////////
////////////////////////////
// Send session
////////////////////////////
sessionWaiting = _session->isWaiting();
sendSessionFromMic(timestamp);
timestamp += step;
////////////////////////////
// Recv session
////////////////////////////
receiveSessionForSpkr(countTime);
// Let's wait for the next transmit cycle
if(sessionWaiting == 1){
// _debug("Record TWO buffer \n");
_ca->recAudio.recData(spkrDataConverted,micData,_nSamplesSpkr,_nSamplesMic);
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
}
else {
// _debug("Record ONE buffer \n");
_ca->recAudio.recData(micData,_nSamplesMic);
}
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
}
// _debug("stop stream for audiortp loop\n");
audiolayer->stopStream();
_debug("- ARTP Action: Stop\n");
_debug("- ARTP Action: Stop call %s\n",_ca->getCallId().c_str());
//} catch(std::exception &e) {
//_start.post();
//_debug("! ARTP: Stop %s\n", e.what());
//throw;
//} catch(...) {
//_start.post();
//_debugException("* ARTP Action: Stop");
//throw;
//}
}
......