#include "decoder.h" #include #include static gboolean mpg123_decoder_init(struct decoder *decoder) { mpg123_handle *handle; int error; mpg123_init(); handle = mpg123_new("generic", &error); if(error) { g_warning("Error: %s", mpg123_plain_strerror(error)); return FALSE; } error = mpg123_open_feed(handle); if(error) { g_warning("Error: %s", mpg123_plain_strerror(error)); } /* force format for now */ mpg123_format_none(handle); mpg123_format(handle, 44100, 2, MPG123_ENC_SIGNED_16); decoder->data = handle; return TRUE; } static gssize mpg123_decoder_decode(struct decoder *decoder, GInputStream *input, GOutputStream *output, GError **error) { mpg123_handle *handle = decoder->data; gssize size; int ret; const int inbuf_size = 0x400*8; const int outbuf_size = 0x400*8; unsigned char inbuf[inbuf_size]; unsigned char outbuf[inbuf_size]; gsize inbuf_read = g_input_stream_read(input, inbuf, inbuf_size, NULL, NULL); if(mpg123_feed(handle, inbuf, inbuf_read) != MPG123_OK) { g_debug("asdfasdf"); *error = g_error_new(decoder_quark(), DECODER_CODE_ERROR, mpg123_strerror(handle)); return -1; } ret = mpg123_read(handle, outbuf, outbuf_size, (size_t*)&size); if(ret == MPG123_NEW_FORMAT) { long rate; int channels, enc; mpg123_getformat(handle, &rate, &channels, &enc); g_debug("New format: %li Hz, %i channels, encoding value %i", rate, channels, enc); ret = mpg123_read(handle, outbuf, outbuf_size, (size_t*)&size); decoder->rate = rate; /* TODO: mpg123 uses native byte order, add endian check here */ /* assuming little endian for now... */ switch(enc) { case MPG123_ENC_SIGNED_16: decoder->format = AUDIO_FORMAT_S16LE; break; default: *error = g_error_new(decoder_quark(), DECODER_CODE_ERROR, g_strdup("unknown audio format")); return -1; } decoder->channels = channels; } if(ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT && ret != MPG123_NEED_MORE) { *error = g_error_new(decoder_quark(), DECODER_CODE_ERROR, mpg123_plain_strerror(ret)); return -1; } if(size == 0) { *error = g_error_new(decoder_quark(), DECODER_CODE_DONE, "done"); return -1; } g_output_stream_write(output, outbuf, size, NULL, NULL); return size; } static void mpg123_decoder_close(struct decoder *decoder) { mpg123_handle *handle = decoder->data; mpg123_close(handle); mpg123_delete(handle); } static const gchar * const decoder_mpg123_extensions[] = { "mp3", NULL, }; const struct decoder_plugin decoder_mpg123_decoder = { .name = "mpg123", .extensions = decoder_mpg123_extensions, .init = mpg123_decoder_init, .decode = mpg123_decoder_decode, .close = mpg123_decoder_close, };