mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 06:51:54 +00:00
Merge pull request #745 from chirs241097/winadrv-cb
Add support for new_fluid_audio_driver2 to dsound and waveout drivers.
This commit is contained in:
commit
1fefa4d2f2
4 changed files with 222 additions and 37 deletions
|
@ -114,7 +114,7 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] =
|
|||
{
|
||||
"dsound",
|
||||
new_fluid_dsound_audio_driver,
|
||||
NULL,
|
||||
new_fluid_dsound_audio_driver2,
|
||||
delete_fluid_dsound_audio_driver,
|
||||
fluid_dsound_audio_driver_settings
|
||||
},
|
||||
|
@ -124,7 +124,7 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] =
|
|||
{
|
||||
"waveout",
|
||||
new_fluid_waveout_audio_driver,
|
||||
NULL,
|
||||
new_fluid_waveout_audio_driver2,
|
||||
delete_fluid_waveout_audio_driver,
|
||||
fluid_waveout_audio_driver_settings
|
||||
},
|
||||
|
|
|
@ -95,6 +95,9 @@ void fluid_core_audio_driver_settings(fluid_settings_t *settings);
|
|||
#if DSOUND_SUPPORT
|
||||
fluid_audio_driver_t *new_fluid_dsound_audio_driver(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth);
|
||||
fluid_audio_driver_t *new_fluid_dsound_audio_driver2(fluid_settings_t *settings,
|
||||
fluid_audio_func_t func,
|
||||
void *data);
|
||||
void delete_fluid_dsound_audio_driver(fluid_audio_driver_t *p);
|
||||
void fluid_dsound_audio_driver_settings(fluid_settings_t *settings);
|
||||
#endif
|
||||
|
@ -102,6 +105,9 @@ void fluid_dsound_audio_driver_settings(fluid_settings_t *settings);
|
|||
#if WAVEOUT_SUPPORT
|
||||
fluid_audio_driver_t *new_fluid_waveout_audio_driver(fluid_settings_t *settings,
|
||||
fluid_synth_t *synth);
|
||||
fluid_audio_driver_t *new_fluid_waveout_audio_driver2(fluid_settings_t *settings,
|
||||
fluid_audio_func_t func,
|
||||
void *data);
|
||||
void delete_fluid_waveout_audio_driver(fluid_audio_driver_t *p);
|
||||
void fluid_waveout_audio_driver_settings(fluid_settings_t *settings);
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
#include <ksmedia.h>
|
||||
|
||||
static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter);
|
||||
static int fluid_dsound_write_processed_channels(fluid_synth_t *data, int len,
|
||||
int channels_count,
|
||||
void *channels_out[], int channels_off[],
|
||||
int channels_incr[]);
|
||||
|
||||
static char *fluid_win32_error(HRESULT hr);
|
||||
|
||||
|
@ -84,10 +88,12 @@ typedef struct
|
|||
|
||||
HANDLE thread; /* driver task */
|
||||
DWORD threadID;
|
||||
fluid_synth_t *synth; /* fluidsynth instance */
|
||||
void *synth; /* fluidsynth instance, or user pointer if custom processing function is defined */
|
||||
fluid_audio_func_t func;
|
||||
/* callback called by the task for audio rendering in dsound buffers */
|
||||
fluid_audio_channels_callback_t write;
|
||||
HANDLE quit_ev; /* Event object to request the audio task to stop */
|
||||
float **drybuf;
|
||||
|
||||
int bytes_per_second; /* number of bytes per second */
|
||||
DWORD buffer_byte_size; /* size of one buffer in bytes */
|
||||
|
@ -177,6 +183,12 @@ void fluid_dsound_audio_driver_settings(fluid_settings_t *settings)
|
|||
*/
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_dsound_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
||||
{
|
||||
return new_fluid_dsound_audio_driver2(settings, (fluid_audio_func_t)fluid_synth_process, synth);
|
||||
}
|
||||
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_dsound_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
|
||||
{
|
||||
HRESULT hr;
|
||||
DSBUFFERDESC desc;
|
||||
|
@ -186,6 +198,8 @@ new_fluid_dsound_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
DWORD bytes1;
|
||||
double sample_rate;
|
||||
int periods, period_size;
|
||||
int audio_channels;
|
||||
int i;
|
||||
fluid_dsound_devsel_t devsel;
|
||||
WAVEFORMATEXTENSIBLE format;
|
||||
|
||||
|
@ -199,47 +213,81 @@ new_fluid_dsound_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
}
|
||||
|
||||
FLUID_MEMSET(dev, 0, sizeof(fluid_dsound_audio_driver_t));
|
||||
dev->synth = synth;
|
||||
dev->synth = data;
|
||||
dev->func = func;
|
||||
|
||||
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
|
||||
fluid_settings_getint(settings, "audio.periods", &periods);
|
||||
fluid_settings_getint(settings, "audio.period-size", &period_size);
|
||||
fluid_settings_getint(settings, "synth.audio-channels", &audio_channels);
|
||||
|
||||
/* Clear format structure*/
|
||||
ZeroMemory(&format, sizeof(WAVEFORMATEXTENSIBLE));
|
||||
|
||||
/* Set this early so that if buffer allocation failed we can free the memory */
|
||||
dev->channels_count = audio_channels * 2;
|
||||
|
||||
/* check the format */
|
||||
if(fluid_settings_str_equal(settings, "audio.sample-format", "float"))
|
||||
if(!func)
|
||||
{
|
||||
if(fluid_settings_str_equal(settings, "audio.sample-format", "float"))
|
||||
{
|
||||
GUID guid_float = {DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT)};
|
||||
FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format");
|
||||
dev->write = fluid_synth_write_float_channels;
|
||||
/* sample container size in bits: 32 bits */
|
||||
format.Format.wBitsPerSample = 8 * sizeof(float);
|
||||
format.SubFormat = guid_float;
|
||||
format.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
}
|
||||
else if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits"))
|
||||
{
|
||||
GUID guid_pcm = {DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_PCM)};
|
||||
FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format");
|
||||
dev->write = fluid_synth_write_s16_channels;
|
||||
/* sample container size in bits: 16bits */
|
||||
format.Format.wBitsPerSample = 8 * sizeof(short);
|
||||
format.SubFormat = guid_pcm;
|
||||
format.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
}
|
||||
else
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Unhandled sample format");
|
||||
goto error_recovery;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUID guid_float = {DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT)};
|
||||
FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format");
|
||||
dev->write = fluid_synth_write_float_channels;
|
||||
dev->write = fluid_dsound_write_processed_channels;
|
||||
/* sample container size in bits: 32 bits */
|
||||
format.Format.wBitsPerSample = 8 * sizeof(float);
|
||||
format.SubFormat = guid_float;
|
||||
format.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
}
|
||||
else if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits"))
|
||||
{
|
||||
GUID guid_pcm = {DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_PCM)};
|
||||
FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format");
|
||||
dev->write = fluid_synth_write_s16_channels;
|
||||
/* sample container size in bits: 16bits */
|
||||
format.Format.wBitsPerSample = 8 * sizeof(short);
|
||||
format.SubFormat = guid_pcm;
|
||||
format.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
}
|
||||
else
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Unhandled sample format");
|
||||
goto error_recovery;
|
||||
dev->drybuf = FLUID_ARRAY(float*, audio_channels * 2);
|
||||
if(dev->drybuf == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
FLUID_MEMSET(dev->drybuf, 0, sizeof(float*) * audio_channels * 2);
|
||||
for(i = 0; i < audio_channels * 2; ++i)
|
||||
{
|
||||
dev->drybuf[i] = FLUID_ARRAY(float, periods * period_size);
|
||||
if(dev->drybuf[i] == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish to initialize the format structure */
|
||||
/* number of channels in a frame */
|
||||
format.Format.nChannels = synth->audio_channels * 2;
|
||||
format.Format.nChannels = audio_channels * 2;
|
||||
|
||||
if(synth->audio_channels > DSOUND_MAX_STEREO_CHANNELS)
|
||||
if(audio_channels > DSOUND_MAX_STEREO_CHANNELS)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Channels number %d exceed internal limit %d",
|
||||
format.Format.nChannels, DSOUND_MAX_STEREO_CHANNELS * 2);
|
||||
|
@ -261,7 +309,7 @@ new_fluid_dsound_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
/* CreateSoundBuffer accepts only format.dwChannelMask compatible with
|
||||
format.Format.nChannels
|
||||
*/
|
||||
format.dwChannelMask = channel_mask_speakers[synth->audio_channels - 1];
|
||||
format.dwChannelMask = channel_mask_speakers[audio_channels - 1];
|
||||
}
|
||||
|
||||
/* Finish to initialize dev structure */
|
||||
|
@ -269,7 +317,6 @@ new_fluid_dsound_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
dev->buffer_byte_size = period_size * dev->frame_size;
|
||||
dev->queue_byte_size = periods * dev->buffer_byte_size;
|
||||
dev->bytes_per_second = format.Format.nAvgBytesPerSec;
|
||||
dev->channels_count = format.Format.nChannels;
|
||||
|
||||
devsel.devGUID = NULL;
|
||||
|
||||
|
@ -416,6 +463,8 @@ error_recovery:
|
|||
|
||||
void delete_fluid_dsound_audio_driver(fluid_audio_driver_t *d)
|
||||
{
|
||||
int i;
|
||||
|
||||
fluid_dsound_audio_driver_t *dev = (fluid_dsound_audio_driver_t *) d;
|
||||
fluid_return_if_fail(dev != NULL);
|
||||
|
||||
|
@ -470,6 +519,16 @@ void delete_fluid_dsound_audio_driver(fluid_audio_driver_t *d)
|
|||
IDirectSound_Release(dev->direct_sound);
|
||||
}
|
||||
|
||||
if(dev->func)
|
||||
{
|
||||
for(i = 0; i < dev->channels_count; ++i)
|
||||
{
|
||||
FLUID_FREE(dev->drybuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
FLUID_FREE(dev->drybuf);
|
||||
|
||||
FLUID_FREE(dev);
|
||||
}
|
||||
|
||||
|
@ -568,8 +627,16 @@ static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter)
|
|||
while(i);
|
||||
|
||||
/* calling write function */
|
||||
dev->write(dev->synth, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
if(dev->func == NULL)
|
||||
{
|
||||
dev->write(dev->synth, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->write((fluid_synth_t*)dev, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
}
|
||||
cur_position += frames * dev->frame_size;
|
||||
}
|
||||
|
||||
|
@ -592,8 +659,16 @@ static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter)
|
|||
while(i);
|
||||
|
||||
/* calling write function */
|
||||
dev->write(dev->synth, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
if(dev->func == NULL)
|
||||
{
|
||||
dev->write(dev->synth, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->write((fluid_synth_t*)dev, frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
}
|
||||
cur_position += frames * dev->frame_size;
|
||||
}
|
||||
|
||||
|
@ -629,6 +704,32 @@ static DWORD WINAPI fluid_dsound_audio_run(LPVOID lpParameter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fluid_dsound_write_processed_channels(fluid_synth_t *data, int len,
|
||||
int channels_count,
|
||||
void *channels_out[], int channels_off[],
|
||||
int channels_incr[])
|
||||
{
|
||||
int i, ch;
|
||||
int ret;
|
||||
fluid_dsound_audio_driver_t *drv = (fluid_dsound_audio_driver_t*) data;
|
||||
float *optr[DSOUND_MAX_STEREO_CHANNELS * 2];
|
||||
for(ch = 0; ch < drv->channels_count; ++ch)
|
||||
{
|
||||
FLUID_MEMSET(drv->drybuf[ch], 0, len * sizeof(float));
|
||||
optr[ch] = (float*)channels_out[ch] + channels_off[ch];
|
||||
}
|
||||
ret = drv->func(drv->synth, len, 0, NULL, drv->channels_count, drv->drybuf);
|
||||
for(ch = 0; ch < drv->channels_count; ++ch)
|
||||
{
|
||||
for(i = 0; i < len; ++i)
|
||||
{
|
||||
*optr[ch] = drv->drybuf[ch][i];
|
||||
optr[ch] += channels_incr[ch];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static char *fluid_win32_error(HRESULT hr)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
#define WAVEOUT_MAX_STEREO_CHANNELS 4
|
||||
|
||||
static char *fluid_waveout_error(MMRESULT hr);
|
||||
static int fluid_waveout_write_processed_channels(fluid_synth_t *data, int len,
|
||||
int channels_count,
|
||||
void *channels_out[], int channels_off[],
|
||||
int channels_incr[]);
|
||||
|
||||
/* speakers mapping */
|
||||
const static DWORD channel_mask_speakers[WAVEOUT_MAX_STEREO_CHANNELS] =
|
||||
|
@ -81,8 +85,10 @@ typedef struct
|
|||
{
|
||||
fluid_audio_driver_t driver;
|
||||
|
||||
fluid_synth_t *synth;
|
||||
void *synth;
|
||||
fluid_audio_func_t func;
|
||||
fluid_audio_channels_callback_t write_ptr;
|
||||
float **drybuf;
|
||||
|
||||
HWAVEOUT hWaveOut;
|
||||
WAVEHDR waveHeader[NB_SOUND_BUFFERS];
|
||||
|
@ -191,7 +197,7 @@ static DWORD WINAPI fluid_waveout_synth_thread(void *data)
|
|||
}
|
||||
while(i);
|
||||
|
||||
dev->write_ptr(dev->synth, dev->num_frames, dev->channels_count,
|
||||
dev->write_ptr(dev->func ? (fluid_synth_t*)dev : dev->synth, dev->num_frames, dev->channels_count,
|
||||
channels_out, channels_off, channels_incr);
|
||||
|
||||
waveOutWrite((HWAVEOUT)msg.wParam, pWave, sizeof(WAVEHDR));
|
||||
|
@ -259,11 +265,19 @@ void fluid_waveout_audio_driver_settings(fluid_settings_t *settings)
|
|||
*/
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
||||
{
|
||||
return new_fluid_waveout_audio_driver2(settings, (fluid_audio_func_t)fluid_synth_process, synth);
|
||||
}
|
||||
|
||||
fluid_audio_driver_t *
|
||||
new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
|
||||
{
|
||||
fluid_waveout_audio_driver_t *dev = NULL;
|
||||
fluid_audio_channels_callback_t write_ptr;
|
||||
double sample_rate;
|
||||
int frequency, sample_size;
|
||||
int periods, period_size;
|
||||
int audio_channels;
|
||||
LPSTR ptrBuffer;
|
||||
int lenBuffer;
|
||||
int device;
|
||||
|
@ -274,18 +288,21 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
|
||||
/* Retrieve the settings */
|
||||
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
|
||||
fluid_settings_getint(settings, "audio.periods", &periods);
|
||||
fluid_settings_getint(settings, "audio.period-size", &period_size);
|
||||
fluid_settings_getint(settings, "synth.audio-channels", &audio_channels);
|
||||
|
||||
/* Clear format structure */
|
||||
ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE));
|
||||
|
||||
/* check the format */
|
||||
if(fluid_settings_str_equal(settings, "audio.sample-format", "float"))
|
||||
if(fluid_settings_str_equal(settings, "audio.sample-format", "float") || func)
|
||||
{
|
||||
GUID guid_float = {DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT)};
|
||||
FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format");
|
||||
|
||||
sample_size = sizeof(float);
|
||||
write_ptr = fluid_synth_write_float_channels;
|
||||
write_ptr = func ? fluid_waveout_write_processed_channels : fluid_synth_write_float_channels;
|
||||
wfx.SubFormat = guid_float;
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
}
|
||||
|
@ -309,9 +326,9 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
frequency = (int)sample_rate;
|
||||
|
||||
/* Initialize the format structure */
|
||||
wfx.Format.nChannels = synth->audio_channels * 2;
|
||||
wfx.Format.nChannels = audio_channels * 2;
|
||||
|
||||
if(synth->audio_channels > WAVEOUT_MAX_STEREO_CHANNELS)
|
||||
if(audio_channels > WAVEOUT_MAX_STEREO_CHANNELS)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Channels number %d exceed internal limit %d",
|
||||
wfx.Format.nChannels, WAVEOUT_MAX_STEREO_CHANNELS * 2);
|
||||
|
@ -335,7 +352,7 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
wfx.Format.cbSize = 22;
|
||||
wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
|
||||
wfx.dwChannelMask = channel_mask_speakers[synth->audio_channels - 1];
|
||||
wfx.dwChannelMask = channel_mask_speakers[audio_channels - 1];
|
||||
}
|
||||
|
||||
/* Calculate the length of a single buffer */
|
||||
|
@ -353,7 +370,8 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
}
|
||||
|
||||
/* Save copy of synth */
|
||||
dev->synth = synth;
|
||||
dev->synth = data;
|
||||
dev->func = func;
|
||||
|
||||
/* Save copy of other variables */
|
||||
dev->write_ptr = write_ptr;
|
||||
|
@ -366,6 +384,28 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
/* Set default device to use */
|
||||
device = WAVE_MAPPER;
|
||||
|
||||
if(func)
|
||||
{
|
||||
dev->drybuf = FLUID_ARRAY(float*, audio_channels * 2);
|
||||
if(dev->drybuf == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
delete_fluid_waveout_audio_driver(&dev->driver);
|
||||
return NULL;
|
||||
}
|
||||
FLUID_MEMSET(dev->drybuf, 0, sizeof(float*) * audio_channels * 2);
|
||||
for(i = 0; i < audio_channels * 2; ++i)
|
||||
{
|
||||
dev->drybuf[i] = FLUID_ARRAY(float, periods * period_size);
|
||||
if(dev->drybuf[i] == NULL)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
delete_fluid_waveout_audio_driver(&dev->driver);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get the selected device name. if none is specified, use default device. */
|
||||
if(fluid_settings_copystr(settings, "audio.waveout.device", dev_name, MAXPNAMELEN) == FLUID_OK
|
||||
&& dev_name[0] != '\0')
|
||||
|
@ -482,6 +522,8 @@ new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
|||
|
||||
void delete_fluid_waveout_audio_driver(fluid_audio_driver_t *d)
|
||||
{
|
||||
int i;
|
||||
|
||||
fluid_waveout_audio_driver_t *dev = (fluid_waveout_audio_driver_t *) d;
|
||||
fluid_return_if_fail(dev != NULL);
|
||||
|
||||
|
@ -507,9 +549,45 @@ void delete_fluid_waveout_audio_driver(fluid_audio_driver_t *d)
|
|||
CloseHandle(dev->hQuit);
|
||||
}
|
||||
|
||||
if(dev->func)
|
||||
{
|
||||
for(i = 0; i < dev->channels_count; ++i)
|
||||
{
|
||||
FLUID_FREE(dev->drybuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
FLUID_FREE(dev->drybuf);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, dev);
|
||||
}
|
||||
|
||||
static int fluid_waveout_write_processed_channels(fluid_synth_t *data, int len,
|
||||
int channels_count,
|
||||
void *channels_out[], int channels_off[],
|
||||
int channels_incr[])
|
||||
{
|
||||
int i, ch;
|
||||
int ret;
|
||||
fluid_waveout_audio_driver_t *drv = (fluid_waveout_audio_driver_t*) data;
|
||||
float *optr[WAVEOUT_MAX_STEREO_CHANNELS * 2];
|
||||
for(ch = 0; ch < drv->channels_count; ++ch)
|
||||
{
|
||||
FLUID_MEMSET(drv->drybuf[ch], 0, len * sizeof(float));
|
||||
optr[ch] = (float*)channels_out[ch] + channels_off[ch];
|
||||
}
|
||||
ret = drv->func(drv->synth, len, 0, NULL, drv->channels_count, drv->drybuf);
|
||||
for(ch = 0; ch < drv->channels_count; ++ch)
|
||||
{
|
||||
for(i = 0; i < len; ++i)
|
||||
{
|
||||
*optr[ch] = drv->drybuf[ch][i];
|
||||
optr[ch] += channels_incr[ch];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *fluid_waveout_error(MMRESULT hr)
|
||||
{
|
||||
char *s = "Don't know why";
|
||||
|
|
Loading…
Reference in a new issue