SDL_mixer: music_wavpack.c: disable DSD music decoding by default. (84476)

From 84476f6e7418fa0f55a3d5d515eebf74897cd128 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Wed, 11 Oct 2023 10:51:02 +0300
Subject: [PATCH] music_wavpack.c: disable DSD music decoding by default.

DSD files aren't of common interest. And the decimation
code isn't easy on the cpu, either...

Set the SDL2MIXER_WAVPACK_DSD cmake option to enable it.
---
 CMakeLists.txt             |  4 ++++
 src/codecs/music_wavpack.c | 34 ++++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0458c13d..287a9794 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -190,6 +190,7 @@ cmake_dependent_option(SDL3MIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorb
 option(SDL3MIXER_WAVE "Enable streaming WAVE music" ON)
 
 option(SDL3MIXER_WAVPACK "Enable WavPack music" ON)
+cmake_dependent_option(SDL3MIXER_WAVPACK_DSD "Enable WavPack DSD music support" OFF SDL3MIXER_WAVPACK OFF)
 cmake_dependent_option(SDL3MIXER_WAVPACK_SHARED "Dynamically load WavPack library" "${SDL3MIXER_DEPS_SHARED}" SDL3MIXER_WAVPACK OFF)
 
 if(SDL3MIXER_VORBIS_TREMOR OR SDL3MIXER_VORBIS_VORBISFILE OR SDL3MIXER_FLAC_LIBFLAC OR SDL3MIXER_OPUS)
@@ -1061,6 +1062,9 @@ if(SDL3MIXER_WAVPACK)
     endif()
     if(SDL3MIXER_WAVPACK_ENABLED)
         target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_WAVPACK)
