diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/load/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/load/load-mp3.c | 81 | ||||
-rw-r--r-- | src/load/load.h | 1 | ||||
-rw-r--r-- | src/mossrose.c | 7 |
5 files changed, 98 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0453c34..6b3d2e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,8 @@ target_sources(mossrose PUBLIC ${CMAKE_CURRENT_LIST_DIR}/sound.c ) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/load) + if (MOSSROSE_BUILD_TESTS) target_sources(test PUBLIC 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 <stdio.h> +#include <minimp3_ex.h> +#include <mossrose.h> +#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; i<mp3.samples; i++) { + if (i%2) + sound->left[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 diff --git a/src/mossrose.c b/src/mossrose.c index 8a99770..f96d394 100644 --- a/src/mossrose.c +++ b/src/mossrose.c @@ -5,6 +5,7 @@ #include <mossrose.h> #include "channel.h" #include "sound.h" +#include "load/load.h" struct mossrose_global_t { @@ -154,6 +155,12 @@ void mossrose_poll_callbacks() } +struct mossrose_sound_t * mossrose_load_mp3(const char *filename) +{ + return load_mp3(filename); +} + + int mossrose_terminate() { for (int i=0; i<mossrose_global.n_channels; i++) { |