summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-09-06 23:21:20 -0500
committersanine <sanine.not@pm.me>2022-09-06 23:21:20 -0500
commit500dd00fb11efdd19aef924b0d8ff0b370c28d33 (patch)
treed89b17563866950f02ec948b37dea6364b4ac0dc /src
parent7c678ce0266c66bb1b4d52bd70fb2351019e8ecd (diff)
implement mp3 loading
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/load/CMakeLists.txt7
-rw-r--r--src/load/load-mp3.c81
-rw-r--r--src/load/load.h1
-rw-r--r--src/mossrose.c7
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++) {