From cf8dda6b0d2b461afa32fbce60e79a7a3e842613 Mon Sep 17 00:00:00 2001 From: mannol Date: Thu, 10 Jul 2014 01:24:14 +0200 Subject: [PATCH] Fixes problems with upstream changes --- src/audio_call.c | 106 ++++++++++++++--------------------------------- src/device.c | 73 ++++++++++++++------------------ src/device.h | 1 - 3 files changed, 62 insertions(+), 118 deletions(-) diff --git a/src/audio_call.c b/src/audio_call.c index 529e43a..0d9a881 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -95,6 +95,7 @@ void callback_requ_timeout ( int32_t call_index, void *arg ); void callback_peer_timeout ( int32_t call_index, void *arg ); int stop_transmission(int call_index); +void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int size); static void print_err (ToxWindow *self, uint8_t *error_str) { @@ -104,7 +105,7 @@ static void print_err (ToxWindow *self, uint8_t *error_str) ToxAv *init_audio(ToxWindow *self, Tox *tox) { ASettins.cs = av_DefaultSettings; - ASettins.cs.video_height = ASettins.cs.video_width = 0; + ASettins.cs.max_video_height= ASettins.cs.max_video_width = 0; ASettins.errors = ae_None; @@ -140,6 +141,7 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox) toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, self); toxav_register_callstate_callback(callback_peer_timeout, av_OnPeerTimeout, self); + toxav_register_audio_recv_callback(ASettins.av, write_device_callback); return ASettins.av; } @@ -167,74 +169,11 @@ void read_device_callback (const int16_t* captured, uint32_t size, void* data) } } -/* - * Transmission - */ -void *transmission(void *arg) +void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int size) { -#define lock pthread_mutex_lock(&this_call->mutex) -#define unlock pthread_mutex_unlock(&this_call->mutex) - - ToxWindow* self = arg; - int32_t call_index = self->call_idx; - - /* Missing audio support */ - if ( !ASettins.av ) _cbend; - - Call* this_call = &ASettins.calls[call_index]; - - int32_t dec_frame_len; - int16_t PCM[frame_size]; - this_call->has_output = 1; - - if ( open_primary_device(input, &this_call->in_idx) != de_None ) - line_info_add(self, NULL, NULL, NULL, "Failed to open input device!", SYS_MSG, 0, 0); - if ( register_device_callback(call_index, this_call->in_idx, read_device_callback, &call_index, _True) != de_None) - /* Set VAD as true for all; TODO: Make it more dynamic */ - line_info_add(self, NULL, NULL, NULL, "Failed to register input handler!", SYS_MSG, 0, 0); - - if ( open_primary_device(output, &this_call->out_idx) != de_None ) { - line_info_add(self, NULL, NULL, NULL, "Failed to open output device!", SYS_MSG, 0, 0); - this_call->has_output = 0; - } - /* Start transmission */ - while (this_call->ttas) { - - lock; - if ( this_call->has_output ) { - - if (playback_device_ready(this_call->out_idx) == de_Busy) { - unlock; - continue; - } - - dec_frame_len = toxav_recv_audio(ASettins.av, call_index, frame_size, PCM); - - /* Play the packet */ - if (dec_frame_len > 0) { - write_out(this_call->out_idx, PCM, dec_frame_len, av_DefaultSettings.audio_channels); - } - else if (dec_frame_len != 0) { - /* >implying it'll ever get an error */ - } - - } - unlock; - - usleep(1000); - } - -cleanup: - if ( this_call->in_idx != -1 ) if ( close_device(input, this_call->in_idx) != de_None ) - line_info_add(self, NULL, NULL, NULL, "Failed to close input device!", SYS_MSG, 0, 0); - - if ( this_call->out_idx != -1 ) if ( close_device(output, this_call->out_idx) != de_None ) - line_info_add(self, NULL, NULL, NULL, "Failed to close output device!", SYS_MSG, 0, 0); - - set_call(this_call, _False); - - _cbend; + if (ASettins.calls[call_index].ttas) + write_out(ASettins.calls[call_index].out_idx, data, size, 1); } int start_transmission(ToxWindow *self) @@ -247,17 +186,25 @@ int start_transmission(ToxWindow *self) } if ( !toxav_capability_supported(ASettins.av, self->call_idx, AudioDecoding) || - !toxav_capability_supported(ASettins.av, self->call_idx, AudioEncoding) ) + !toxav_capability_supported(ASettins.av, self->call_idx, AudioEncoding) ) return -1; set_call(&ASettins.calls[self->call_idx], _True); - - if ( 0 != pthread_create(&ASettins.calls[self->call_idx].ttid, NULL, transmission, self ) && - 0 != pthread_detach(ASettins.calls[self->call_idx].ttid) ) { - return -1; - } - return 0; + if ( open_primary_device(input, &ASettins.calls[self->call_idx].in_idx) != de_None ) + line_info_add(self, NULL, NULL, NULL, "Failed to open input device!", SYS_MSG, 0, 0); + + if ( register_device_callback(self->call_idx, ASettins.calls[self->call_idx].in_idx, + read_device_callback, &self->call_idx, _True) != de_None) + /* Set VAD as true for all; TODO: Make it more dynamic */ + line_info_add(self, NULL, NULL, NULL, "Failed to register input handler!", SYS_MSG, 0, 0); + + if ( open_primary_device(output, &ASettins.calls[self->call_idx].out_idx) != de_None ) { + line_info_add(self, NULL, NULL, NULL, "Failed to open output device!", SYS_MSG, 0, 0); + ASettins.calls[self->call_idx].has_output = 0; + } + + return 0; } int stop_transmission(int call_index) @@ -265,6 +212,14 @@ int stop_transmission(int call_index) if ( ASettins.calls[call_index].ttas ) { toxav_kill_transmission(ASettins.av, call_index); ASettins.calls[call_index].ttas = _False; + + if ( ASettins.calls[call_index].in_idx != -1 ) + close_device(input, ASettins.calls[call_index].in_idx); + + if ( ASettins.calls[call_index].out_idx != -1 ) + close_device(output, ASettins.calls[call_index].out_idx); + + set_call(&ASettins.calls[call_index], _False); return 0; } @@ -302,10 +257,9 @@ void callback_recv_starting ( int32_t call_index, void* arg ) 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; } + return; } - } void callback_recv_ending ( int32_t call_index, void* arg ) { diff --git a/src/device.c b/src/device.c index 50d0514..93637a8 100644 --- a/src/device.c +++ b/src/device.c @@ -57,6 +57,7 @@ typedef struct _Device { _Bool enable_VAD; _Bool muted; float VAD_treshold; /* 40 is usually recommended value */ + pthread_mutex_t mutex[1]; } Device; const char *ddevice_names[2]; /* Default device */ @@ -190,7 +191,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx uint32_t i; for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; i ++); - if (i == size[type]) { unlock; return de_AllDevicesBusy; } + if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; } else *device_idx = i; Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));; @@ -205,6 +206,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx device->source = running[type][i]->source; } device->ref_count++; + pthread_mutex_init(device->mutex, NULL); unlock; return de_None; } @@ -254,6 +256,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx thread_paused = _False; } + pthread_mutex_init(device->mutex, NULL); unlock; return de_None; } @@ -269,7 +272,7 @@ DeviceError close_device(DeviceType type, uint32_t device_idx) unlock; return de_DeviceNotActive; } - + if ( !(device->ref_count--) ) { running[type][device_idx] = NULL; unlock; @@ -289,11 +292,13 @@ DeviceError close_device(DeviceType type, uint32_t device_idx) alcMakeContextCurrent(NULL); if ( device->ctx ) alcDestroyContext(device->ctx); } - + free(device); return rc; } + unlock; + return de_None; } @@ -312,21 +317,6 @@ DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, Dat return de_None; } -inline__ DeviceError playback_device_ready(uint32_t device_idx) -{ - if (device_idx >= MAX_DEVICES) return de_InvalidSelection; - - Device* device = running[output][device_idx]; - - if (!device) return de_DeviceNotActive; - - int32_t ready; - alGetSourcei(device->source, AL_BUFFERS_PROCESSED, &ready); - - return ready <= 0 ? de_Busy : de_None; -} - -/* TODO: thread safety? */ inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels) { if (device_idx >= MAX_DEVICES) return de_InvalidSelection; @@ -335,37 +325,38 @@ inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t leng if (!device || device->muted) return de_DeviceNotActive; - alcMakeContextCurrent(device->ctx); /* TODO: Check for error */ - - uint32_t buffer; - int32_t ready; + pthread_mutex_lock(device->mutex); - alSourceUnqueueBuffers(device->source, 1, &buffer); - alBufferData(buffer, AL_FORMAT_MONO16, data, lenght * 2 * 1 /*channels*/, sample_rate); // TODO: Frequency must be set dynamically + ALuint bufid; + ALint processed, queued; + alGetSourcei(device->source, AL_BUFFERS_PROCESSED, &processed); + alGetSourcei(device->source, AL_BUFFERS_QUEUED, &queued); - int rc = alGetError(); - if (rc != AL_NO_ERROR) { - fprintf(stderr, "Error setting buffer %d\n", rc); - return de_BufferError; + if(processed) { + ALuint bufids[processed]; + alSourceUnqueueBuffers(device->source, processed, bufids); + alDeleteBuffers(processed - 1, bufids + 1); + bufid = bufids[0]; + } + else if(queued < 16) alGenBuffers(1, &bufid); + else { + pthread_mutex_unlock(device->mutex); + return de_Busy; } - alSourceQueueBuffers(device->source, 1, &buffer); - rc = alGetError(); - if (alGetError() != AL_NO_ERROR) { - fprintf(stderr, "Error: could not buffer audio: %d\n", rc); - return de_BufferError; - } + alBufferData(bufid, AL_FORMAT_MONO16, data, lenght * 2 * channels, av_DefaultSettings.audio_sample_rate); + alSourceQueueBuffers(device->source, 1, &bufid); - alGetSourcei(device->source, AL_SOURCE_STATE, &ready); + ALint state; + alGetSourcei(device->source, AL_SOURCE_STATE, &state); - if (ready != AL_PLAYING) { - alSourcePlay(device->source); - return de_None; - } + if(state != AL_PLAYING) alSourcePlay(device->source); - return de_Busy; + + pthread_mutex_unlock(device->mutex); + return de_None; } void* thread_poll (void* arg) // TODO: maybe use thread for every input source @@ -438,4 +429,4 @@ void* get_device_callback_data(uint32_t device_idx) return NULL; return running[input][device_idx]->cb_data; -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/device.h b/src/device.h index 6b8e062..95daea6 100644 --- a/src/device.h +++ b/src/device.h @@ -75,7 +75,6 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx /* Stop device */ DeviceError close_device(DeviceType type, uint32_t device_idx); -DeviceError playback_device_ready(uint32_t device_idx); /* Write data to device */ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels);