[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
--- /dev/null
+#include "fifo.h"
+#include <semaphore.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+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;
+}
#include <ao/ao.h>
#include <mpg123.h>
#include <unistd.h>
+#include "fifo.h"
#define BITS 8
struct playermem {
ao_device* aodev;
mpg123_handle* mh;
unsigned char* buffer;
+ fifo* queue;
};
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;
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);
struct playersettings* settings = (struct playersettings*) arg;
//mpg123_handle* mh;
//unsigned char* buffer;
- size_t buffer_size;
- size_t done;
int err;
int driver;
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());;
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);
-//}
+// }