+        if(SDL3MIXER_WAVPACK_DSD)
+          target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_WAVPACK_DSD)
+        endif()
         if(SDL3MIXER_WAVPACK_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:WavPack::WavPack,INCLUDE_DIRECTORIES>
diff --git a/src/codecs/music_wavpack.c b/src/codecs/music_wavpack.c
index 78f16b65..5bb465f5 100644
--- a/src/codecs/music_wavpack.c
+++ b/src/codecs/music_wavpack.c
@@ -185,8 +185,11 @@ typedef struct {
     WavpackContext *ctx;
     int64_t numsamples;
     uint32_t samplerate;
-    int bps, channels, mode, decimation;
+    int bps, channels, mode;
+    #ifdef MUSIC_WAVPACK_DSD
+    int decimation;
     void *decimation_ctx;
+    #endif
 
     SDL_AudioStream *stream;
     void *buffer;
@@ -287,9 +290,16 @@ static int WAVPACK_Seek(void *context, double time);
 static void WAVPACK_Delete(void *context);
 static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL_bool freesrc, SDL_bool *freesrc2);
 
+#ifdef MUSIC_WAVPACK_DSD
 static void *decimation_init(int num_channels, int ratio);
 static int decimation_run(void *context, int32_t *samples, int num_samples);
 static void decimation_reset(void *context);
+#define FLAGS_DSD OPEN_DSD_AS_PCM
+#define DECIMATION(x) (x)->decimation
+#else
+#define FLAGS_DSD 0
+#define DECIMATION(x) 1
+#endif
 
 static void *WAVPACK_CreateFromRW(SDL_RWops *src, SDL_bool freesrc)
 {
@@ -356,7 +366,7 @@ static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL
     music->volume = MIX_MAX_VOLUME;
 
     music->ctx = (wvpk.WavpackOpenFileInputEx64 != NULL) ?
-                  wvpk.WavpackOpenFileInputEx64(&sdl_reader64, src1, src2, err, OPEN_NORMALIZE|OPEN_TAGS|OPEN_DSD_AS_PCM, 0) :
+                  wvpk.WavpackOpenFileInputEx64(&sdl_reader64, src1, src2, err, OPEN_NORMALIZE|OPEN_TAGS|FLAGS_DSD, 0) :
                   wvpk.WavpackOpenFileInputEx(&sdl_reader32, src1, src2, err, OPEN_NORMALIZE|OPEN_TAGS, 0);
     if (!music->ctx) {
         Mix_SetError("%s", err);
@@ -374,12 +384,13 @@ static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL
     music->bps = wvpk.WavpackGetBytesPerSample(music->ctx) << 3;
     music->channels = wvpk.WavpackGetNumChannels(music->ctx);
     music->mode = wvpk.WavpackGetMode(music->ctx);
-    music->decimation = 1;
 
     if (freesrc2) {
        *freesrc2 = SDL_FALSE; /* WAVPACK_Delete() will free it */
     }
 
+    #ifdef MUSIC_WAVPACK_DSD
+    music->decimation = 1;
     /* for very high sample rates (including DSD, which will normally be 352,800 Hz)
      * decimate 4x here before sending on */
     if (music->samplerate >= 256000) {
@@ -391,6 +402,7 @@ static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL
             return NULL;
         }
     }
+    #endif
 
     #if WAVPACK_DBG
     SDL_Log("WavPack loader:\n numsamples: %" SDL_PRIs64 "\n samplerate: %d\n bitspersample: %d\n channels: %d\n mode: 0x%x\n lossy: %d\n duration: %f\n",
@@ -411,10 +423,9 @@ static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL
         break;
     }
 
-
     srcspec.format = format;
     srcspec.channels = music->channels;
-    srcspec.freq = (int)music->samplerate / music->decimation;
+    srcspec.freq = (int)music->samplerate / DECIMATION(music);
     music->stream = SDL_CreateAudioStream(&srcspec, &music_spec);
     if (!music->stream) {
         WAVPACK_Delete(music);
@@ -422,7 +433,7 @@ static void *WAVPACK_CreateFromRW_internal(SDL_RWops *src1, SDL_RWops *src2, SDL
     }
 
     music->frames = 4096/*music_spec.samples*/;
-    music->buffer = SDL_malloc(music->frames * music->channels * sizeof(int32_t) * music->decimation);
+    music->buffer = SDL_malloc(music->frames * music->channels * sizeof(int32_t) * DECIMATION(music));
     if (!music->buffer) {
         SDL_OutOfMemory();
         WAVPACK_Delete(music);
@@ -509,11 +520,12 @@ static int WAVPACK_GetSome(void *context, void *data, int bytes, SDL_bool *done)
         return 0;
     }
 
-    amount = (int) wvpk.WavpackUnpackSamples(music->ctx, music->buffer, music->frames * music->decimation);
-
+    amount = (int) wvpk.WavpackUnpackSamples(music->ctx, music->buffer, music->frames * DECIMATION(music));
+    #ifdef MUSIC_WAVPACK_DSD
     if (amount && music->decimation_ctx) {
         amount = decimation_run(music->decimation_ctx, music->buffer, amount);
     }
+    #endif
 
     if (amount) {
         int32_t *src = (int32_t *)music->buffer;
@@ -578,9 +590,11 @@ static int WAVPACK_Seek(void *context, double time)
     if (!success) {
         return Mix_SetError("%s", wvpk.WavpackGetErrorMessage(music->ctx));
     }
+    #ifdef MUSIC_WAVPACK_DSD
     if (music->decimation_ctx) {
         decimation_reset(music->decimation_ctx);
     }
+    #endif
     return 0;
 }
 
@@ -610,7 +624,9 @@ static void WAVPACK_Delete(void *context)
         SDL_DestroyAudioStream(music->stream);
     }
     SDL_free(music->buffer);
+    #ifdef MUSIC_WAVPACK_DSD
     SDL_free(music->decimation_ctx);
+    #endif
     if (music->src2) {
         SDL_RWclose(music->src2);
     }
@@ -620,6 +636,7 @@ static void WAVPACK_Delete(void *context)
     SDL_free(music);
 }
 
+#ifdef MUSIC_WAVPACK_DSD
 /* Decimation code for playing DSD (which comes from the library already decimated 8x) */
 /* Code provided by David Bryant. */
 /* sinc low-pass filter, cutoff = fs/12, 80 terms */
@@ -707,6 +724,7 @@ static void decimation_reset(void *context)
         sp[i].ratio = ratio;
     }
 }
+#endif /* MUSIC_WAVPACK_DSD */
 
 Mix_MusicInterface Mix_MusicInterface_WAVPACK =
 {