1 /* FluidSynth - A Software Synthesizer
2 *
3 * Copyright (C) 2003 Peter Hanappe and others.
4 * Copyright (C) 2018 Carlo Bramini
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
20 */
21
22 #include "fluid_synth.h"
23 #include "fluid_adriver.h"
24 #include "fluid_settings.h"
25
26 #if WAVEOUT_SUPPORT
27
28 #include <mmsystem.h>
29 #include <mmreg.h>
30
31 /* Those two includes are required on Windows 9x/ME */
32 #include <ks.h>
33 #include <ksmedia.h>
34
35 /**
36 * The driver handle multiple channels.
37 * Actually the number maximum of channels is limited to 2 * WAVEOUT_MAX_STEREO_CHANNELS.
38 * The only reason of this limitation is because we dont know how to define the mapping
39 * of speakers for stereo output number above WAVEOUT_MAX_STEREO_CHANNELS.
40 */
41 /* Maximum number of stereo outputs */
42 #define WAVEOUT_MAX_STEREO_CHANNELS 4
43
44 static char *fluid_waveout_error(MMRESULT hr);
45 static int fluid_waveout_write_processed_channels(fluid_synth_t *data, int len,
46 int channels_count,
47 void *channels_out[], int channels_off[],
48 int channels_incr[]);
49
50 /* Speakers mapping */
51 static const DWORD channel_mask_speakers[WAVEOUT_MAX_STEREO_CHANNELS] =
52 {
53 /* 1 stereo output */
54 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
55
56 /* 2 stereo outputs */
57 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
58 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
59
60 /* 3 stereo outputs */
61 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
62 SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
63 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
64
65 /* 4 stereo outputs */
66 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
67 SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
68 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |
69 SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT
70 };
71
72 typedef struct
73 {
74 fluid_audio_driver_t driver;
75
76 void *synth;
77 fluid_audio_func_t func;
78 fluid_audio_channels_callback_t write_ptr;
79 float **drybuf;
80
81 HWAVEOUT hWaveOut;
82 WAVEHDR *waveHeader;
83
84 int periods; /* numbers of internal driver buffers */
85 int num_frames;
86
87 HANDLE hThread;
88 DWORD dwThread;
89
90 int nQuit;
91 HANDLE hQuit;
92 int channels_count; /* number of channels in audio stream */
93
94 } fluid_waveout_audio_driver_t;
95
96
97 /* Thread for playing sample buffers */
fluid_waveout_synth_thread(void * data)98 static DWORD WINAPI fluid_waveout_synth_thread(void *data)
99 {
100 fluid_waveout_audio_driver_t *dev;
101 WAVEHDR *pWave;
102
103 MSG msg;
104 int code;
105 /* pointers table on output first sample channels */
106 void *channels_out[WAVEOUT_MAX_STEREO_CHANNELS * 2];
107 int channels_off[WAVEOUT_MAX_STEREO_CHANNELS * 2];
108 int channels_incr[WAVEOUT_MAX_STEREO_CHANNELS * 2];
109 int i;
110
111 dev = (fluid_waveout_audio_driver_t *)data;
112
113 /* initialize write callback constant parameters:
114 MME expects interleaved channels in a unique buffer.
115 For example 4 channels (c1, c2, c3, c4) and n samples:
116 { s1:c1, s1:c2, s1:c3, s1:c4, s2:c1, s2:c2, s2:c3, s2:c4,...
117 sn:c1, sn:c2, sn:c3, sn:c4 }.
118
119 So, channels_off[], channnel_incr[] tables should initialized like this:
120 channels_off[0] = 0 channels_incr[0] = 4
121 channels_off[1] = 1 channels_incr[1] = 4
122 channels_off[2] = 2 channels_incr[2] = 4
123 channels_off[3] = 3 channels_incr[3] = 4
124
125 channels_out[], table will be initialized later, just before calling
126 the write callback function.
127 channels_out[0] = address of dsound buffer
128 channels_out[1] = address of dsound buffer
129 channels_out[2] = address of dsound buffer
130 channels_out[3] = address of dsound buffer
131 */
132 for(i = 0; i < dev->channels_count; i++)
133 {
134 channels_off[i] = i;
135 channels_incr[i] = dev->channels_count;
136 }
137
138 /* Forces creation of message queue */
139 PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
140
141 for(;;)
142 {
143 code = GetMessage(&msg, NULL, 0, 0);
144
145 if(code < 0)
146 {
147 FLUID_LOG(FLUID_ERR, "fluid_waveout_synth_thread: GetMessage() failed: '%s'", fluid_get_windows_error());
148 break;
149 }
150
151 if(msg.message == WM_CLOSE)
152 {
153 break;
154 }
155
156 switch(msg.message)
157 {
158 case MM_WOM_DONE:
159 pWave = (WAVEHDR *)msg.lParam;
160 dev = (fluid_waveout_audio_driver_t *)pWave->dwUser;
161
162 if(dev->nQuit > 0)
163 {
164 /* Release the sample buffer */
165 waveOutUnprepareHeader((HWAVEOUT)msg.wParam, pWave, sizeof(WAVEHDR));
166
167 if(--dev->nQuit == 0)
168 {
169 SetEvent(dev->hQuit);
170 }
171 }
172 else
173 {
174 /* Before calling write function, finish to initialize
175 channels_out[] table parameter:
176 MME expects interleaved channels in a unique buffer.
177 So, channels_out[] table must be initialized with the address
178 of the same buffer (lpData).
179 */
180 i = dev->channels_count;
181
182 do
183 {
184 channels_out[--i] = pWave->lpData;
185 }
186 while(i);
187
188 dev->write_ptr(dev->func ? (fluid_synth_t*)dev : dev->synth, dev->num_frames, dev->channels_count,
189 channels_out, channels_off, channels_incr);
190
191 waveOutWrite((HWAVEOUT)msg.wParam, pWave, sizeof(WAVEHDR));
192 }
193
194 break;
195 }
196 }
197
198 return 0;
199 }
200
fluid_waveout_audio_driver_settings(fluid_settings_t * settings)201 void fluid_waveout_audio_driver_settings(fluid_settings_t *settings)
202 {
203 UINT n, nDevs = waveOutGetNumDevs();
204 #ifdef _UNICODE
205 char dev_name[MAXPNAMELEN];
206 #endif
207
208 fluid_settings_register_str(settings, "audio.waveout.device", "default", 0);
209 fluid_settings_add_option(settings, "audio.waveout.device", "default");
210
211 for(n = 0; n < nDevs; n++)
212 {
213 WAVEOUTCAPS caps;
214 MMRESULT res;
215
216 res = waveOutGetDevCaps(n, &caps, sizeof(caps));
217
218 if(res == MMSYSERR_NOERROR)
219 {
220 #ifdef _UNICODE
221 WideCharToMultiByte(CP_UTF8, 0, caps.szPname, -1, dev_name, MAXPNAMELEN, 0, 0);
222 FLUID_LOG(FLUID_DBG, "Testing audio device: %s", dev_name);
223 fluid_settings_add_option(settings, "audio.waveout.device", dev_name);
224 #else
225 FLUID_LOG(FLUID_DBG, "Testing audio device: %s", caps.szPname);
226 fluid_settings_add_option(settings, "audio.waveout.device", caps.szPname);
227 #endif
228 }
229 }
230 }
231
232
233 /*
234 * new_fluid_waveout_audio_driver
235 * The driver handle the case of multiple stereo buffers provided by fluidsynth
236 * mixer.
237 * Each stereo buffers (left, right) are written to respective channels pair
238 * of the audio device card.
239 * For example, if the number of internal mixer buffer is 2, the audio device
240 * must have at least 4 channels:
241 * - buffer 0 (left, right) will be written to channel pair (0, 1).
242 * - buffer 1 (left, right) will be written to channel pair (2, 3).
243 *
244 * @param setting. The settings the driver looks for:
245 * "synth.sample-rate", the sample rate.
246 * "synth.audio-channels", the number of internal mixer stereo buffer.
247 * "audio.periods",the number of buffers.
248 * "audio.period-size",the size of one buffer.
249 * "audio.sample-format",the sample format, 16bits or float.
250 *
251 * @param synth, fluidsynth synth instance to associate to the driver.
252 *
253 * Note: The number of internal mixer stereo buffer is indicated by "synth.audio-channels".
254 * If the audio device cannot handle the format or do not have enough channels,
255 * the driver fails and return NULL.
256 */
257 fluid_audio_driver_t *
new_fluid_waveout_audio_driver(fluid_settings_t * settings,fluid_synth_t * synth)258 new_fluid_waveout_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
259 {
260 return new_fluid_waveout_audio_driver2(settings, NULL, synth);
261 }
262
263 fluid_audio_driver_t *
new_fluid_waveout_audio_driver2(fluid_settings_t * settings,fluid_audio_func_t func,void * data)264 new_fluid_waveout_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
265 {
266 fluid_waveout_audio_driver_t *dev = NULL;
267 fluid_audio_channels_callback_t write_ptr;
268 double sample_rate;
269 int frequency, sample_size;
270 int periods, period_size;
271 int audio_channels;
272 LPSTR ptrBuffer;
273 int lenBuffer;
274 int device;
275 int i;
276 WAVEFORMATEXTENSIBLE wfx;
277 char dev_name[MAXPNAMELEN];
278 MMRESULT errCode;
279
280 /* Retrieve the settings */
281 fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
282 fluid_settings_getint(settings, "audio.periods", &periods);
283 fluid_settings_getint(settings, "audio.period-size", &period_size);
284 fluid_settings_getint(settings, "synth.audio-channels", &audio_channels);
285
286 /* Clear format structure */
287 ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE));
288
289 /* check the format */
290 if(fluid_settings_str_equal(settings, "audio.sample-format", "float") || func)
291 {
292 FLUID_LOG(FLUID_DBG, "Selected 32 bit sample format");
293
294 sample_size = sizeof(float);
295 write_ptr = func ? fluid_waveout_write_processed_channels : fluid_synth_write_float_channels;
296 wfx.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
297 wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
298 }
299 else if(fluid_settings_str_equal(settings, "audio.sample-format", "16bits"))
300 {
301 FLUID_LOG(FLUID_DBG, "Selected 16 bit sample format");
302
303 sample_size = sizeof(short);
304 write_ptr = fluid_synth_write_s16_channels;
305 wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
306 wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
307 }
308 else
309 {
310 FLUID_LOG(FLUID_ERR, "Unhandled sample format");
311 return NULL;
312 }
313
314 /* Set frequency to integer */
315 frequency = (int)sample_rate;
316
317 /* Initialize the format structure */
318 wfx.Format.nChannels = audio_channels * 2;
319
320 if(audio_channels > WAVEOUT_MAX_STEREO_CHANNELS)
321 {
322 FLUID_LOG(FLUID_ERR, "Channels number %d exceed internal limit %d",
323 wfx.Format.nChannels, WAVEOUT_MAX_STEREO_CHANNELS * 2);
324 return NULL;
325 }
326
327 wfx.Format.wBitsPerSample = sample_size * 8;
328 wfx.Format.nBlockAlign = sample_size * wfx.Format.nChannels;
329 wfx.Format.nSamplesPerSec = frequency;
330 wfx.Format.nAvgBytesPerSec = frequency * wfx.Format.nBlockAlign;
331 /* WAVEFORMATEXTENSIBLE extension is used only when channels number
332 is above 2.
333 When channels number is below 2, only WAVEFORMATEX structure
334 will be used by the Windows driver. This ensures compatibility with
335 Windows 9X/NT in the case these versions does not accept the
336 WAVEFORMATEXTENSIBLE structure.
337 */
338 if(wfx.Format.nChannels > 2)
339 {
340 wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
341 wfx.Format.cbSize = 22;
342 wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
343 wfx.dwChannelMask = channel_mask_speakers[audio_channels - 1];
344 }
345
346 /* allocate the internal waveout buffers:
347 The length of a single buffer in bytes is dependent of period_size.
348 */
349 lenBuffer = wfx.Format.nBlockAlign * period_size;
350 /* create and clear the driver data */
351 dev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
352 sizeof(fluid_waveout_audio_driver_t) +
353 lenBuffer * periods +
354 sizeof(WAVEHDR) * periods);
355 if(dev == NULL)
356 {
357 FLUID_LOG(FLUID_ERR, "Out of memory");
358 return NULL;
359 }
360
361 /* Assign extra memory to WAVEHDR */
362 dev->waveHeader = (WAVEHDR *)((uintptr_t)(dev + 1) + lenBuffer * periods);
363
364 /* Save copy of synth */
365 dev->synth = data;
366 dev->func = func;
367
368 /* Save copy of other variables */
369 dev->write_ptr = write_ptr;
370 /* number of frames in a buffer */
371 dev->num_frames = period_size;
372 /* number of buffers */
373 dev->periods = periods;
374 dev->channels_count = wfx.Format.nChannels;
375
376 /* Set default device to use */
377 device = WAVE_MAPPER;
378
379 if(func)
380 {
381 /* allocate extra buffer used by fluid_waveout_write_processed_channels().
382 These buffers are buffer adaptation between the rendering
383 API fluid_synth_process() and the waveout internal buffers
384 Note: the size (in bytes) of these extra buffer (drybuf[]) must be the
385 same that the size of internal waveout buffers.
386 */
387 dev->drybuf = FLUID_ARRAY(float*, audio_channels * 2);
388 if(dev->drybuf == NULL)
389 {
390 FLUID_LOG(FLUID_ERR, "Out of memory");
391 delete_fluid_waveout_audio_driver(&dev->driver);
392 return NULL;
393 }
394 FLUID_MEMSET(dev->drybuf, 0, sizeof(float*) * audio_channels * 2);
395 for(i = 0; i < audio_channels * 2; ++i)
396 {
397 /* The length of a single buffer drybuf[i] is dependent of period_size */
398 dev->drybuf[i] = FLUID_ARRAY(float, period_size);
399 if(dev->drybuf[i] == NULL)
400 {
401 FLUID_LOG(FLUID_ERR, "Out of memory");
402 delete_fluid_waveout_audio_driver(&dev->driver);
403 return NULL;
404 }
405 }
406 }
407
408 /* get the selected device name. if none is specified, use default device. */
409 if(fluid_settings_copystr(settings, "audio.waveout.device", dev_name, MAXPNAMELEN) == FLUID_OK
410 && dev_name[0] != '\0')
411 {
412 UINT nDevs = waveOutGetNumDevs();
413 UINT n;
414 #ifdef _UNICODE
415 WCHAR lpwDevName[MAXPNAMELEN];
416
417 MultiByteToWideChar(CP_UTF8, 0, dev_name, -1, lpwDevName, MAXPNAMELEN);
418 #endif
419
420 for(n = 0; n < nDevs; n++)
421 {
422 WAVEOUTCAPS caps;
423 MMRESULT res;
424
425 res = waveOutGetDevCaps(n, &caps, sizeof(caps));
426
427 if(res == MMSYSERR_NOERROR)
428 {
429 #ifdef _UNICODE
430
431 if(wcsicmp(lpwDevName, caps.szPname) == 0)
432 #else
433 if(FLUID_STRCASECMP(dev_name, caps.szPname) == 0)
434 #endif
435 {
436 FLUID_LOG(FLUID_DBG, "Selected audio device GUID: %s", dev_name);
437 device = n;
438 break;
439 }
440 }
441 }
442 }
443
444 do
445 {
446
447 dev->hQuit = CreateEvent(NULL, FALSE, FALSE, NULL);
448
449 if(dev->hQuit == NULL)
450 {
451 FLUID_LOG(FLUID_ERR, "Failed to create quit event: '%s'", fluid_get_windows_error());
452 break;
453 }
454
455 /* Create thread which processes re-adding SYSEX buffers */
456 dev->hThread = CreateThread(
457 NULL,
458 0,
459 (LPTHREAD_START_ROUTINE)
460 fluid_waveout_synth_thread,
461 dev,
462 0,
463 &dev->dwThread);
464
465 if(dev->hThread == NULL)
466 {
467 FLUID_LOG(FLUID_ERR, "Failed to create waveOut thread: '%s'", fluid_get_windows_error());
468 break;
469 }
470
471 errCode = waveOutOpen(&dev->hWaveOut,
472 device,
473 (WAVEFORMATEX *)&wfx,
474 (DWORD_PTR)dev->dwThread,
475 0,
476 CALLBACK_THREAD);
477
478 if(errCode != MMSYSERR_NOERROR)
479 {
480 FLUID_LOG(FLUID_ERR, "Failed to open waveOut device: '%s'", fluid_waveout_error(errCode));
481 break;
482 }
483
484 /* Get pointer to sound buffer memory */
485 ptrBuffer = (LPSTR)(dev + 1);
486
487 /* Setup the sample buffers */
488 for(i = 0; i < periods; i++)
489 {
490 /* Clear the sample buffer */
491 memset(ptrBuffer, 0, lenBuffer);
492
493 /* Clear descriptor buffer */
494 memset(dev->waveHeader + i, 0, sizeof(WAVEHDR));
495
496 /* Compile descriptor buffer */
497 dev->waveHeader[i].lpData = ptrBuffer;
498 dev->waveHeader[i].dwBufferLength = lenBuffer;
499 dev->waveHeader[i].dwUser = (DWORD_PTR)dev;
500
501 waveOutPrepareHeader(dev->hWaveOut, &dev->waveHeader[i], sizeof(WAVEHDR));
502
503 ptrBuffer += lenBuffer;
504 }
505
506 /* Play the sample buffers */
507 for(i = 0; i < periods; i++)
508 {
509 waveOutWrite(dev->hWaveOut, &dev->waveHeader[i], sizeof(WAVEHDR));
510 }
511
512 return (fluid_audio_driver_t *) dev;
513
514 }
515 while(0);
516
517 delete_fluid_waveout_audio_driver(&dev->driver);
518 return NULL;
519 }
520
521
delete_fluid_waveout_audio_driver(fluid_audio_driver_t * d)522 void delete_fluid_waveout_audio_driver(fluid_audio_driver_t *d)
523 {
524 int i;
525
526 fluid_waveout_audio_driver_t *dev = (fluid_waveout_audio_driver_t *) d;
527 fluid_return_if_fail(dev != NULL);
528
529 /* release all the allocated resources */
530 if(dev->hWaveOut != NULL)
531 {
532 dev->nQuit = dev->periods;
533 WaitForSingleObject(dev->hQuit, INFINITE);
534
535 waveOutClose(dev->hWaveOut);
536 }
537
538 if(dev->hThread != NULL)
539 {
540 PostThreadMessage(dev->dwThread, WM_CLOSE, 0, 0);
541 WaitForSingleObject(dev->hThread, INFINITE);
542
543 CloseHandle(dev->hThread);
544 }
545
546 if(dev->hQuit != NULL)
547 {
548 CloseHandle(dev->hQuit);
549 }
550
551 if(dev->drybuf != NULL)
552 {
553 for(i = 0; i < dev->channels_count; ++i)
554 {
555 FLUID_FREE(dev->drybuf[i]);
556 }
557 }
558
559 FLUID_FREE(dev->drybuf);
560
561 HeapFree(GetProcessHeap(), 0, dev);
562 }
563
fluid_waveout_write_processed_channels(fluid_synth_t * data,int len,int channels_count,void * channels_out[],int channels_off[],int channels_incr[])564 static int fluid_waveout_write_processed_channels(fluid_synth_t *data, int len,
565 int channels_count,
566 void *channels_out[], int channels_off[],
567 int channels_incr[])
568 {
569 int i, ch;
570 int ret;
571 fluid_waveout_audio_driver_t *drv = (fluid_waveout_audio_driver_t*) data;
572 float *optr[WAVEOUT_MAX_STEREO_CHANNELS * 2];
573 for(ch = 0; ch < drv->channels_count; ++ch)
574 {
575 FLUID_MEMSET(drv->drybuf[ch], 0, len * sizeof(float));
576 optr[ch] = (float*)channels_out[ch] + channels_off[ch];
577 }
578 ret = drv->func(drv->synth, len, 0, NULL, drv->channels_count, drv->drybuf);
579 for(ch = 0; ch < drv->channels_count; ++ch)
580 {
581 for(i = 0; i < len; ++i)
582 {
583 *optr[ch] = drv->drybuf[ch][i];
584 optr[ch] += channels_incr[ch];
585 }
586 }
587 return ret;
588 }
589
fluid_waveout_error(MMRESULT hr)590 static char *fluid_waveout_error(MMRESULT hr)
591 {
592 char *s = "Don't know why";
593
594 switch(hr)
595 {
596 case MMSYSERR_NOERROR:
597 s = "The operation completed successfully :)";
598 break;
599
600 case MMSYSERR_ALLOCATED:
601 s = "Specified resource is already allocated.";
602 break;
603
604 case MMSYSERR_BADDEVICEID:
605 s = "Specified device identifier is out of range";
606 break;
607
608 case MMSYSERR_NODRIVER:
609 s = "No device driver is present";
610 break;
611
612 case MMSYSERR_NOMEM:
613 s = "Unable to allocate or lock memory";
614 break;
615
616 case WAVERR_BADFORMAT:
617 s = "Attempted to open with an unsupported waveform-audio format";
618 break;
619
620 case WAVERR_SYNC:
621 s = "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag";
622 break;
623 }
624
625 return s;
626 }
627
628 #endif /* WAVEOUT_SUPPORT */
629