1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 19:13:26 +01:00

Merge pull request #183 from mannol1/master

Fixes problems with upstream changes
This commit is contained in:
mannol1 2014-07-10 01:30:17 +02:00
commit a774121c13
3 changed files with 61 additions and 117 deletions

View File

@ -95,6 +95,7 @@ void callback_requ_timeout ( int32_t call_index, void *arg );
void callback_peer_timeout ( int32_t call_index, void *arg ); void callback_peer_timeout ( int32_t call_index, void *arg );
int stop_transmission(int call_index); 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, char *error_str) static void print_err (ToxWindow *self, char *error_str)
{ {
@ -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_requ_timeout, av_OnRequestTimeout, self);
toxav_register_callstate_callback(callback_peer_timeout, av_OnPeerTimeout, self); toxav_register_callstate_callback(callback_peer_timeout, av_OnPeerTimeout, self);
toxav_register_audio_recv_callback(ASettins.av, write_device_callback);
return ASettins.av; 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) if (ASettins.calls[call_index].ttas)
#define unlock pthread_mutex_unlock(&this_call->mutex) write_out(ASettins.calls[call_index].out_idx, data, size, 1);
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;
} }
int start_transmission(ToxWindow *self) int start_transmission(ToxWindow *self)
@ -252,9 +191,17 @@ int start_transmission(ToxWindow *self)
set_call(&ASettins.calls[self->call_idx], _True); set_call(&ASettins.calls[self->call_idx], _True);
if ( 0 != pthread_create(&ASettins.calls[self->call_idx].ttid, NULL, transmission, self ) && if ( open_primary_device(input, &ASettins.calls[self->call_idx].in_idx) != de_None )
0 != pthread_detach(ASettins.calls[self->call_idx].ttid) ) { line_info_add(self, NULL, NULL, NULL, "Failed to open input device!", SYS_MSG, 0, 0);
return -1;
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; return 0;
@ -265,6 +212,14 @@ int stop_transmission(int call_index)
if ( ASettins.calls[call_index].ttas ) { if ( ASettins.calls[call_index].ttas ) {
toxav_kill_transmission(ASettins.av, call_index); toxav_kill_transmission(ASettins.av, call_index);
ASettins.calls[call_index].ttas = _False; 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; return 0;
} }
@ -302,11 +257,10 @@ void callback_recv_starting ( int32_t call_index, void* arg )
windows[i].onStarting(&windows[i], ASettins.av, call_index); windows[i].onStarting(&windows[i], ASettins.av, call_index);
if ( 0 != start_transmission(&windows[i]) ) {/* YEAH! */ if ( 0 != start_transmission(&windows[i]) ) {/* YEAH! */
line_info_add(&windows[i], NULL, NULL, NULL, "Error starting transmission!", SYS_MSG, 0, 0); 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 ) void callback_recv_ending ( int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onEnding); CB_BODY(call_index, arg, onEnding);

View File

@ -57,6 +57,7 @@ typedef struct _Device {
_Bool enable_VAD; _Bool enable_VAD;
_Bool muted; _Bool muted;
float VAD_treshold; /* 40 is usually recommended value */ float VAD_treshold; /* 40 is usually recommended value */
pthread_mutex_t mutex[1];
} Device; } Device;
const char *ddevice_names[2]; /* Default 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; uint32_t i;
for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; 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; else *device_idx = i;
Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));; 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->source = running[type][i]->source;
} }
device->ref_count++; device->ref_count++;
pthread_mutex_init(device->mutex, NULL);
unlock; unlock;
return de_None; return de_None;
} }
@ -254,6 +256,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
thread_paused = _False; thread_paused = _False;
} }
pthread_mutex_init(device->mutex, NULL);
unlock; unlock;
return de_None; return de_None;
} }
@ -294,6 +297,8 @@ DeviceError close_device(DeviceType type, uint32_t device_idx)
return rc; return rc;
} }
unlock;
return de_None; return de_None;
} }
@ -312,21 +317,6 @@ DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, Dat
return de_None; 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) 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; if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
@ -335,39 +325,40 @@ inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t leng
if (!device || device->muted) return de_DeviceNotActive; if (!device || device->muted) return de_DeviceNotActive;
alcMakeContextCurrent(device->ctx); /* TODO: Check for error */ pthread_mutex_lock(device->mutex);
uint32_t buffer;
int32_t ready;
alSourceUnqueueBuffers(device->source, 1, &buffer); ALuint bufid;
alBufferData(buffer, AL_FORMAT_MONO16, data, lenght * 2 * 1 /*channels*/, sample_rate); // TODO: Frequency must be set dynamically ALint processed, queued;
alGetSourcei(device->source, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(device->source, AL_BUFFERS_QUEUED, &queued);
int rc = alGetError(); if(processed) {
if (rc != AL_NO_ERROR) { ALuint bufids[processed];
fprintf(stderr, "Error setting buffer %d\n", rc); alSourceUnqueueBuffers(device->source, processed, bufids);
return de_BufferError; alDeleteBuffers(processed - 1, bufids + 1);
bufid = bufids[0];
} }
else if(queued < 16) alGenBuffers(1, &bufid);
alSourceQueueBuffers(device->source, 1, &buffer); else {
pthread_mutex_unlock(device->mutex);
rc = alGetError();
if (alGetError() != AL_NO_ERROR) {
fprintf(stderr, "Error: could not buffer audio: %d\n", rc);
return de_BufferError;
}
alGetSourcei(device->source, AL_SOURCE_STATE, &ready);
if (ready != AL_PLAYING) {
alSourcePlay(device->source);
return de_None;
}
return de_Busy; return de_Busy;
} }
alBufferData(bufid, AL_FORMAT_MONO16, data, lenght * 2 * channels, av_DefaultSettings.audio_sample_rate);
alSourceQueueBuffers(device->source, 1, &bufid);
ALint state;
alGetSourcei(device->source, AL_SOURCE_STATE, &state);
if(state != AL_PLAYING) alSourcePlay(device->source);
pthread_mutex_unlock(device->mutex);
return de_None;
}
void* thread_poll (void* arg) // TODO: maybe use thread for every input source void* thread_poll (void* arg) // TODO: maybe use thread for every input source
{ {
/* /*

View File

@ -75,7 +75,6 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
/* Stop device */ /* Stop device */
DeviceError close_device(DeviceType type, uint32_t device_idx); DeviceError close_device(DeviceType type, uint32_t device_idx);
DeviceError playback_device_ready(uint32_t device_idx);
/* Write data to device */ /* Write data to device */
DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels); DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8_t channels);