#include <stdbool.h>
#include <ao/ao.h>
#include <mpg123.h>
+#include <unistd.h>
#define BITS 8
+struct playermem {
+ ao_device* aodev;
+ mpg123_handle* mh;
+ unsigned char* buffer;
+};
+
+struct playersettings {
+ const char* file;
+ bool loop;
+};
+
+static void cleanupThread(void* arg)
+{
+ struct playermem* mem = (struct playermem*) arg;
+ free(mem->buffer);
+ ao_close(mem->aodev);
+ mpg123_close(mem->mh);
+ mpg123_delete(mem->mh);
+ mpg123_exit();
+ ao_shutdown();
+ free(mem);
+}
+
pthread_t startPlayThread(const char* file, bool loop)
{
pthread_t thread;
- pthread_create(&thread, NULL, playFunc, (void*) file, loop);
+ struct playersettings* settings = malloc(sizeof(struct playersettings));
+ settings->file=file;
+ settings->loop=loop;
+ pthread_create(&thread, NULL, playFunc, (void*) settings);
return thread;
}
-void* playFunc(void* file)
+void* playFunc(void* arg)
{
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+ //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
bool running = true;
- mpg123_handle* mh;
- unsigned char* buffer;
+ struct playermem* mem = (struct playermem*) malloc(sizeof(struct playermem));
+ struct playersettings* settings = (struct playersettings*) arg;
+ //mpg123_handle* mh;
+ //unsigned char* buffer;
size_t buffer_size;
size_t done;
int err;
int driver;
- ao_device* aodev;
+ //ao_device* aodev;
ao_sample_format format;
int channels;
int encoding;
ao_initialize();
driver = ao_default_driver_id();
mpg123_init();
- mh = mpg123_new(NULL, &err);
- buffer_size = mpg123_outblock(mh);
- buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
-
- if (mpg123_open(mh, file) != MPG123_OK) return NULL;
- if (mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) return NULL;
+ mem->mh = mpg123_new(NULL, &err);
+ buffer_size = mpg123_outblock(mem->mh);
+ mem->buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
+ pthread_cleanup_push(cleanupThread, (void*) mem);
+ do {
+ if (mpg123_open(mem->mh, settings->file) != MPG123_OK) return NULL;
+ if (mpg123_getformat(mem->mh, &rate, &channels, &encoding) != MPG123_OK) return NULL;
- format.bits = mpg123_encsize(encoding) * BITS;
- format.rate = rate;
- format.channels = channels;
- format.byte_format = AO_FMT_NATIVE;
- format.matrix = 0;
- aodev = ao_open_live(driver, &format, NULL);
-
- while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK && running) {
- ao_play(aodev, buffer, done);
- }
-
- // cleanup
- free (buffer);
- ao_close(aodev);
- mpg123_close(mh);
- mpg123_delete(mh);
- mpg123_exit();
- ao_shutdown();
+ format.bits = mpg123_encsize(encoding) * BITS;
+ format.rate = rate;
+ format.channels = channels;
+ format.byte_format = AO_FMT_NATIVE;
+ format.matrix = 0;
+ mem->aodev = ao_open_live(driver, &format, NULL);
+
+
+
+ while (mpg123_read(mem->mh, mem->buffer, buffer_size, &done) == MPG123_OK && running)
+ {
+ ao_play(mem->aodev, mem->buffer, done);
+ pthread_testcancel();
+ }
+ } 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);
+// //sleep(3);
+// //pthread_cancel(th);
+// pthread_join(th, NULL);
+//}