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);
}