Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The horn has a noticeable clicking sound #324

Closed
dethrace-labs opened this issue May 4, 2023 · 2 comments · Fixed by #329
Closed

The horn has a noticeable clicking sound #324

dethrace-labs opened this issue May 4, 2023 · 2 comments · Fixed by #329
Assignees

Comments

@dethrace-labs
Copy link
Owner

dethrace-labs commented May 4, 2023

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.

@dethrace-labs dethrace-labs self-assigned this May 4, 2023
@madebr
Copy link
Collaborator

madebr commented May 6, 2023

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)

@dethrace-labs
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants