diff --git a/.gitignore b/.gitignore index 47d3eac..af4794f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ fate-suite.ffmpeg.org +player/SDL minimp3 minimp3_arm *.gcda diff --git a/minimp3_ex.h b/minimp3_ex.h index 53a94cf..04a3d5d 100644 --- a/minimp3_ex.h +++ b/minimp3_ex.h @@ -455,7 +455,7 @@ int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERA if (!io || !buf || (size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE) return MP3D_E_PARAM; size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0; - uint64_t readed = 0, frames = 0; + uint64_t readed = 0; mp3dec_frame_info_t frame_info; int eof = 0; memset(&frame_info, 0, sizeof(frame_info)); @@ -500,7 +500,6 @@ int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERA frame_info.frame_bytes = frame_size; readed += i; - frames++; if (callback) { if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info))) @@ -765,8 +764,8 @@ size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples) { /* count decoded samples to properly cut padding */ if (dec->cur_sample + to_copy >= dec->detected_samples) to_copy = dec->detected_samples - dec->cur_sample; - dec->cur_sample += to_copy; } + dec->cur_sample += to_copy; memcpy(buf, dec->buffer + dec->buffer_consumed, to_copy*sizeof(mp3d_sample_t)); buf += to_copy; dec->buffer_consumed += to_copy; @@ -820,8 +819,8 @@ size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples) { /* ^ handle padding */ if (dec->cur_sample + to_copy >= dec->detected_samples) to_copy = dec->detected_samples - dec->cur_sample; - dec->cur_sample += to_copy; } + dec->cur_sample += to_copy; memcpy(buf, dec->buffer + dec->buffer_consumed, to_copy*sizeof(mp3d_sample_t)); buf += to_copy; dec->buffer_consumed += to_copy; diff --git a/player/decode.c b/player/decode.c index 4b8eb2e..0a46f91 100644 --- a/player/decode.c +++ b/player/decode.c @@ -8,16 +8,15 @@ #include #include #include -#include "decode.h" #define MINIMP3_IMPLEMENTATION -#include "../minimp3.h" +#include "decode.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) static void get_spectrum(decoder *dec, int numch) { int i, ch, band; - const mp3dec_t *d = &dec->mp3d; + const mp3dec_t *d = &dec->mp3d.mp3d; // Average spectrum power for 32 frequency band for (ch = 0; ch < numch; ch++) { @@ -53,38 +52,8 @@ static void get_spectrum(decoder *dec, int numch) void decode_samples(decoder *dec, uint8_t *buf, int bytes) { - if (dec->pcm_bytes - dec->pcm_copied) - { - int to_copy = MIN(dec->pcm_bytes - dec->pcm_copied, bytes); - memcpy(buf, (uint8_t*)dec->pcm + dec->pcm_copied, to_copy); - buf += to_copy; - bytes -= to_copy; - dec->pcm_copied += to_copy; - } - if (!bytes) - return; - do - { - int samples = mp3dec_decode_frame(&dec->mp3d, dec->mp3_buf + dec->pos, dec->mp3_size - dec->pos, dec->pcm, &dec->info); - dec->pos += dec->info.frame_bytes; - if (samples) - { - get_spectrum(dec, dec->info.channels); - dec->pcm_bytes = samples*2*dec->info.channels; - dec->pcm_copied = MIN(dec->pcm_bytes, bytes); - memcpy(buf, dec->pcm, dec->pcm_copied); - buf += dec->pcm_copied; - bytes -= dec->pcm_copied; - if (!dec->mp3_rate) - dec->mp3_rate = dec->info.hz; - if (!dec->mp3_channels) - dec->mp3_channels = dec->info.channels; - if (dec->mp3_rate != dec->info.hz || dec->mp3_channels != dec->info.channels) - break; - } - } while (dec->info.frame_bytes && bytes); - if (bytes) - memset(buf, 0, bytes); + memset(buf, 0, bytes); + mp3dec_ex_read(&dec->mp3d, (mp3d_sample_t*)buf, bytes/sizeof(mp3d_sample_t)); } int open_dec(decoder *dec, const char *file_name) @@ -94,38 +63,14 @@ int open_dec(decoder *dec, const char *file_name) memset(dec, 0, sizeof(*dec)); - struct stat st; -retry_open: - dec->file = open(file_name, O_RDONLY); - if (dec->file < 0 && (errno == EAGAIN || errno == EINTR)) - goto retry_open; - if (dec->file < 0 || fstat(dec->file, &st) < 0) - { - close_dec(dec); + mp3dec_ex_open(&dec->mp3d, file_name, MP3D_SEEK_TO_SAMPLE); + if (!dec->mp3d.samples) return 0; - } - - dec->mp3_size = st.st_size; -retry_mmap: - dec->mp3_buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, dec->file, 0); - if (MAP_FAILED == dec->mp3_buf && (errno == EAGAIN || errno == EINTR)) - goto retry_mmap; - if (MAP_FAILED == dec->mp3_buf) - { - close_dec(dec); - return 0; - } - mp3dec_init(&dec->mp3d); return 1; } int close_dec(decoder *dec) { - if (dec->mp3_buf) - free(dec->mp3_buf); - if (dec->mp3_buf && MAP_FAILED != dec->mp3_buf) - munmap(dec->mp3_buf, dec->mp3_size); - if (dec->file) - close(dec->file); + mp3dec_ex_close(&dec->mp3d); memset(dec, 0, sizeof(*dec)); } diff --git a/player/decode.h b/player/decode.h index 7e2a1da..e6dfc1d 100644 --- a/player/decode.h +++ b/player/decode.h @@ -1,6 +1,6 @@ #pragma once #include -#include "../minimp3.h" +#include "../minimp3_ex.h" #ifdef __cplusplus extern "C" { #endif @@ -10,14 +10,9 @@ typedef int (*PARSE_INFO_CB)(void *user, char *file_name, int rate, int mp3_chan typedef struct decoder { - mp3dec_t mp3d; - mp3dec_frame_info_t info; - uint8_t *mp3_buf; - size_t mp3_size, pos; - int file, pcm_bytes, pcm_copied, mp3_rate, mp3_channels; + mp3dec_ex_t mp3d; float mp3_duration; float spectrum[32][2]; // for visualization - short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; } decoder; extern decoder _dec; @@ -25,7 +20,6 @@ extern decoder _dec; int open_dec(decoder *dec, const char *file_name); int close_dec(decoder *dec); void decode_samples(decoder *dec, uint8_t *buf, int bytes); -void start_parser(PARSE_GET_FILE_CB fcb, void *fcb_user, PARSE_INFO_CB icb, void *icb_user); #ifdef __cplusplus } diff --git a/player/player.cpp b/player/player.cpp index 817e953..0e0ab49 100644 --- a/player/player.cpp +++ b/player/player.cpp @@ -98,7 +98,7 @@ static int init() SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif - _mainWindow = SDL_CreateWindow("Lion Audio Player", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 600, SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI); + _mainWindow = SDL_CreateWindow("minimp3", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 600, SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI); if (!_mainWindow) { printf("error: create window failed: %s\n", SDL_GetError()); @@ -197,6 +197,16 @@ static void tick() } } nk_button_pop_behavior(ctx); + static size_t progress = 0; + uint64_t cur_sample = _dec.mp3d.cur_sample; + progress = cur_sample; + nk_progress(ctx, &progress, _dec.mp3d.samples, NK_MODIFIABLE); + if (progress != cur_sample) + { + SDL_PauseAudio(1); + mp3dec_ex_seek(&_dec.mp3d, progress); + SDL_PauseAudio(0); + } if (nk_tree_push(ctx, NK_TREE_TAB, "Playlist", NK_MAXIMIZED)) {