mplay.mp3

Controllable music player (mp3)
git clone https://git.sinitax.com/sinitax/mplay.mp3
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit ac7ab7067e81f8ab3748de26acefc4c8f31ec8ea
parent 8a5f93bfa7b56bdc101a810119c081eaa4a2537e
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 10 Mar 2024 14:34:39 +0100

Rename mp3d to generic decoder

Diffstat:
Mmplay.mp3.c | 107+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 58 insertions(+), 49 deletions(-)

diff --git a/mplay.mp3.c b/mplay.mp3.c @@ -30,7 +30,7 @@ struct audiofile { size_t len; }; -struct mp3d { +struct decoder { mp3dec_t dec; uint8_t *pos; ssize_t left; @@ -38,6 +38,7 @@ struct mp3d { mp3d_sample_t *samples; size_t sample_cnt; size_t sample_cap; + size_t sample_max; size_t sample_next; @@ -75,7 +76,7 @@ static bool pa_strm_sink_update; static struct audiofile audiofile = { 0 }; -static struct mp3d mp3d = { 0 }; +static struct decoder decoder = { 0 }; static pthread_t input_worker_thread; static bool input_worker_alive = false; @@ -173,41 +174,41 @@ decode_next_frame(mp3d_sample_t *samples, size_t *size) if (size) *size = 0; - if (mp3d.sample_next < mp3d.sample_cnt) { - cnt = MIN(max_cnt, mp3d.sample_cnt - mp3d.sample_next); + if (decoder.sample_next < decoder.sample_cnt) { + cnt = MIN(max_cnt, decoder.sample_cnt - decoder.sample_next); *size = cnt * sizeof(mp3d_sample_t); } else { - if (mp3d.sample_cnt + max_cnt > mp3d.sample_cap) { - mp3d.sample_cap = MAX(mp3d.sample_cap * 2, - mp3d.sample_cnt + max_cnt); - mp3d.samples = realloc(mp3d.samples, - mp3d.sample_cap * sizeof(mp3d_sample_t)); - if (!mp3d.samples) die("realloc:"); + if (decoder.sample_cnt + max_cnt > decoder.sample_cap) { + decoder.sample_cap = MAX(decoder.sample_cap * 2, + decoder.sample_cnt + max_cnt); + decoder.samples = realloc(decoder.samples, + decoder.sample_cap * sizeof(mp3d_sample_t)); + if (!decoder.samples) die("realloc:"); } - cnt = (size_t) mp3dec_decode_frame(&mp3d.dec, mp3d.pos, - (int) mp3d.left, &mp3d.samples[mp3d.sample_cnt], &info); + cnt = (size_t) mp3dec_decode_frame(&decoder.dec, decoder.pos, + (int) decoder.left, &decoder.samples[decoder.sample_cnt], &info); cnt *= (size_t) info.channels; - mp3d.sample_cnt += cnt; + decoder.sample_cnt += cnt; if (size) *size = (size_t) info.frame_bytes; if (!info.frame_bytes) return 0; - if (!mp3d.init) { - mp3d.rate = info.hz; - mp3d.channels = info.channels; + if (!decoder.init) { + decoder.rate = info.hz; + decoder.channels = info.channels; } - mp3d.pos += info.frame_bytes; - mp3d.left -= info.frame_bytes; + decoder.pos += info.frame_bytes; + decoder.left -= info.frame_bytes; } if (samples != NULL) - memcpy(samples, &mp3d.samples[mp3d.sample_next], + memcpy(samples, &decoder.samples[decoder.sample_next], cnt * sizeof(mp3d_sample_t)); - mp3d.sample_next += cnt; + decoder.sample_next += cnt; return cnt; } @@ -218,23 +219,23 @@ decoder_init(void) mp3d_sample_t samples[MINIMP3_MAX_SAMPLES_PER_FRAME]; size_t size; - mp3dec_init(&mp3d.dec); - mp3d.pos = audiofile.data; - mp3d.left = (ssize_t) audiofile.len; + mp3dec_init(&decoder.dec); + decoder.pos = audiofile.data; + decoder.left = (ssize_t) audiofile.len; - mp3d.sample_cnt = 0; - mp3d.sample_next = 0; - mp3d.sample_cap = MINIMP3_MAX_SAMPLES_PER_FRAME; - mp3d.samples = malloc(mp3d.sample_cap * sizeof(mp3d_sample_t)); - if (!mp3d.samples) die("malloc:"); + decoder.sample_cnt = 0; + decoder.sample_next = 0; + decoder.sample_cap = MINIMP3_MAX_SAMPLES_PER_FRAME; + decoder.samples = malloc(decoder.sample_cap * sizeof(mp3d_sample_t)); + if (!decoder.samples) die("malloc:"); /* decode channel specs */ decode_next_frame(samples, &size); if (!size) die("invalid mp3"); - mp3d.seek = false; - mp3d.pause = false; - mp3d.init = true; + decoder.seek = false; + decoder.pause = false; + decoder.init = true; } static void @@ -242,14 +243,14 @@ decoder_seek(size_t sample_pos) { size_t size, cnt; - while (mp3d.sample_next < sample_pos) { + while (decoder.sample_next < sample_pos) { cnt = decode_next_frame(NULL, &size); if (!size) { mplay_status(MPLAY_INFO_EXIT, "from seek"); exit(0); } } - mp3d.sample_next = sample_pos; + decoder.sample_next = sample_pos; } static void @@ -280,9 +281,9 @@ pa_stream_write_callback(pa_stream *stream, size_t requested, void *data) pa_stream_write(stream, samples, cnt * sizeof(mp3d_sample_t), NULL, 0, - mp3d.seek ? PA_SEEK_RELATIVE_ON_READ: PA_SEEK_RELATIVE); + decoder.seek ? PA_SEEK_RELATIVE_ON_READ: PA_SEEK_RELATIVE); - mp3d.seek = false; + decoder.seek = false; remaining -= (ssize_t) (cnt * sizeof(mp3d_sample_t)); } } @@ -368,13 +369,21 @@ user_vol(void) } static double -user_time(void) +user_pos(void) { size_t sample_pos; - sample_pos = MAX(0, mp3d.sample_next - stream_samples_buffered()); + sample_pos = (size_t) MAX(0, + (ssize_t) decoder.sample_next - (ssize_t) stream_samples_buffered()); - return (double) sample_pos * 1.F / (double) (mp3d.rate * mp3d.channels); + return (double) sample_pos * 1.F / (double) (decoder.rate * decoder.channels); +} + +static double +user_end(void) +{ + return (double) decoder.sample_max * 1.F + / (double) (decoder.rate * decoder.channels); } static void @@ -414,18 +423,18 @@ cmd_seek(double time_sec, double delta) pa_threaded_mainloop_lock(pa_mloop); if (delta != 0) { - time_sec = user_time() + delta; + time_sec = user_pos() + delta; } if (time_sec < 0) time_sec = 0; - sample_pos = (size_t) (time_sec * mp3d.channels * mp3d.rate); + sample_pos = (size_t) (time_sec * decoder.channels * decoder.rate); decoder_seek(sample_pos); op = pa_stream_flush(pa_strm, NULL, NULL); pa_operation_unref(op); - mp3d.seek = true; + decoder.seek = true; - mplay_status(MPLAY_INFO_SEEK, "%02.2f", user_time()); + mplay_status(MPLAY_INFO_SEEK, "%02.2f", user_pos()); pa_threaded_mainloop_unlock(pa_mloop); } @@ -437,11 +446,11 @@ cmd_playpause(void) pa_threaded_mainloop_lock(pa_mloop); - mp3d.pause ^= 1; - op = pa_stream_cork(pa_strm, mp3d.pause, NULL, NULL); + decoder.pause ^= 1; + op = pa_stream_cork(pa_strm, decoder.pause, NULL, NULL); pa_operation_unref(op); - mplay_status(MPLAY_INFO_PAUSE, "%i", mp3d.pause); + mplay_status(MPLAY_INFO_PAUSE, "%i", decoder.pause); pa_threaded_mainloop_unlock(pa_mloop); } @@ -454,8 +463,8 @@ cmd_status(void) update_sink_input_info(); mplay_status(MPLAY_INFO_STATUS, - "volume=%02.2f,time=%02.2f,pause=%i", - user_vol(), user_time(), mp3d.pause); + "volume=%02.2f,pos=%02.2f,end=%02.2f,pause=%i", + user_vol(), user_pos(), user_end(), decoder.pause); pa_threaded_mainloop_unlock(pa_mloop); } @@ -651,8 +660,8 @@ main(int argc, const char **argv) audiofile.data = map_file(file, &audiofile.len); decoder_init(); - pa_spec.channels = (uint8_t) mp3d.channels; - pa_spec.rate = (uint32_t) mp3d.rate; + pa_spec.channels = (uint8_t) decoder.channels; + pa_spec.rate = (uint32_t) decoder.rate; pa_mloop = pa_threaded_mainloop_new(); if (!pa_mloop) die("pa_threaded_mainloop_new");