shithub: mp3dec

Download patch

ref: 53cb2a1e0996bc0da30cc1ec35a25f518048c91c
parent: 29f6dca321808736a6f671692e647b95fda2d288
author: lieff <lieff@users.noreply.github.com>
date: Mon Feb 5 20:40:21 EST 2018

player: add audio render

--- /dev/null
+++ b/player/audio_sdl.c
@@ -1,0 +1,94 @@
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <SDL2/SDL.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "decode.h"
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#define SDL2
+
+typedef struct audio_ctx
+{
+#ifdef SDL2
+    int dev;
+#endif
+    SDL_AudioSpec outputSpec;
+} audio_ctx;
+
+decoder _dec;
+
+static void audio_cb(void *udata, Uint8 *stream, int len)
+{
+    audio_ctx *ctx = (audio_ctx *)udata;
+    memset(stream, 0, len);
+    EnterCriticalSection(&_dec.mp3_lock);
+    if ((_dec.mp3_size - _dec.mp3_pos) >= len)
+    {
+        memcpy(stream, (char*)_dec.mp3_buf + _dec.mp3_pos, len);
+        _dec.mp3_pos += len;
+    }
+    LeaveCriticalSection(&_dec.mp3_lock);
+}
+
+int sdl_audio_init(void **audio_render, int samplerate, int channels, int format, int buffer)
+{
+    *audio_render = 0;
+    audio_ctx *ctx = calloc(1, sizeof(audio_ctx));
+    SDL_AudioSpec wanted;
+    memset(&wanted, 0, sizeof(wanted));
+    wanted.freq = samplerate;
+    wanted.format = format ? AUDIO_F32 : AUDIO_S16;
+    wanted.channels = channels;
+    wanted.samples = buffer ? buffer : 4096;
+    wanted.callback = audio_cb;
+    wanted.userdata = ctx;
+    if (SDL_Init(SDL_INIT_AUDIO) < 0)
+    {
+        printf("error: sdl init failed: %s\n", SDL_GetError());
+        return 0;
+    }
+#ifdef SDL2
+    int dev = SDL_OpenAudioDevice(NULL, 0, &wanted, &ctx->outputSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
+    if (dev <= 0)
+    {
+        printf("error: couldn't open audio: %s\n", SDL_GetError());
+        free(ctx);
+        return 0;
+    }
+    ctx->dev = dev;
+#else
+    if (SDL_OpenAudio(&wanted, &ctx->outputSpec) < 0)
+    {
+        printf("error: couldn't open audio: %s\n", SDL_GetError());
+        return 0;
+    }
+#endif
+#ifdef SDL2
+    SDL_PauseAudioDevice(dev, 0);
+#else
+    SDL_PauseAudio(0);
+#endif
+    *audio_render = ctx;
+    return 1;
+}
+
+void sdl_audio_release(void *audio_render)
+{
+    audio_ctx *ctx = (audio_ctx *)audio_render;
+#ifdef SDL2
+    if (ctx->dev)
+    {
+        SDL_CloseAudioDevice(ctx->dev);
+        ctx->dev = 0;
+    }
+#else
+    SDL_PauseAudio(1);
+    SDL_CloseAudio();
+#endif
+    free(ctx);
+}
--- /dev/null
+++ b/player/audio_sdl.h
@@ -1,0 +1,11 @@
+#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sdl_audio_init(void **audio_render, int samplerate, int channels, int format, int buffer);
+void sdl_audio_release(void *audio_render);
+
+#ifdef __cplusplus
+}
+#endif
--- a/player/build.sh
+++ b/player/build.sh
@@ -1,1 +1,1 @@
-gcc -O2 -o player *.cpp *.c -lstdc++ -lglfw -lGL -lpthread -lm -ldl
\ No newline at end of file
+gcc -O2 -o player *.cpp *.c -lstdc++ -lglfw -lGL -lpthread -lm -ldl -lSDL2
\ No newline at end of file
--- a/player/decode.c
+++ b/player/decode.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <sys/mman.h>
@@ -26,8 +27,9 @@
         if (dec->mp3_buf)
             free(dec->mp3_buf);
         dec->mp3_buf = (short *)buf_new;
-        dec->mp3_size += bytes;
     }
+    memcpy((char*)dec->mp3_buf + dec->mp3_size, buf, bytes);
+    dec->mp3_size += bytes;
     LeaveCriticalSection(&dec->mp3_lock);
 }
 
@@ -98,6 +100,7 @@
         free(dec->mp3_buf);
         dec->mp3_buf = 0;
         dec->mp3_size = 0;
+        dec->mp3_pos = 0;
         dec->mp3_allocated = 0;
         dec->mp3_rate = 0;
         dec->mp3_channels = 0;
--- a/player/decode.h
+++ b/player/decode.h
@@ -1,5 +1,8 @@
 #pragma once
 #include "system.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 typedef struct decoder
 {
@@ -6,9 +9,15 @@
     CRITICAL_SECTION mp3_lock;
     const char *file_name;
     short *mp3_buf;
-    int mp3_size, mp3_allocated, mp3_file_size, mp3_rate, mp3_channels;
+    int mp3_size, mp3_pos, mp3_allocated, mp3_file_size, mp3_rate, mp3_channels;
     float mp3_duration;
     HANDLE mp3_open_thread;
 } decoder;
 
+extern decoder _dec;
+
 int preload_mp3(decoder *dec, const char *file_name);
+
+#ifdef __cplusplus
+}
+#endif
--- a/player/player.cpp
+++ b/player/player.cpp
@@ -10,6 +10,8 @@
 #include <OpenGL/gl3.h>
 #endif
 #include "FreeSans.h"
+#include "audio_sdl.h"
+#include "decode.h"
 
 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
@@ -32,10 +34,11 @@
 #ifdef USE_GLES3
 static PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
 #endif
-void       *_ctx;
-GLFWwindow *_mainWindow;
-std::map<std::string, int> _previews;
-std::vector<std::string> _playlist;
+static void       *_ctx;
+static GLFWwindow *_mainWindow;
+static std::map<std::string, int> _previews;
+static std::vector<std::string> _playlist;
+static void *_render;
 
 static int load_image(const stbi_uc *data, int len)
 {
@@ -156,7 +159,7 @@
             if (nk_button_label(ctx, "Play") && _selected < (int)_playlist.size())
             {
                 _play_state = 1;
-                //play();
+                preload_mp3(&_dec, _playlist[_selected].c_str());
             }
         } else
         {
@@ -196,10 +199,15 @@
 
 int main(int argc, char *argv[])
 {
+    InitializeCriticalSection(&_dec.mp3_lock);
+    sdl_audio_init(&_render, 44100, 2, 0, 0);
     init();
+    for (int i = 1; i < argc; i++)
+        _playlist.push_back(argv[i]);
     while (!glfwWindowShouldClose(_mainWindow))
     {
         tick();
     }
     close();
+    sdl_audio_release(_render);
 }