[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.
This commit is contained in:
Carlo Bramini 2021-05-03 20:16:40 +02:00 committed by GitHub
parent 0ea101721a
commit f88f27c0da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 7 additions and 12 deletions

View File

@ -32,9 +32,6 @@
#include <ks.h> #include <ks.h>
#include <ksmedia.h> #include <ksmedia.h>
/* Number of driver buffers in the chain */
#define NB_SOUND_BUFFERS 4
/** /**
* The driver handle multiple channels. * The driver handle multiple channels.
* Actually the number maximum of channels is limited to 2 * WAVEOUT_MAX_STEREO_CHANNELS. * Actually the number maximum of channels is limited to 2 * WAVEOUT_MAX_STEREO_CHANNELS.
@ -82,7 +79,7 @@ typedef struct
float **drybuf; float **drybuf;
HWAVEOUT hWaveOut; HWAVEOUT hWaveOut;
WAVEHDR waveHeader[NB_SOUND_BUFFERS]; WAVEHDR *waveHeader;
int periods; /* numbers of internal driver buffers */ int periods; /* numbers of internal driver buffers */
int num_frames; 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, "audio.period-size", &period_size);
fluid_settings_getint(settings, "synth.audio-channels", &audio_channels); 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 */ /* Clear format structure */
ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE)); 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; lenBuffer = wfx.Format.nBlockAlign * period_size;
/* create and clear the driver data */ /* create and clear the driver data */
dev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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) if(dev == NULL)
{ {
FLUID_LOG(FLUID_ERR, "Out of memory"); FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL; return NULL;
} }
/* Assign extra memory to WAVEHDR */
dev->waveHeader = (WAVEHDR *)((uintptr_t)(dev + 1) + lenBuffer * periods);
/* Save copy of synth */ /* Save copy of synth */
dev->synth = data; dev->synth = data;
dev->func = func; dev->func = func;