Closed dethrace-labs closed 1 year ago
For a wip patch, I implemented loading sound from memory instead of from file. When applying it on current master, the clicking goes away.
--- a/src/S3/audio.c
+++ b/src/S3/audio.c
@@ -215,6 +215,11 @@ int S3DisposeDescriptor(tS3_sound_id id) {
if (desc->sound_data == NULL) {
return 0;
}
+
+ tS3_sample* sample = (tS3_sample*)desc->sound_data;
+ ma_audio_buffer_uninit(sample->audio_buffer);
+ S3MemFree(sample->dataptr);
+
S3MemFree(desc->sound_data);
desc->sound_data = NULL;
}
--- a/src/S3/s3_defs.h
+++ b/src/S3/s3_defs.h
@@ -162,6 +162,7 @@ typedef struct tS3_sample {
int channels;
char* dataptr;
void* freeptr;
+ void* audio_buffer; // added by DethRace (FIXME: use dataptr for storage + freeptr for freeing)
} tS3_sample;
typedef struct tS3_hardware_info {
diff --git a/src/S3/s3sound.c b/src/S3/s3sound.c
index b4ab571f..121780fc 100644
--- a/src/S3/s3sound.c
+++ b/src/S3/s3sound.c
@@ -131,6 +131,8 @@ void* S3LoadWavFile(char* pFile_name, tS3_sample* pSample) {
char* data_ptr; // [esp+C8h] [ebp-Ch] BYREF
// char* locked_buffer_data; // [esp+CCh] [ebp-8h] BYREF
size_t file_len; // [esp+D0h] [ebp-4h]
+ ma_format format; // Added by DethRace
+ ma_uint64 nbFrames; // Added by DethRace
f = fopen(pFile_name, "r");
if (f == NULL) {
@@ -154,12 +156,13 @@ void* S3LoadWavFile(char* pFile_name, tS3_sample* pSample) {
wav_format = 0;
data_ptr = 0;
if (S3ReadWavHeader(buf, &wav_format, &data_ptr, &data_size) == 0) {
+ S3MemFree(buf);
gS3_last_error = eS3_error_readfile;
dr_dprintf("ERROR: .WAV file '%s' is crap", pFile_name);
return 0;
}
pSample->freeptr = 0;
- pSample->dataptr = 0;
+ pSample->dataptr = buf;
pSample->size = data_size;
pSample->rate = wav_format->nSamplesPerSec;
pSample->resolution = wav_format->nAvgBytesPerSec;
@@ -170,12 +173,52 @@ void* S3LoadWavFile(char* pFile_name, tS3_sample* pSample) {
pSample->channels = BrSwap32(pSample->channels);
#endif
+ switch (wav_format->wBitsPerSample) {
+ case 8:
+ format = ma_format_u8;
+ nbFrames = data_size / wav_format->nChannels;
+ break;
+ case 16:
+ format = ma_format_s16;
+ nbFrames = data_size / 2 / wav_format->nChannels;
+ break;
+ case 24:
+ format = ma_format_s24;
+ nbFrames = data_size / 3 / wav_format->nChannels;
+ break;
+ case 32:
+ format = ma_format_s32;
+ nbFrames = data_size / 4 / wav_format->nChannels;
+ break;
+ default:
+ format = ma_format_unknown;
+ nbFrames = data_size * 8 / wav_format->wBitsPerSample / wav_format->nChannels;
+ break;
+ }
+ ma_audio_buffer_config bufferConfig = ma_audio_buffer_config_init(
+ format,
+ wav_format->nChannels,
+ nbFrames,
+ data_ptr,
+ NULL);
+ bufferConfig.sampleRate = wav_format->nSamplesPerSec;
+
+ pSample->audio_buffer = malloc(sizeof(ma_audio_buffer));
+ if (ma_audio_buffer_init(&bufferConfig, pSample->audio_buffer) != MA_SUCCESS) {
+ gS3_last_error = eS3_error_memory;
+ S3MemFree(buf);
+ return NULL;
+ }
+
ma_sound* sound = malloc(sizeof(ma_sound));
- // TOOD: load from memory - we've already read the file data
- if (ma_sound_init_from_file(&miniaudio_engine, pFile_name, MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, NULL, sound) != MA_SUCCESS) {
- return NULL; // Failed to load sound.
+
+ if (ma_sound_init_from_data_source(&miniaudio_engine, pSample->audio_buffer, MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, sound) != MA_SUCCESS) {
+ gS3_last_error = eS3_error_memory;
+ free(sound);
+ free(pSample->audio_buffer);
+ S3MemFree(buf);
+ return NULL; // Failed to load sound
}
- S3MemFree(buf);
return sound;
// S3MemFree(buf);
@@ -203,7 +246,7 @@ void* S3LoadWavFile(char* pFile_name, tS3_sample* pSample) {
// ds_buffer->lpVtbl->Unlock(ds_buffer, locked_buffer_data, locked_buffer_data_len, 0, 0);
// return ds_buffer;
// }
- return NULL;
+ // return NULL;
}
int S3StopSample(tS3_channel* chan) {
Clean up is missing. But that is not done anyway (#328)
Yes, I made similar changes to load from the data_ptr
set by S3ReadWavHeader
(I working on a couple of audio fixes on my local).
I didn't look further, but my guess is that there is some junk at the end of the wav file that is handled incorrectly by the miniaudio wav file loader, and also by the MIX_LoadWav
function.
I originally also reproduced the same clicking sound by passing the last chunk of the file (buf[file_len - data_size]
) to a miniaudio buffer
When holding down the horn ('H' key in race), there is a continuous click/pop sound as the horn sound loops.
This does not exist in OG, and is due to miniaudio not loading the wav file correctly.
SDL_mixer
also has the same issue.