From 3cb5dbdaa9db986d89e639122588491229ed82c9 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 23 Mar 2025 18:57:14 +0100 Subject: [PATCH] Work on the audio implementation. --- sfw/audio/audio.cpp_off | 105 ++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 30 deletions(-) diff --git a/sfw/audio/audio.cpp_off b/sfw/audio/audio.cpp_off index 3c213df..80b7b1d 100644 --- a/sfw/audio/audio.cpp_off +++ b/sfw/audio/audio.cpp_off @@ -1,3 +1,30 @@ + +#define MINIAUDIO_IMPLEMENTATION // miniaudio +#define MA_NO_FLAC // miniaudio +#define STS_MIXER_IMPLEMENTATION // sts_mixer + +#ifdef __APPLE__ +#define MA_NO_RUNTIME_LINKING // miniaudio osx +#endif + +//--STRIP +#include "core/memory.h" + +#include "audio.h" + +#include "3rd_jo_mp1.h" + +#define get_bits stb_vorbis_get_bits +#define error stb_vorbis_error +#include "3rd_stb_vorbis.h" +#undef error +#undef DEBUG + +#include "3rd_miniaudio.h" +#include "3rd_sts_mixer.h" + +//--STRIP + // @fixme: really shutdown audio & related threads before quitting. ma_dr_wav crashes. // encapsulate ma_dr_wav,ma_dr_mp3,stbvorbis and some buffer with the sts_mixer_stream_t @@ -95,15 +122,21 @@ static void reset_stream(mystream_t *stream) { // load a (stereo) stream static bool load_stream(mystream_t *stream, const char *filename) { - int datalen; - char *data = vfs_load(filename, &datalen); - if (!data) + int datalen = 0; + + //char *data = vfs_load(filename, &datalen); + + char *data = NULL; + + if (!data) { return false; + } int error; - int HZ = 44100; + //int HZ = 44100; stream->type = UNK; stream->loop = true; + if (stream->type == UNK && (stream->ogg = stb_vorbis_open_memory((const unsigned char *)data, datalen, &error, NULL))) { stb_vorbis_info info = stb_vorbis_get_info(stream->ogg); if (info.channels != 2) { @@ -114,7 +147,7 @@ static bool load_stream(mystream_t *stream, const char *filename) { stream->stream.sample.frequency = info.sample_rate; stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_16; } - if (stream->type == UNK && ma_dr_wav_init_memory(&stream->wav, data, datalen, NULL)) { + if (stream->type == UNK && ma_dr_wav_init_memory(&stream->wav, data, (size_t)datalen, NULL)) { if (stream->wav.channels != 2) { puts("cannot stream wav file. stereo required."); goto end; @@ -123,11 +156,15 @@ static bool load_stream(mystream_t *stream, const char *filename) { stream->stream.sample.frequency = stream->wav.sampleRate; stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_16; } - ma_dr_mp3_config mp3_cfg = { 2, HZ }; - if (stream->type == UNK && (ma_dr_mp3_init_memory(&stream->mp3_, data, datalen, NULL /*&mp3_cfg*/) != 0)) { - stream->type = MP3; - stream->stream.sample.frequency = stream->mp3_.sampleRate; - stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_FLOAT; + + if (stream->type == UNK) { + //ma_dr_mp3_config mp3_cfg = { 2, HZ }; + + if ((ma_dr_mp3_init_memory(&stream->mp3_, data, (size_t)datalen, NULL /*&mp3_cfg*/) != 0)) { + stream->type = MP3; + stream->stream.sample.frequency = stream->mp3_.sampleRate; + stream->stream.sample.audio_format = STS_MIXER_SAMPLE_FORMAT_FLOAT; + } } if (stream->type == UNK) { @@ -147,15 +184,19 @@ end:; // load a (mono) sample static bool load_sample(sts_mixer_sample_t *sample, const char *filename) { int datalen; - char *data = vfs_load(filename, &datalen); - if (!data) + //char *data = vfs_load(filename, &datalen); + + char *data = NULL; + + if (!data) { return false; + } int error; int channels = 0; if (!channels) - for (ma_dr_wav w = { 0 }, *wav = &w; wav && ma_dr_wav_init_memory(wav, data, datalen, NULL); wav = 0) { + for (ma_dr_wav w = { 0 }, *wav = &w; wav && ma_dr_wav_init_memory(wav, data, (size_t)datalen, NULL); wav = 0) { channels = wav->channels; sample->frequency = wav->sampleRate; sample->audio_format = STS_MIXER_SAMPLE_FORMAT_16; @@ -181,13 +222,14 @@ static bool load_sample(sts_mixer_sample_t *sample, const char *filename) { ma_dr_mp3_config mp3_cfg = { 2, 44100 }; ma_uint64 mp3_fc; if (!channels) - for (short *fbuf = ma_dr_mp3_open_memory_and_read_pcm_frames_s16(data, datalen, &mp3_cfg, &mp3_fc, NULL); fbuf; fbuf = 0) { + for (short *fbuf = ma_dr_mp3_open_memory_and_read_pcm_frames_s16(data, (size_t)datalen, &mp3_cfg, &mp3_fc, NULL); fbuf; fbuf = 0) { channels = mp3_cfg.channels; sample->frequency = mp3_cfg.sampleRate; sample->audio_format = STS_MIXER_SAMPLE_FORMAT_16; sample->length = mp3_fc; // / sizeof(float) / mp3_cfg.channels; sample->data = fbuf; } + if (!channels) { short *output = 0; int outputSize, hz, mp1channels; @@ -287,8 +329,8 @@ int audio_init(int flags) { #endif }; - if (ma_context_init(backends, countof(backends), NULL, &context) != MA_SUCCESS) { - PRINTF("%s\n", "Failed to initialize audio context."); + if (ma_context_init(backends, (int)(sizeof(backends) / sizeof(0 [backends])), NULL, &context) != MA_SUCCESS) { + LOG_ERR("Failed to initialize audio context."); return false; } @@ -297,7 +339,7 @@ int audio_init(int flags) { config.playback.format = ma_format_s32; config.playback.channels = 2; config.sampleRate = 44100; - config.dataCallback = (void *)audio_callback; //< @r-lyeh add void* cast + config.dataCallback = audio_callback; config.pUserData = NULL; if (ma_device_init(NULL, &config, &device) != MA_SUCCESS) { @@ -320,20 +362,20 @@ typedef struct audio_handle { }; } audio_handle; -static array(audio_handle *) audio_instances; +static Vector audio_instances; audio_t audio_clip(const char *pathfile) { - audio_handle *a = REALLOC(0, sizeof(audio_handle)); + audio_handle *a = memnew(audio_handle); memset(a, 0, sizeof(audio_handle)); a->is_clip = load_sample(&a->clip, pathfile); - array_push(audio_instances, a); + audio_instances.push_back(a); return a; } audio_t audio_stream(const char *pathfile) { - audio_handle *a = REALLOC(0, sizeof(audio_handle)); + audio_handle *a = memnew(audio_handle); memset(a, 0, sizeof(audio_handle)); a->is_stream = load_stream(&a->stream, pathfile); - array_push(audio_instances, a); + audio_instances.push_back(a); return a; } @@ -342,7 +384,7 @@ float audio_volume_clip(float gain) { if (gain >= 0 && gain <= 1) volume_clip = gain * gain; // patch all live clips - for (int i = 0, active = 0; i < STS_MIXER_VOICES; ++i) { + for (int i = 0; i < STS_MIXER_VOICES; ++i) { if (mixer.voices[i].state != STS_MIXER_VOICE_STOPPED) // is_active? if (mixer.voices[i].sample) // is_sample? mixer.voices[i].gain = volume_clip; @@ -353,7 +395,7 @@ float audio_volume_stream(float gain) { if (gain >= 0 && gain <= 1) volume_stream = gain * gain; // patch all live streams - for (int i = 0, active = 0; i < STS_MIXER_VOICES; ++i) { + for (int i = 0; i < STS_MIXER_VOICES; ++i) { if (mixer.voices[i].state != STS_MIXER_VOICE_STOPPED) // is_active? if (mixer.voices[i].stream) // is_stream? mixer.voices[i].gain = volume_stream; @@ -369,9 +411,11 @@ float audio_volume_master(float gain) { } int audio_mute(int mute) { static bool muted = 0; - do_once muted = flag("--mute") || flag("--muted"); - if (mute >= 0 && mute <= 1) + + if (mute >= 0 && mute <= 1) { muted = mute; + } + return muted; } int audio_muted() { @@ -479,13 +523,14 @@ static bool audio_queue_callback(sts_mixer_sample_t *sample, void *userdata) { int sl = sample->length / 2; // 2 ch int bytes = sl * 2 * (sample->audio_format == STS_MIXER_SAMPLE_FORMAT_16 ? 2 : 4); - char *dst = sample->data; + char *dst = (char *)sample->data; static audio_queue_t *aq = 0; do { - while (!aq) + while (!aq) { aq = (audio_queue_t *)thread_queue_consume(&queue_mutex, THREAD_QUEUE_WAIT_INFINITE); + } int len = aq->avail > bytes ? bytes : aq->avail; memcpy(dst, (char *)aq->data + aq->cursor, len); @@ -495,7 +540,7 @@ static bool audio_queue_callback(sts_mixer_sample_t *sample, void *userdata) { aq->avail -= len; if (aq->avail <= 0) { - FREE(aq); // @fixme: mattias' original thread_queue_consume() implementation crashes here on tcc+win because of a double free on same pointer. using mcmp for now + memfree(aq); // @fixme: mattias' original thread_queue_consume() implementation crashes here on tcc+win because of a double free on same pointer. using mcmp for now aq = 0; } } while (bytes > 0); @@ -542,7 +587,7 @@ int audio_queue(const void *samples, int num_samples, int flags) { return 0; } - audio_queue_t *aq = MALLOC(sizeof(audio_queue_t) + (bytes << (channels == 1))); // dupe space if going to be converted from mono to stereo + audio_queue_t *aq = (audio_queue_t *)memalloc(sizeof(audio_queue_t) + (bytes << (channels == 1))); // dupe space if going to be converted from mono to stereo aq->cursor = 0; aq->avail = bytes; aq->flags = flags;