diff --git a/src/audio_call.c b/src/audio_call.c index e3dca2e..992255b 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -20,11 +20,17 @@ #include #include #include +#include #define _cbend pthread_exit(NULL) #define AUDIO_FRAME_SIZE (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000) +#define MAX_CALLS 10 + +#define _True 1 +#define _False 0 + typedef struct _DeviceIx { ALCdevice *dhndl; /* Handle of device selected/opened */ @@ -35,29 +41,34 @@ typedef struct _DeviceIx { int index; /* Current index */ } DeviceIx; -struct _ASettings { +typedef struct _Call { + pthread_t ttid; /* Transmission thread id */ + _Bool ttas; /* Transmission thread active status (0 - stopped, 1- running) */ +} Call; +struct _ASettings { DeviceIx device[2]; AudioError errors; ToxAv *av; - - pthread_t ttid; /* Transmission thread id */ - int ttas; /* Transmission thread active status (0 - stopped, 1- running) */ + + ToxAvCodecSettings cs; + + Call calls[MAX_CALLS]; } ASettins; -void callback_recv_invite ( void *arg ); -void callback_recv_ringing ( void *arg ); -void callback_recv_starting ( void *arg ); -void callback_recv_ending ( void *arg ); -void callback_recv_error ( void *arg ); -void callback_call_started ( void *arg ); -void callback_call_canceled ( void *arg ); -void callback_call_rejected ( void *arg ); -void callback_call_ended ( void *arg ); -void callback_requ_timeout ( void *arg ); -void callback_peer_timeout ( void *arg ); +void callback_recv_invite ( int32_t call_index, void *arg ); +void callback_recv_ringing ( int32_t call_index, void *arg ); +void callback_recv_starting ( int32_t call_index, void *arg ); +void callback_recv_ending ( int32_t call_index, void *arg ); +void callback_recv_error ( int32_t call_index, void *arg ); +void callback_call_started ( int32_t call_index, void *arg ); +void callback_call_canceled ( int32_t call_index, void *arg ); +void callback_call_rejected ( int32_t call_index, void *arg ); +void callback_call_ended ( int32_t call_index, void *arg ); +void callback_requ_timeout ( int32_t call_index, void *arg ); +void callback_peer_timeout ( int32_t call_index, void *arg ); static void print_err (ToxWindow *self, uint8_t *error_str) @@ -65,21 +76,6 @@ static void print_err (ToxWindow *self, uint8_t *error_str) line_info_add(self, NULL, NULL, NULL, error_str, SYS_MSG, 0, 0); } -int device_set(ToxWindow *self, _Devices type, long int selection) -{ - uint8_t error_str[MAX_STR_SIZE]; - uint8_t *s_type = type == input ? "input" : "output"; - - if ( selection < 0 || selection >= ASettins.device[type].size ) { - snprintf(error_str, sizeof(error_str), "Cannot set audio %s device: Invalid index", s_type); - line_info_add(self, NULL, NULL, NULL, error_str, SYS_MSG, 0, 0); - return -1; - } - - ASettins.device[type].index = selection; - return 0; -} - /* Opens device under current index */ int device_open (ToxWindow *self, _Devices type) @@ -173,9 +169,10 @@ int device_open (ToxWindow *self, _Devices type) int device_close (ToxWindow *self, _Devices type) { - uint8_t *device = NULL; - + /* Only close if device opened */ if ( ASettins.device[type].dhndl ) { + uint8_t *device = NULL; + if (type == input) { alcCaptureCloseDevice(ASettins.device[type].dhndl); device = "input"; @@ -190,19 +187,53 @@ int device_close (ToxWindow *self, _Devices type) } ASettins.device[type].index = ASettins.device[type].dix; - } - if ( self && device ) { - uint8_t msg[MAX_STR_SIZE]; - snprintf(msg, sizeof(msg), "Closed %s device", device); - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + if ( device == NULL ) { + return -1; + } + + if ( self ) { + uint8_t msg[MAX_STR_SIZE]; + snprintf(msg, sizeof(msg), "Closed %s device", device); + line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + } } + + return 0; } -ToxAv *init_audio(ToxWindow *self, Tox *tox) + +int device_set(ToxWindow *self, _Devices type, long int selection) { + uint8_t str[MAX_STR_SIZE]; + uint8_t *s_type = type == input ? "input" : "output"; + + if ( selection < 0 || selection >= ASettins.device[type].size ) { + snprintf(str, sizeof(str), "Cannot set audio %s device: Invalid index: %d", s_type); + line_info_add(self, NULL, NULL, NULL, str, SYS_MSG, 0, 0); + return -1; + } + + ASettins.device[type].index = selection; + + if ( device_open(self, type) != 0 ) { + snprintf(str, sizeof(str), "Cannot open audio %s device index: %d", s_type); + line_info_add(self, NULL, NULL, NULL, str, SYS_MSG, 0, 0); + return -1; + } + + return 0; +} + + +ToxAv *init_audio(ToxWindow *self, Tox *tox) +{ + ASettins.cs = av_DefaultSettings; + ASettins.cs.video_height = ASettins.cs.video_width = 0; + ASettins.errors = NoError; - ASettins.ttas = 0; /* Not running */ + + memset(ASettins.calls, 0, sizeof(Call) * 10); /* Capture devices */ const char *stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); @@ -246,10 +277,7 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox) } else { /* Streaming stuff from core */ - ToxAvCodecSettings cs = av_DefaultSettings; - cs.video_height = cs.video_width = 0; - - ASettins.av = toxav_new(tox, &cs); + ASettins.av = toxav_new(tox, MAX_CALLS); if ( !ASettins.av ) { ASettins.errors |= ErrorStartingCoreAudio; @@ -276,10 +304,15 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox) void terminate_audio() { - stop_transmission(); + int i; + for (i = 0; i < MAX_CALLS; i ++) + stop_transmission(i); if ( ASettins.av ) toxav_kill(ASettins.av); + + device_close(NULL, input); + device_close(NULL, output); } int errors() @@ -294,18 +327,21 @@ int errors() */ void *transmission(void *arg) -{ - (void)arg; /* Avoid warning */ +{ + ToxWindow* self = arg; + int32_t call_index = self->call_index; /* Missing audio support */ if ( !ASettins.av ) _cbend; - ASettins.ttas = 1; + Call* this_call = &ASettins.calls[call_index]; + + this_call->ttas = _True; /* Prepare devices */ alcCaptureStart(ASettins.device[input].dhndl); alcMakeContextCurrent(ASettins.device[output].ctx); - + int32_t dec_frame_len; int16_t frame[4096]; int32_t sample = 0; @@ -313,57 +349,57 @@ void *transmission(void *arg) int32_t ready; int32_t openal_buffers = 5; uint32_t source, *buffers; - + uint8_t encoded_payload[RTP_PAYLOAD_SIZE]; + const int32_t frame_size = AUDIO_FRAME_SIZE; + /* Prepare buffers */ buffers = calloc(sizeof(uint32_t), openal_buffers); alGenBuffers(openal_buffers, buffers); alGenSources((uint32_t)1, &source); alSourcei(source, AL_LOOPING, AL_FALSE); - - uint16_t zeros[AUDIO_FRAME_SIZE]; - memset(zeros, 0, AUDIO_FRAME_SIZE); - int16_t PCM[AUDIO_FRAME_SIZE]; + uint16_t zeros[frame_size]; + memset(zeros, 0, frame_size); + int16_t PCM[frame_size]; int32_t i = 0; for (; i < openal_buffers; ++i) { - alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, AUDIO_FRAME_SIZE, 48000); + alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000); } alSourceQueueBuffers(source, openal_buffers, buffers); alSourcePlay(source); - + if (alGetError() != AL_NO_ERROR) { /* Print something? */ /*fprintf(stderr, "Error starting audio\n");*/ - goto cleanup; + +// goto cleanup; } /* Start transmission */ - while (ASettins.ttas) { + while (this_call->ttas) { alcGetIntegerv(ASettins.device[input].dhndl, ALC_CAPTURE_SAMPLES, (int32_t) sizeof(int32_t), &sample); /* RECORD AND SEND */ - if (sample >= AUDIO_FRAME_SIZE) { - alcCaptureSamples(ASettins.device[input].dhndl, frame, AUDIO_FRAME_SIZE); - - if (toxav_send_audio(ASettins.av, frame, AUDIO_FRAME_SIZE) < 0) - /*fprintf(stderr, "Could not encode or send audio packet\n")*/; - - } else usleep(1000); - - + if (sample >= frame_size) { + alcCaptureSamples(ASettins.device[input].dhndl, frame, frame_size); + + int32_t payload_size = toxav_prepare_audio_frame(ASettins.av, call_index, encoded_payload, RTP_PAYLOAD_SIZE, frame, frame_size); + if ( payload_size <= 0 || toxav_send_audio(ASettins.av, call_index, encoded_payload, payload_size) < 0 ) { + /*fprintf(stderr, "Could not encode audio packet\n");*/ + } + } /* PLAYBACK */ alGetSourcei(source, AL_BUFFERS_PROCESSED, &ready); - if (ready <= 0) - continue; + if (ready <= 0) continue; - dec_frame_len = toxav_recv_audio(ASettins.av, AUDIO_FRAME_SIZE, PCM); + dec_frame_len = toxav_recv_audio(ASettins.av, call_index, frame_size, PCM); /* Play the packet */ if (dec_frame_len > 0) { @@ -372,14 +408,14 @@ void *transmission(void *arg) int32_t error = alGetError(); if (error != AL_NO_ERROR) { - /*fprintf(stderr, "Error setting buffer %d\n", error);*/ + fprintf(stderr, "Error setting buffer %d\n", error); break; } alSourceQueueBuffers(source, 1, &buffer); if (alGetError() != AL_NO_ERROR) { - /*fprintf(stderr, "Error: could not buffer audio\n");*/ + fprintf(stderr, "Error: could not buffer audio\n"); break; } @@ -387,6 +423,9 @@ void *transmission(void *arg) if (ready != AL_PLAYING) alSourcePlay(source); } + else { + /* Error ignored */ + } usleep(1000); } @@ -395,40 +434,36 @@ cleanup: alDeleteSources(1, &source); alDeleteBuffers(openal_buffers, buffers); - + /* device_close(NULL, input); - device_close(NULL, output); + device_close(NULL, output);*/ _cbend; } int start_transmission(ToxWindow *self) { - if ( !ASettins.av ) return -1; - - if ( !toxav_capability_supported(ASettins.av, AudioDecoding) || - !toxav_capability_supported(ASettins.av, AudioEncoding) ) - return -1; - - /* Now open our devices */ - if ( -1 == device_open(self, input) ) - return -1; - - if ( -1 == device_open(self, output)) - return -1; - + if ( !ASettins.av || self->call_index == -1 ) return -1; + /* Don't provide support for video */ - toxav_prepare_transmission(ASettins.av, 0); + if ( 0 != toxav_prepare_transmission(ASettins.av, self->call_index, &ASettins.cs, 0) ) { + line_info_add(self, NULL, NULL, NULL, "Could not prepare transmission", SYS_MSG, 0, 0); + } + + if ( !toxav_capability_supported(ASettins.av, self->call_index, AudioDecoding) || + !toxav_capability_supported(ASettins.av, self->call_index, AudioEncoding) ) + return -1; - if ( 0 != pthread_create(&ASettins.ttid, NULL, transmission, NULL ) && - 0 != pthread_detach(ASettins.ttid) ) { + if ( 0 != pthread_create(&ASettins.calls[self->call_index].ttid, NULL, transmission, self ) && + 0 != pthread_detach(ASettins.calls[self->call_index].ttid) ) { return -1; } } -int stop_transmission() -{ - ASettins.ttas = 0; +int stop_transmission(int call_index) +{ + toxav_kill_transmission(ASettins.av, call_index); + ASettins.calls[call_index].ttas = _False; } /* * End of transmission @@ -442,63 +477,82 @@ int stop_transmission() * Callbacks */ -#define CB_BODY(Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\ -for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av); } while (0) +#define CB_BODY(call_idx, Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\ +for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av, call_idx); } while (0) -void callback_recv_invite ( void *arg ) +void callback_recv_invite ( int32_t call_index, void* arg ) { - CB_BODY(arg, onInvite); + CB_BODY(call_index, arg, onInvite); } -void callback_recv_ringing ( void *arg ) +void callback_recv_ringing ( int32_t call_index, void* arg ) { - CB_BODY(arg, onRinging); + CB_BODY(call_index, arg, onRinging); } -void callback_recv_starting ( void *arg ) +void callback_recv_starting ( int32_t call_index, void* arg ) { - CB_BODY(arg, onStarting); + ToxWindow* windows = arg; + int i; + for (i = 0; i < MAX_WINDOWS_NUM; ++i) + if (windows[i].onStarting != NULL && windows[i].call_index == call_index) { + windows[i].onStarting(&windows[i], ASettins.av, call_index); + if ( 0 != start_transmission(&windows[i]) ) {/* YEAH! */ + line_info_add(&windows[i], NULL, NULL, NULL, "Error starting transmission!", SYS_MSG, 0, 0); + return; + } + } + } -void callback_recv_ending ( void *arg ) +void callback_recv_ending ( int32_t call_index, void* arg ) { - CB_BODY(arg, onEnding); - stop_transmission(); + CB_BODY(call_index, arg, onEnding); + stop_transmission(call_index); } -void callback_recv_error ( void *arg ) +void callback_recv_error ( int32_t call_index, void* arg ) { - CB_BODY(arg, onError); + CB_BODY(call_index, arg, onError); } -void callback_call_started ( void *arg ) -{ - CB_BODY(arg, onStart); +void callback_call_started ( int32_t call_index, void* arg ) +{ + ToxWindow* windows = arg; + int i; + for (i = 0; i < MAX_WINDOWS_NUM; ++i) + if (windows[i].onStart != NULL && windows[i].call_index == call_index) { + windows[i].onStart(&windows[i], ASettins.av, call_index); + if ( 0 != start_transmission(&windows[i]) ) {/* YEAH! */ + line_info_add(&windows[i], NULL, NULL, NULL, "Error starting transmission!", SYS_MSG, 0, 0); + return; + } + } } -void callback_call_canceled ( void *arg ) +void callback_call_canceled ( int32_t call_index, void* arg ) { - CB_BODY(arg, onCancel); + CB_BODY(call_index, arg, onCancel); /* In case call is active */ - stop_transmission(); + stop_transmission(call_index); } -void callback_call_rejected ( void *arg ) +void callback_call_rejected ( int32_t call_index, void* arg ) { - CB_BODY(arg, onReject); + CB_BODY(call_index, arg, onReject); } -void callback_call_ended ( void *arg ) +void callback_call_ended ( int32_t call_index, void* arg ) { - CB_BODY(arg, onEnd); - stop_transmission(); + CB_BODY(call_index, arg, onEnd); + stop_transmission(call_index); } -void callback_requ_timeout ( void *arg ) +void callback_requ_timeout ( int32_t call_index, void* arg ) { - CB_BODY(arg, onRequestTimeout); + CB_BODY(call_index, arg, onRequestTimeout); } -void callback_peer_timeout ( void *arg ) +void callback_peer_timeout ( int32_t call_index, void* arg ) { - CB_BODY(arg, onPeerTimeout); - stop_transmission(); + CB_BODY(call_index, arg, onPeerTimeout); + stop_transmission(call_index); /* Call is stopped manually since there might be some other * actions that one can possibly take on timeout */ - toxav_stop_call(ASettins.av); + toxav_stop_call(ASettins.av, call_index); } /* * End of Callbacks @@ -523,7 +577,7 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA goto on_error; } - ToxAvError error = toxav_call(ASettins.av, self->num, TypeAudio, 30); + ToxAvError error = toxav_call(ASettins.av, &self->call_index, self->num, TypeAudio, 30); if ( error != ErrorNone ) { if ( error == ErrorAlreadyInCall ) error_str = "Already in a call!"; @@ -532,8 +586,8 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA goto on_error; } - error_str = "Calling..."; - line_info_add(self, NULL, NULL, NULL, error_str, SYS_MSG, 0, 0); + snprintf(msg, sizeof(msg), "Calling... idx: %d", self->call_index); + line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); return; on_error: @@ -555,7 +609,7 @@ void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ goto on_error; } - ToxAvError error = toxav_answer(ASettins.av, TypeAudio); + ToxAvError error = toxav_answer(ASettins.av, self->call_index, TypeAudio); if ( error != ErrorNone ) { if ( error == ErrorInvalidState ) error_str = "Cannot answer in invalid state!"; @@ -586,7 +640,7 @@ void cmd_reject(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ goto on_error; } - ToxAvError error = toxav_reject(ASettins.av, "Why not?"); + ToxAvError error = toxav_reject(ASettins.av, self->call_index, "Why not?"); if ( error != ErrorNone ) { if ( error == ErrorInvalidState ) error_str = "Cannot reject in invalid state!"; @@ -617,7 +671,7 @@ void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ goto on_error; } - ToxAvError error = toxav_hangup(ASettins.av); + ToxAvError error = toxav_hangup(ASettins.av, self->call_index); if ( error != ErrorNone ) { if ( error == ErrorInvalidState ) error_str = "Cannot hangup in invalid state!"; @@ -646,8 +700,8 @@ void cmd_cancel(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ goto on_error; } - ToxAvError error = toxav_cancel(ASettins.av, self->num, - "Only those who appreciate small things know the beauty of life"); + ToxAvError error = toxav_cancel(ASettins.av, self->call_index, self->num, + "Only those who appreciate small things know the beauty that is life"); if ( error != ErrorNone ) { if ( error == ErrorNoCall ) error_str = "No call!"; @@ -715,7 +769,7 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char ( goto on_error; } - if ( ASettins.ttas ) { /* Transmission is active */ + if ( ASettins.calls[self->call_index].ttas ) { /* Transmission is active */ error_str = "Cannot change device while active transmission"; goto on_error; } @@ -742,12 +796,22 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char ( error_str = "Invalid input"; goto on_error; } - + + if ( device_close(self, type) != 0 ) { + error_str = "Could not close device!"; + goto on_error; + } + if ( device_set(self, type, selection ) == 0) { - snprintf(msg, sizeof(msg), "Selected: %s", ASettins.device[type].devices[selection]); + /*snprintf(msg, sizeof(msg), "Selected: %s", ASettins.device[type].devices[selection]); + line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);*/ + } + + if ( device_open(self, type) == 0 ) { + snprintf(msg, sizeof(msg), "Now using: %s", ASettins.device[type].devices[selection]); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); } - + return; on_error: print_err (self, error_str); diff --git a/src/chat.c b/src/chat.c index 9cb3c00..a83a601 100644 --- a/src/chat.c +++ b/src/chat.c @@ -382,125 +382,98 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui /* Av Stuff */ #ifdef _SUPPORT_AUDIO -void chat_onInvite (ToxWindow *self, ToxAv *av) +void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Incoming audio call!\nType: \"/answer\" or \"/reject\""; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + /* call_index is set here and reset on call end */ + + self->call_index = call_index; + + line_info_add(self, NULL, NULL, NULL, "Incoming audio call!\nType: \"/answer\" or \"/reject\"", SYS_MSG, 0, 0); alert_window(self, WINDOW_ALERT_0, true); } -void chat_onRinging (ToxWindow *self, ToxAv *av) +void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if ( self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Ringing...\n\"cancel\" ?"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Ringing...\n\"cancel\" ?", SYS_MSG, 0, 0); } -void chat_onStarting (ToxWindow *self, ToxAv *av) +void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if ( self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg; - - if ( 0 != start_transmission(self) ) {/* YEAH! */ - msg = "Error starting transmission!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); - return; - } - - msg = "Call started!\nType: \"/hangup\" to end it."; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Call started!\nType: \"/hangup\" to end it.", SYS_MSG, 0, 0); } -void chat_onEnding (ToxWindow *self, ToxAv *av) +void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Call ended!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); - - toxav_kill_transmission(av); + line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0); } -void chat_onError (ToxWindow *self, ToxAv *av) +void chat_onError (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Error!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Error!", SYS_MSG, 0, 0); } -void chat_onStart (ToxWindow *self, ToxAv *av) +void chat_onStart (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if ( self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg; - - if ( 0 != start_transmission(self) ) {/* YEAH! */ - msg = "Error starting transmission!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); - return; - } - - msg = "Call started!\nType: \"/hangup\" to end it."; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Call started!\nType: \"/hangup\" to end it.", SYS_MSG, 0, 0); } -void chat_onCancel (ToxWindow *self, ToxAv *av) +void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if ( self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Call canceled!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Call canceled!", SYS_MSG, 0, 0); } -void chat_onReject (ToxWindow *self, ToxAv *av) +void chat_onReject (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Rejected!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Rejected!", SYS_MSG, 0, 0); } -void chat_onEnd (ToxWindow *self, ToxAv *av) +void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - toxav_kill_transmission(av); - - uint8_t *msg = "Call ended!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0); } -void chat_onRequestTimeout (ToxWindow *self, ToxAv *av) +void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "No answer!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "No answer!", SYS_MSG, 0, 0); } -void chat_onPeerTimeout (ToxWindow *self, ToxAv *av) +void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index) { - if (self->num != toxav_get_peer_id(av, 0)) + if (self->call_index != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - uint8_t *msg = "Peer disconnected; call ended!"; - line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); + line_info_add(self, NULL, NULL, NULL, "Peer disconnected; call ended!", SYS_MSG, 0, 0); } #endif /* _SUPPORT_AUDIO */ @@ -932,6 +905,8 @@ ToxWindow new_chat(Tox *m, int32_t friendnum) ret.onEnd = &chat_onEnd; ret.onRequestTimeout = &chat_onRequestTimeout; ret.onPeerTimeout = &chat_onPeerTimeout; + + ret.call_index = -1; #endif /* _SUPPORT_AUDIO */ uint8_t name[TOX_MAX_NAME_LENGTH] = {'\0'}; diff --git a/src/friendlist.c b/src/friendlist.c index 656bf81..d8ca16d 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -558,9 +558,9 @@ void disable_chatwin(int32_t f_num) } #ifdef _SUPPORT_AUDIO -static void friendlist_onAv(ToxWindow *self, ToxAv *av) +static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index) { - int id = toxav_get_peer_id(av, 0); + int id = toxav_get_peer_id(av, call_index, 0); /*id++;*/ if ( id != ErrorInternal && id >= max_friends_index) @@ -622,6 +622,8 @@ ToxWindow new_friendlist(void) ret.onEnd = &friendlist_onAv; ret.onRequestTimeout = &friendlist_onAv; ret.onPeerTimeout = &friendlist_onAv; + + ret.call_index = -1; #endif /* _SUPPORT_AUDIO */ strcpy(ret.name, "friends"); diff --git a/src/main.c b/src/main.c index a121a14..975902d 100644 --- a/src/main.c +++ b/src/main.c @@ -521,8 +521,8 @@ int main(int argc, char *argv[]) memset(user_settings, 0, sizeof(struct user_settings)); int settings_err = settings_load(user_settings, NULL); - init_term(); Tox *m = init_tox(f_use_ipv4); + init_term(); if (m == NULL) { endwin(); @@ -553,6 +553,9 @@ int main(int argc, char *argv[]) #ifdef _SUPPORT_AUDIO av = init_audio(prompt, m); + + device_set(prompt, input, user_settings->audio_in_dev); + device_set(prompt, output, user_settings->audio_out_dev); if ( errors() == NoError ) msg = "Audio initiated with no problems."; @@ -561,9 +564,6 @@ int main(int argc, char *argv[]) line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); - device_set(prompt, input, user_settings->audio_in_dev); - device_set(prompt, output, user_settings->audio_out_dev); - #endif /* _SUPPORT_AUDIO */ if (f_flag == -1) { diff --git a/src/toxic_windows.h b/src/toxic_windows.h index fef2af8..fc0d2d5 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -120,18 +120,20 @@ struct ToxWindow { #ifdef _SUPPORT_AUDIO - void(*onInvite)(ToxWindow *, ToxAv *); - void(*onRinging)(ToxWindow *, ToxAv *); - void(*onStarting)(ToxWindow *, ToxAv *); - void(*onEnding)(ToxWindow *, ToxAv *); - void(*onError)(ToxWindow *, ToxAv *); - void(*onStart)(ToxWindow *, ToxAv *); - void(*onCancel)(ToxWindow *, ToxAv *); - void(*onReject)(ToxWindow *, ToxAv *); - void(*onEnd)(ToxWindow *, ToxAv *); - void(*onRequestTimeout)(ToxWindow *, ToxAv *); - void(*onPeerTimeout)(ToxWindow *, ToxAv *); + void(*onInvite)(ToxWindow *, ToxAv *, int); + void(*onRinging)(ToxWindow *, ToxAv *, int); + void(*onStarting)(ToxWindow *, ToxAv *, int); + void(*onEnding)(ToxWindow *, ToxAv *, int); + void(*onError)(ToxWindow *, ToxAv *, int); + void(*onStart)(ToxWindow *, ToxAv *, int); + void(*onCancel)(ToxWindow *, ToxAv *, int); + void(*onReject)(ToxWindow *, ToxAv *, int); + void(*onEnd)(ToxWindow *, ToxAv *, int); + void(*onRequestTimeout)(ToxWindow *, ToxAv *, int); + void(*onPeerTimeout)(ToxWindow *, ToxAv *, int); + int call_index; /* If in a call will have this index set, otherwise it's -1. + * Don't modify outside av callbacks. */ #endif /* _SUPPORT_AUDIO */ char name[TOX_MAX_NAME_LENGTH];