From 500dd00fb11efdd19aef924b0d8ff0b370c28d33 Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 6 Sep 2022 23:21:20 -0500 Subject: implement mp3 loading --- src/load/CMakeLists.txt | 7 +++++ src/load/load-mp3.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ src/load/load.h | 1 + 3 files changed, 89 insertions(+) create mode 100644 src/load/CMakeLists.txt create mode 100644 src/load/load-mp3.c (limited to 'src/load') diff --git a/src/load/CMakeLists.txt b/src/load/CMakeLists.txt new file mode 100644 index 0000000..3369dd2 --- /dev/null +++ b/src/load/CMakeLists.txt @@ -0,0 +1,7 @@ +project(mossrose) + +target_sources(mossrose PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/load-mp3.c +) + +target_include_directories(mossrose PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/minimp3) diff --git a/src/load/load-mp3.c b/src/load/load-mp3.c new file mode 100644 index 0000000..09eef0c --- /dev/null +++ b/src/load/load-mp3.c @@ -0,0 +1,81 @@ +#define MINIMP3_FLOAT_OUTPUT +#define MINIMP3_IMPLEMENTATION +#include +#include +#include +#include "load.h" + + +#define ABORT(...) do { \ + fprintf(stderr, __VA_ARGS__); \ + free(mp3.buffer); \ + return NULL; \ +} while(0) + + +struct mossrose_sound_t * load_mp3(const char *filename) +{ + mp3dec_t mp3d; + mp3dec_file_info_t mp3; + if (mp3dec_load(&mp3d, filename, &mp3, NULL, NULL)) { + fprintf(stderr, "failed to decode mp3 file '%s'\n", filename); + return NULL; + } + + printf("samples: %lu\n" + "channels: %d\n" + "hz: %d\n" + "layer: %d\n" + "bitrate: %d\n", + mp3.samples, + mp3.channels, + mp3.hz, + mp3.layer, + mp3.avg_bitrate_kbps); + + if (mp3.channels != 1 && mp3.channels != 2) { + ABORT("files with %d audio tracks are not supported!\n", mp3.channels); + } + + struct mossrose_sound_t *sound = malloc(sizeof(struct mossrose_sound_t)); + if (sound == NULL) + ABORT("failed to allocate sound structure\n"); + + if (mp3.channels == 1) { + sound->mono = true; + sound->left = malloc(mp3.samples * sizeof(float)); + if (sound->left == NULL) { + free(sound); + ABORT("failed to allocate mono audio data!\n"); + } + memcpy(sound->left, mp3.buffer, mp3.samples * sizeof(float)); + sound->right = NULL; + sound->len = mp3.samples; + } + else { + /* stereo */ + sound->mono = false; + size_t sz = (mp3.samples/2) * sizeof(float); + sound->left = malloc(sz); + if (sound->left == NULL) { + free(sound); + ABORT("failed to allocate left audio channel!\n"); + } + sound->right = malloc(sz); + if (sound->right == NULL) { + free(sound->left); + free(sound); + ABORT("failed to allocate right audio channel!\n"); + } + for (int i=0; ileft[i/2] = mp3.buffer[i]; + else + sound->right[i/2] = mp3.buffer[i]; + } + sound->len = mp3.samples/2; + } + + free(mp3.buffer); + return sound; +} diff --git a/src/load/load.h b/src/load/load.h index 7f91b14..b4d60c0 100644 --- a/src/load/load.h +++ b/src/load/load.h @@ -4,5 +4,6 @@ #include "mossrose.h" struct mossrose_sound_t * load_wav(const char *filename); +struct mossrose_sound_t * load_mp3(const char *filename); #endif -- cgit v1.2.1