2026-04-29 06:57:46 +03:00

75 lines
1.8 KiB
C

//
// Tiny C wrapper around dr_mp3 + dr_flac. Each function decodes a buffer of
// MP3/FLAC bytes to interleaved s16 PCM. The caller owns the returned
// pointer and must release it with player_decoder_free().
//
// Compiled to a static lib (decoders.a) by lib/build_decoders.sh. The
// metaprogram in build.jai re-runs the script if the .a is missing or the
// sources are newer.
//
#define DR_MP3_IMPLEMENTATION
#define DR_MP3_NO_STDIO
#include "dr_mp3.h"
#define DR_FLAC_IMPLEMENTATION
#define DR_FLAC_NO_STDIO
#include "dr_flac.h"
#include <stdint.h>
#include <stdlib.h>
int16_t* player_decode_mp3(
const void* data, size_t data_size,
uint32_t* out_channels,
uint32_t* out_sample_rate,
uint64_t* out_total_pcm_frames
) {
drmp3_config config;
config.channels = 0;
config.sampleRate = 0;
drmp3_uint64 total_frames = 0;
drmp3_int16* pcm = drmp3_open_memory_and_read_pcm_frames_s16(
data, data_size,
&config,
&total_frames,
NULL // default allocator
);
if (!pcm) return NULL;
*out_channels = config.channels;
*out_sample_rate = config.sampleRate;
*out_total_pcm_frames = total_frames;
return pcm;
}
int16_t* player_decode_flac(
const void* data, size_t data_size,
uint32_t* out_channels,
uint32_t* out_sample_rate,
uint64_t* out_total_pcm_frames
) {
unsigned int channels = 0;
unsigned int sample_rate = 0;
drflac_uint64 total_frames = 0;
drflac_int16* pcm = drflac_open_memory_and_read_pcm_frames_s16(
data, data_size,
&channels,
&sample_rate,
&total_frames,
NULL
);
if (!pcm) return NULL;
*out_channels = channels;
*out_sample_rate = sample_rate;
*out_total_pcm_frames = total_frames;
return pcm;
}
void player_decoder_free(void* p) {
free(p);
}