From 96ceab53c94df719531823d52ac26d8917eeaf63 Mon Sep 17 00:00:00 2001 From: John Janus Date: Sat, 23 Sep 2017 16:33:41 +0200 Subject: [PATCH] use fifo for buffer --- .kdev4/FakeRadio.kdev4 | 29 +++++++++++++++ fifo.c | 67 ++++++++++++++++++++++++++++++++++ fifo.h | 28 +++++++++++++++ mp3player.c | 82 ++++++++++++++++++++++++++++++------------ mp3player.h | 2 +- simple_try.c | 2 +- 6 files changed, 186 insertions(+), 24 deletions(-) create mode 100644 fifo.c create mode 100644 fifo.h diff --git a/.kdev4/FakeRadio.kdev4 b/.kdev4/FakeRadio.kdev4 index 5e23dcc..21a4f39 100644 --- a/.kdev4/FakeRadio.kdev4 +++ b/.kdev4/FakeRadio.kdev4 @@ -20,5 +20,34 @@ Name=GCC [CustomDefinesAndIncludes][ProjectPath0][Includes] 1=/home/john/devel/RPi/wiringPi/wiringPi/ +[Launch] +Launch Configurations=Launch Configuration 0 + +[Launch][Launch Configuration 0] +Configured Launch Modes=execute +Configured Launchers=nativeAppLauncher +Name=Neuer Starter für Kompilierte Programmdatei +Type=Native Application + +[Launch][Launch Configuration 0][Data] +Arguments= +Debugger Shell= +Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00) +Dependency Action=Nothing +Display Demangle Names=true +Display Static Members=false +EnvironmentGroup= +Executable=file:///home/john/devel/RPi/FakeRadio/mp3player +External Terminal=konsole --noclose --workdir %workdir -e %exe +GDB Path= +Project Target= +Remote GDB Config Script= +Remote GDB Run Script= +Remote GDB Shell Script= +Start With=ApplicationOutput +Use External Terminal=false +Working Directory= +isExecutable=true + [Project] VersionControlSupport=kdevgit diff --git a/fifo.c b/fifo.c new file mode 100644 index 0000000..054994e --- /dev/null +++ b/fifo.c @@ -0,0 +1,67 @@ +#include "fifo.h" +#include +#include +#include + +fifo* create_fifo ( size_t length ) +{ + fifo* f = malloc(sizeof(fifo)); + f->sem_in = malloc(sizeof(sem_t)); + f->sem_out = malloc(sizeof(sem_t)); + if (sem_init(f->sem_in, 0, length)) printf("Could not initialize sem_in"); + if (sem_init(f->sem_out, 0, 0)) printf("Could not initialize sem_out"); + f->first = NULL; + f->last = NULL; + return f; +} + +void fifo_push(fifo* f, unsigned char* buffer, size_t done) { + sem_wait(f->sem_in); + node* n = malloc(sizeof(node)); + n->buffer = buffer; + n->done = done; + n->next = NULL; + n->prev = f->last; + if (f->last!= NULL) { + f->last->next = n; + } + f->last = n; + if (f->first == NULL) { + f->first = n; + } + sem_post(f->sem_out); +} + +void fifo_pop(fifo* f, unsigned char** buffer, size_t* done) { + sem_wait(f->sem_out); + node* n = f->first; + *buffer = n->buffer; + *done = n->done; + if (f->first->next != NULL) { + f->first = f->first->next; +// f->first->next = NULL; + f->first->prev = NULL; + } else { + f->first = NULL; + f->last = NULL; + } + free(n); + sem_post(f->sem_in); +// return ret; +} + +int delete_fifo (fifo* f) +{ + node* n = f->first; + while (n != NULL) { + node* tmp = n->next; + free(n); + n=tmp; + } + sem_destroy(f->sem_in); + free(f->sem_in); + sem_destroy(f->sem_out); + free(f->sem_out); + free(f); + return 0; +} diff --git a/fifo.h b/fifo.h new file mode 100644 index 0000000..2a5d81e --- /dev/null +++ b/fifo.h @@ -0,0 +1,28 @@ +#ifndef _FIFO +#define _FIFO +#include + +typedef struct n{ + struct n* prev; + struct n* next; + unsigned char* buffer; + size_t done; +} node; + + +typedef struct { + node* first; + node* last; + size_t length; + sem_t* sem_in; + sem_t* sem_out; +} fifo; + + + + +fifo* create_fifo(size_t length); +void fifo_push (fifo* f, unsigned char* buffer, size_t done ); +void fifo_pop(fifo* f, unsigned char** buffer, size_t* done); +int delete_fifo ( fifo* f ); +#endif diff --git a/mp3player.c b/mp3player.c index a63df39..d7392de 100644 --- a/mp3player.c +++ b/mp3player.c @@ -3,12 +3,14 @@ #include #include #include +#include "fifo.h" #define BITS 8 struct playermem { ao_device* aodev; mpg123_handle* mh; unsigned char* buffer; + fifo* queue; }; struct playersettings { @@ -16,6 +18,12 @@ struct playersettings { bool loop; }; +typedef struct { + fifo* queue; + mpg123_handle* mh; + const char* file; +} decodeData; + static void cleanupThread(void* arg) { struct playermem* mem = (struct playermem*) arg; @@ -28,17 +36,22 @@ static void cleanupThread(void* arg) free(mem); } -pthread_t startPlayThread(const char* file, bool loop) -{ - pthread_t thread; - struct playersettings* settings = malloc(sizeof(struct playersettings)); - settings->file=file; - settings->loop=loop; - pthread_create(&thread, NULL, playFunc, (void*) settings); - return thread; +static void* decodeFunc(void* arg) { + decodeData* dd = arg; + size_t buffersize = mpg123_outblock(dd->mh); + while (1) { + unsigned char* buffer = malloc(buffersize * sizeof(unsigned char)); + size_t done; + int ret = mpg123_read(dd->mh, buffer, buffersize, &done); + if (ret == MPG123_DONE) { + mpg123_open(dd->mh, dd->file); + continue; + } + fifo_push(dd->queue, buffer, done); + } } -void* playFunc(void* arg) +static void* playFunc(void* arg) { pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); @@ -47,8 +60,6 @@ void* playFunc(void* arg) struct playersettings* settings = (struct playersettings*) arg; //mpg123_handle* mh; //unsigned char* buffer; - size_t buffer_size; - size_t done; int err; int driver; @@ -62,8 +73,6 @@ void* playFunc(void* arg) driver = ao_default_driver_id(); mpg123_init(); mem->mh = mpg123_new(NULL, &err); - buffer_size = mpg123_outblock(mem->mh)*2; - mem->buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char)); pthread_cleanup_push(cleanupThread, (void*) mem); if (mpg123_open(mem->mh, settings->file) != MPG123_OK) pthread_exit((void*) pthread_self());; if (mpg123_getformat(mem->mh, &rate, &channels, &encoding) != MPG123_OK) pthread_exit((void*) pthread_self());; @@ -75,25 +84,54 @@ void* playFunc(void* arg) format.matrix = 0; ao_option options = {"debug","",NULL}; mem->aodev = ao_open_live(driver, &format, &options); - - do { + mem->queue = create_fifo(5); + pthread_t dt; + decodeData dd; + dd.file = settings->file; + dd.queue = mem->queue; + dd.mh = mem->mh; + pthread_create(&dt, NULL, decodeFunc, &dd); +// do { while (running) { - if (mpg123_read(mem->mh, mem->buffer, buffer_size, &done) != MPG123_OK) break; - ao_play(mem->aodev, mem->buffer, done); + +// int mpg123ret = mpg123_read(mem->mh, mem->buffer, buffer_size, &done); +// if ( mpg123ret == MPG123_DONE && settings->loop) { +// mpg123_open(mem->mh, settings->file); +// continue; +// //mpg123_read(mem->mh, mem->buffer, buffer_size, &done); +// } else if (mpg123ret != MPG123_OK) { +// break; +// } +// ao_play(mem->aodev, fifo_pop(f), done); + unsigned char* buffer; + size_t done; + fifo_pop(mem->queue, &buffer, &done); + ao_play(mem->aodev, buffer, done); + free(buffer); pthread_testcancel(); } - } while (settings->loop); +// } while (settings->loop); pthread_cleanup_pop(1); pthread_exit((void*) pthread_self()); } -//int main(int argc, char** argv) -//{ -// pthread_t th = startPlayThread("platt01.mp3", true); +pthread_t startPlayThread(const char* file, bool loop) +{ + pthread_t thread; + struct playersettings* settings = malloc(sizeof(struct playersettings)); + settings->file=file; + settings->loop=loop; + pthread_create(&thread, NULL, playFunc, (void*) settings); + return thread; +} + +// int main(int argc, char** argv) +// { +// pthread_t th = startPlayThread("nebelhorn.mp3", true); // //sleep(3); // //pthread_cancel(th); // pthread_join(th, NULL); -//} +// } diff --git a/mp3player.h b/mp3player.h index 3ef0042..a245c64 100644 --- a/mp3player.h +++ b/mp3player.h @@ -5,6 +5,6 @@ long unsigned int startPlayThread ( const char* file, bool loop ); -void* playFunc(void*); +//void* playFunc(void*); #endif diff --git a/simple_try.c b/simple_try.c index d0ca308..028dc98 100644 --- a/simple_try.c +++ b/simple_try.c @@ -19,7 +19,7 @@ #define INTROBTN 13 #define HORNBTN 11 -static volatile bool running = true; +volatile bool running = true; static volatile bool pwrOn = false; static volatile bool chnl1 = true; static volatile bool intro = false; -- 2.47.1