From a8502ae3b152998772f0c309a2347f7c48e3f83f Mon Sep 17 00:00:00 2001 From: Torben Hohn Date: Tue, 31 Mar 2009 00:08:56 +0200 Subject: [PATCH] decouple flash from jack thread with ringbuffer --- flashsupport.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/flashsupport.c b/flashsupport.c index 19fdc83..b6f84e7 100644 --- a/flashsupport.c +++ b/flashsupport.c @@ -192,7 +192,9 @@ extern "C" { #ifdef JACK #include +#include #include +#include #endif static struct FPX_Functions fpx_functions; @@ -1064,11 +1066,32 @@ struct jack_output_data { SRC_STATE *src_l; SRC_STATE *src_r; int src_error; + + jack_ringbuffer_t *buffer; + sem_t semaphore; + volatile int quit; + pthread_t tid; }; +static void *jack_flash_thread( void *arg ) +{ + struct jack_output_data *p = arg; + int jack_rate = jack_get_sample_rate( p->client ); + int flash_frames = jack_get_buffer_size( p->client ) * 44100 / jack_rate; + + size_t bufsize = 2*flash_frames * sizeof( int16_t ); + int16_t *buffer = alloca( bufsize ); + while( !p->quit ) { + sem_wait( &(p->semaphore) ); + FPI_SoundOutput_FillBuffer(p, (char*) buffer, bufsize); + jack_ringbuffer_write( p->buffer, (char*)buffer, bufsize ); + } + return NULL; +} -static int jack_process_cb( jack_nframes_t nframes, void *arg ) { +static int jack_process_cb( jack_nframes_t nframes, void *arg ) +{ struct jack_output_data *p = arg; int i; int jack_rate = jack_get_sample_rate( p->client ); @@ -1083,8 +1106,19 @@ static int jack_process_cb( jack_nframes_t nframes, void *arg ) { SRC_DATA sd; + if( jack_ringbuffer_read_space( p->buffer ) < bufsize ) { + // no data to read. fill ports with zero and return. + memset( port_l, 0, nframes * sizeof( jack_default_audio_sample_t ) ); + memset( port_r, 0, nframes * sizeof( jack_default_audio_sample_t ) ); + return 0; + } - FPI_SoundOutput_FillBuffer(p, (char*) buffer, bufsize); + //FPI_SoundOutput_FillBuffer(p, (char*) buffer, bufsize); + if( jack_ringbuffer_read( p->buffer, (char *)buffer, bufsize ) != bufsize ) { + printf( "Something is pretty wrong :( \n" ); + return 0; + } + sem_post( &(p->semaphore) ); for( i=0; isrc_l = src_new(SRC_SINC_FASTEST, 1, & (p->src_error)); p->src_r = src_new(SRC_SINC_FASTEST, 1, & (p->src_error)); + /* First, let's create the main loop */ if (!(p->client = jack_client_open( "flash", 0, NULL ))) goto fail; + jack_rate = jack_get_sample_rate( p->client ); + flash_frames = jack_get_buffer_size( p->client ) * 44100 / jack_rate; + bufsize = 2*flash_frames * sizeof( int16_t ); + + p->buffer = jack_ringbuffer_create( bufsize * 2 ); + sem_init( &(p->semaphore), 0, 2 ); + + pthread_create( &(p->tid), NULL, jack_flash_thread, p ); + /* Second, initialize the connection context */ if (!(p->port_l = jack_port_register( p->client, "out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) ) goto fail; @@ -1167,6 +1214,10 @@ static int FPX_SoundOutput_Close(void *ptr) { struct jack_output_data *p = ptr; //assert(p); + if( p->tid ) { + p->quit = 1; + pthread_join( p->tid, NULL ); + } if (p->client) { jack_deactivate( p->client ); -- 2.11.4.GIT