From f88f27c0daf7e9898f35490b9049dbde443f14d3 Mon Sep 17 00:00:00 2001 From: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Mon, 3 May 2021 20:16:40 +0200 Subject: [PATCH] [WAVEOUT] Dynamic alloc of WAVEHDR (#873) It seems that the addition of multichannel output has broken the WaveOut driver. If you try to run FluidSynth with -a waveout, you will get this message: fluidsynth: audio.periods 8 exceeds internal limit 4 Actually, the default value for period is set to 8, so it will never work unless you change that value before opening the driver. Rather than lowering the default period value or rising the limit of the number of buffers, in my opinion it would be better to free the driver from this limitation, by allocating the needed amount of memory for WAVEHDR too. Attached patch fixes this bug. --- src/drivers/fluid_waveout.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/drivers/fluid_waveout.c b/src/drivers/fluid_waveout.c index 6ccdf970..bae606bb 100644 --- a/src/drivers/fluid_waveout.c +++ b/src/drivers/fluid_waveout.c @@ -32,9 +32,6 @@ #include #include -/* Number of driver buffers in the chain */ -#define NB_SOUND_BUFFERS 4 - /** * The driver handle multiple channels. * Actually the number maximum of channels is limited to 2 * WAVEOUT_MAX_STEREO_CHANNELS. @@ -82,7 +79,7 @@ typedef struct float **drybuf; HWAVEOUT hWaveOut; - WAVEHDR waveHeader[NB_SOUND_BUFFERS]; + WAVEHDR *waveHeader; int periods; /* numbers of internal driver buffers */ int num_frames; @@ -286,13 +283,6 @@ new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t f fluid_settings_getint(settings, "audio.period-size", &period_size); fluid_settings_getint(settings, "synth.audio-channels", &audio_channels); - if(periods > NB_SOUND_BUFFERS) - { - FLUID_LOG(FLUID_INFO, "audio.periods %d exceeds internal limit %d", - periods, NB_SOUND_BUFFERS); - return NULL; - } - /* Clear format structure */ ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE)); @@ -359,13 +349,18 @@ new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t f lenBuffer = wfx.Format.nBlockAlign * period_size; /* create and clear the driver data */ dev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(fluid_waveout_audio_driver_t) + lenBuffer * periods); + sizeof(fluid_waveout_audio_driver_t) + + lenBuffer * periods + + sizeof(WAVEHDR) * periods); if(dev == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } + /* Assign extra memory to WAVEHDR */ + dev->waveHeader = (WAVEHDR *)((uintptr_t)(dev + 1) + lenBuffer * periods); + /* Save copy of synth */ dev->synth = data; dev->func = func;