#include "backend.h"
#include "harness/config.h"
#include "miniaudio/miniaudio.h"
#include "resource.h"
#include "s3_defs.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
typedef struct tS3_sample_struct_miniaudio {
ma_audio_buffer_ref buffer_ref;
ma_sound sound;
int init_volume;
int init_pan;
int init_new_rate;
int initialized;
} tS3_sample_struct_miniaudio;
// dethrace
ma_engine miniaudio_engine;
tAudioBackend_error_code AudioBackend_Init(void) {
ma_result result;
ma_engine_config engineConfig;
engineConfig = ma_engine_config_init();
result = ma_engine_init(&engineConfig, &miniaudio_engine);
if (result != MA_SUCCESS) {
printf("Failed to initialize audio engine.");
return eAB_error;
}
ma_engine_set_volume(&miniaudio_engine, harness_game_config.volume_multiplier);
return eAB_success;
}
tAudioBackend_error_code AudioBackend_InitCDA(void) {
return eAB_error;
}
void AudioBackend_UnInit(void) {
ma_engine_uninit(&miniaudio_engine);
}
void AudioBackend_UnInitCDA(void) {
}
void* AudioBackend_AllocateSampleTypeStruct(void) {
tS3_sample_struct_miniaudio* sample_struct;
sample_struct = S3MemAllocate(sizeof(tS3_sample_struct_miniaudio), kMem_S3_DOS_SOS_channel);
if (sample_struct == NULL) {
return 0;
}
memset(sample_struct
, 0, sizeof(tS3_sample_struct_miniaudio
));
return sample_struct;
}
tAudioBackend_error_code AudioBackend_PlaySample(tS3_channel* chan) {
tS3_sample_struct_miniaudio* miniaudio;
tS3_sample* sample_data;
ma_result result;
ma_int32 flags;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
sample_data = (tS3_sample*)chan->descriptor->sound_data;
result = ma_audio_buffer_ref_init(ma_format_u8, sample_data->channels, sample_data->dataptr, sample_data->size / sample_data->channels, &miniaudio->buffer_ref);
miniaudio->buffer_ref.sampleRate = sample_data->rate;
if (result != MA_SUCCESS) {
return eAB_error;
}
flags = MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_NO_SPATIALIZATION;
result = ma_sound_init_from_data_source(&miniaudio_engine, &miniaudio->buffer_ref, flags, NULL, &miniaudio->sound);
if (result != MA_SUCCESS) {
return eAB_error;
}
miniaudio->initialized = 1;
if (miniaudio->init_volume > 0)
{
AudioBackend_SetVolume (chan, miniaudio->init_volume);
AudioBackend_SetPan (chan, miniaudio->init_pan);
AudioBackend_SetFrequency (chan, miniaudio->init_new_rate);
}
ma_sound_set_looping(&miniaudio->sound, chan->repetitions == 0);
ma_sound_start(&miniaudio->sound);
return eAB_success;
}
int AudioBackend_SoundIsPlaying(tS3_channel* chan) {
tS3_sample_struct_miniaudio* miniaudio;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
if (ma_sound_is_playing(&miniaudio->sound)) {
return 1;
}
return 0;
}
tAudioBackend_error_code AudioBackend_SetVolume(tS3_channel* chan, int volume) {
tS3_sample_struct_miniaudio* miniaudio;
float linear_volume;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
if (!miniaudio->initialized)
{
miniaudio->init_volume = volume;
return eAB_success;
}
linear_volume = volume / 510.0f;
ma_sound_set_volume(&miniaudio->sound, linear_volume);
return eAB_success;
}
tAudioBackend_error_code AudioBackend_SetPan(tS3_channel* chan, int pan) {
tS3_sample_struct_miniaudio* miniaudio;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
if (!miniaudio->initialized)
{
miniaudio->init_pan = pan;
return eAB_success;
}
// convert from directsound -10000 - 10000 pan scale
ma_sound_set_pan(&miniaudio->sound, pan / 10000.0f);
return eAB_success;
}
tAudioBackend_error_code AudioBackend_SetFrequency(tS3_channel* chan, int rate) {
tS3_sample_struct_miniaudio* miniaudio;
tS3_sample* sample_data;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
if (!miniaudio->initialized)
{
miniaudio->init_new_rate = rate;
return eAB_success;
}
sample_data = (tS3_sample*)chan->descriptor->sound_data;
// convert from directsound frequency to linear pitch scale
ma_sound_set_pitch(&miniaudio->sound, (rate / (float)sample_data->rate));
return eAB_success;
}
tAudioBackend_error_code AudioBackend_StopSample(tS3_channel* chan) {
tS3_sample_struct_miniaudio* miniaudio;
miniaudio = (tS3_sample_struct_miniaudio*)chan->type_struct_sample;
if (miniaudio->initialized) {
ma_sound_stop(&miniaudio->sound);
ma_sound_uninit(&miniaudio->sound);
ma_audio_buffer_ref_uninit(&miniaudio->buffer_ref);
miniaudio->initialized = 0;
}
return eAB_success;
}