1 /***********************************************************************
2  * ������ɽ��Ͻ��� (�����ƥ��¸)
3  *
4  *      �ܺ٤ϡ� snddrv.h / mame-quasi88.h ����
5  ************************************************************************/
6 
7 #include "quasi88.h"
8 #include "device.h"
9 
10 #include "snddrv.h"
11 
12 #ifdef	USE_SOUND
13 
14 #include "mame-quasi88.h"
15 
16 	int g_pcm_bufsize = 100;	/* PCM �Хåե������� [ms] */
17 static	int use_audiodevice = 1;	/* use audio-devide for audio output */
18 
19 static int device_opened = FALSE;	/* �ǥХ���������Ѥߤʤ鿿 */
20 
21 /*===========================================================================*/
22 /*              QUASI88 ����ƤӽФ���롢MAME �ν����ؿ�                    */
23 /*===========================================================================*/
24 
25 /******************************************************************************
26  * ������ɷϥ��ץ��������ν��������λ�ؿ�
27  *
28  * int xmame_config_init(void)
29  *      config_init() ��ꡢ���ץ����β��Ϥ��Ϥ������˸ƤӽФ���롣
30  *      MAME��¸����ν�����ʤɤ�ɬ�פʾ��ϡ������ǹԤ���
31  *
32  * void xmame_config_exit(void)
33  *      config_exit() ��ꡢ�����κǸ�˸ƤӽФ���롣
34  *      xmame_config_init() �ν����θ����դ���ɬ�פʤ顢�����ǹԤ���
35  *
36  *****************************************************************************/
xmame_config_init(void)37 int	xmame_config_init(void)
38 {
39     return 0;		/*OSD_OK;*/
40 }
xmame_config_exit(void)41 void	xmame_config_exit(void)
42 {
43 }
44 
45 
46 /******************************************************************************
47  * ������ɷϥ��ץ����Υ��ץ����ơ��֥����
48  *
49  * const T_CONFIG_TABLE *xmame_config_get_opt_tbl(void)
50  *      config_init() ��ꡢ xmame_config_init() �θ�˸ƤӽФ���롣
51  *
52  *      ������ɷϥ��ץ����β��Ͻ����ˤ����ơ� QUASI88 �Υ��ץ����ơ��֥�
53  *      T_CONFIG_TABLE ����Ѥ����硢���Υݥ������֤���
54  *      �ȼ������Dz��Ϥ�����ϡ� NULL ���֤���
55  *****************************************************************************/
56 static	int	invalid_arg;			/* ̵���ʥ��ץ�����ѤΥ��ߡ��ѿ� */
57 static	const	T_CONFIG_TABLE xmame_options[] =
58 {
59   /* 350��399: ������ɰ�¸���ץ���� */
60 
61   { 351, "sound",        X_FIX,  &use_sound,       TRUE,                  0,0, OPT_SAVE },
62   { 351, "nosound",      X_FIX,  &use_sound,       FALSE,                 0,0, OPT_SAVE },
63 
64   { 352, "audio",        X_FIX,  &use_audiodevice, TRUE,                  0,0, OPT_SAVE },
65   { 352, "noaudio",      X_FIX,  &use_audiodevice, FALSE,                 0,0, OPT_SAVE },
66 
67   { 353, "fmgen",        X_FIX,  &use_fmgen,       TRUE,                  0,0, OPT_SAVE },
68   { 353, "nofmgen",      X_FIX,  &use_fmgen,       FALSE,                 0,0, OPT_SAVE },
69 
70   { 354, "volume",       X_INV,  &invalid_arg,                          0,0,0, 0        },
71 
72   { 355, "fmvol",        X_INT,  &fmvol,           0, 100,                  0, OPT_SAVE },
73   { 356, "psgvol",       X_INT,  &psgvol,          0, 100,                  0, OPT_SAVE },
74   { 357, "beepvol",      X_INT,  &beepvol,         0, 100,                  0, OPT_SAVE },
75   { 358, "rhythmvol",    X_INT,  &rhythmvol,       0, 200,                  0, OPT_SAVE },
76   { 359, "adpcmvol",     X_INT,  &adpcmvol,        0, 200,                  0, OPT_SAVE },
77   { 360, "fmgenvol",     X_INT,  &fmgenvol,        0, 100,                  0, OPT_SAVE },
78   { 361, "samplevol",    X_INT,  &samplevol,       0, 100,                  0, OPT_SAVE },
79 
80   { 362, "samplefreq",   X_INT,  &options.samplerate, 8000, 48000,          0, OPT_SAVE },
81 
82   { 363, "samples",      X_FIX,  &options.use_samples, 1,                 0,0, OPT_SAVE },
83   { 363, "nosamples",    X_FIX,  &options.use_samples, 0,                 0,0, OPT_SAVE },
84 
85   { 364, "pcmbufsize",   X_INT,  &g_pcm_bufsize,   10, 1000,                0, OPT_SAVE },
86 
87   /* ��ü */
88   {   0, NULL,           X_INV,                                       0,0,0,0, 0        },
89 };
90 
xmame_config_get_opt_tbl(void)91 const T_CONFIG_TABLE *xmame_config_get_opt_tbl(void)
92 {
93     return xmame_options;
94 }
95 
96 
97 /******************************************************************************
98  * ������ɷϥ��ץ����Υإ�ץ�å�������ɽ��
99  *
100  * void xmame_config_show_option(void)
101  *      config_init() ��ꡢ���ץ���� -help �ν����κݤ˸ƤӽФ���롣
102  *      ɸ����Ϥ˥إ�ץ�å�������ɽ�����롣
103  *****************************************************************************/
104 #ifdef	XMAME_SNDDRV_071
105 #define	XMAME_VER "0.71.1"
106 #else	/* ver 0.106 */
107 #define	XMAME_VER " 0.106"
108 #endif
109 
xmame_config_show_option(void)110 void	xmame_config_show_option(void)
111 {
112   fprintf(stdout,
113   "\n"
114   "==========================================\n"
115   "== SOUND OPTIONS ( dependent on XMAME ) ==\n"
116   "==                     [ XMAME " XMAME_VER " ] ==\n"
117   "==========================================\n"
118   "    -[no]sound              Enable/disable sound (if available) [-sound]\n"
119   "    -[no]fmgen              Use/don't use cisc's fmgen library\n"
120   "                                               (if compiled in)  [-nofmgen]\n"
121   "    -volume <n>             Set volume to <n> db, (-32 (soft) - 0(loud))\n"
122   "                                                             <NOT SUPPORT>\n"
123   "    -fmvol <level>          Set FM     level to <level> %%, (0 - 100) [100]\n"
124   "    -psgvol <level>         Set PSG    level to <level> %%, (0 - 100) [20]\n"
125   "    -beepvol <level>        Set BEEP   level to <level> %%, (0 - 100) [60]\n"
126   "    -rhythmvol <level>      Set RHYTHM level to <level> %%, (0 - 100) [100]\n"
127   "    -adpcmvol <level>       Set ADPCM  level to <level> %%, (0 - 100) [100]\n"
128   "    -fmgenvol <level>       Set fmgen  level to <level> %%, (0 - 100) [100]\n"
129   "    -samplevol <level>      Set SAMPLE level to <level> %%, (0 - 100) [100]\n"
130   "    -samplefreq <rate>      Set the playback sample-frequency/rate [44100]\n"
131   "    -[no]samples            Use/don't use samples (if available) [-nosamples]\n"
132   "    -pcmbufsize <n>         Set sound-buffer-size to <n> ms (10 - 1000) [100]\n"
133   );
134 }
135 
136 
137 /******************************************************************************
138  * ������ɷϥ��ץ����β��Ͻ���
139  *
140  * int xmame_config_check_option(char *opt1, char *opt2, int priority)
141  *      config_init() ��ꡢ����������ե�����β��Ϥ�Ԥʤ��ݤˡ�
142  *      ����Υ��ץ����Τ�����ˤ���פ��ʤ���硢���δؿ����ƤӽФ���롣
143  *
144  *              opt1     �� �ǽ�ΰ���(ʸ����)
145  *              opt2     �� ���Τΰ���(ʸ���� �ʤ��� NULL)
146  *              priority �� ͥ���� (�ͤ��礭���ۤ�ͥ���٤��⤤)
147  *
148  *      �����  1  �� ��������������1�� (opt1 �Τ߽����� opt2 ��̤����)
149  *              2  �� ��������������2�� (opt1 �� opt2 �����)
150  *              0  �� opt1 ��̤�Τΰ����Τ��ᡢ opt1 opt2 �Ȥ��̤����
151  *              -1 �� ��������̿Ū�ʰ۾郎ȯ��
152  *
153  *      ������ΰ۾� (�����λ����ͤ��ϰϳ��ʤ�) �䡢ͥ���٤ˤ������������å�
154  *      ���줿�褦�ʾ��ϡ������������Ǥ�������Ʊ�ͤˡ� 1 �� 2 ���֤���
155  *
156  *      �� ���δؿ��ϡ��ȼ������ǥ��ץ�������Ϥ��뤿��δؿ��ʤΤǡ�
157  *         ���ץ����ơ��֥� T_CONFIG_TABLE ����Ѥ�����ϡ����ߡ��Ǥ褤��
158  *****************************************************************************/
xmame_config_check_option(char * opt1,char * opt2,int priority)159 int	xmame_config_check_option(char *opt1, char *opt2, int priority)
160 {
161     return 0;
162 }
163 
164 
165 /******************************************************************************
166  * ������ɷϥ��ץ�������¸���뤿��δؿ�
167  *
168  * int  xmame_config_save_option(void (*real_write)
169  *                                 (const char *opt_name, const char *opt_arg))
170  *
171  *      ����ե��������¸�κݤˡ��ƤӽФ���롣
172  *              ��opt_name �˥��ץ����� opt_arg �˥��ץ���������
173  *                ���åȤ���real_write ��ƤӽФ���
174  *              �Ȥ���ư�����¸�����������ץ������Ф��Ʒ����֤��Ԥʤ���
175  *
176  *              (��) "-sound" ������ե��������¸���������
177  *                      (real_write)("sound", NULL) ��ƤӽФ���
178  *              (��) "-fmvol 80" ������ե��������¸���������
179  *                      (real_write)("fmvol", "80") ��ƤӽФ���
180  *
181  *      �����  ��� 0 ���֤�
182  *
183  *      �� ���δؿ��ϡ��ȼ������ǥ��ץ�������Ϥ��뤿��δؿ��ʤΤǡ�
184  *         ���ץ����ơ��֥� T_CONFIG_TABLE ����Ѥ�����ϡ����ߡ��Ǥ褤��
185  *****************************************************************************/
xmame_config_save_option(void (* real_write)(const char * opt_name,const char * opt_arg))186 int	xmame_config_save_option(void (*real_write)
187 				   (const char *opt_name, const char *opt_arg))
188 {
189     return 0;
190 }
191 
192 
193 /******************************************************************************
194  * ������ɷϥ��ץ������˥塼�����ѹ����뤿��Υơ��֥�����ؿ�
195  *
196  * T_SNDDRV_CONFIG *xmame_config_get_sndopt_tbl(void)
197  *
198  *      ��˥塼�⡼�ɤγ��ϻ��˸ƤӽФ���롣
199  *              �ѹ���ǽ�ʥ�����ɷϥ��ץ����ξ����T_SNDDRV_CONFIG ����
200  *              ����Ȥ����Ѱդ���������Ƭ�ݥ������֤���
201  *              ����Ϻ���5�Ĥޤǡ�����������ˤϽ�ü�ǡ������åȤ��Ƥ�����
202  *
203  *              �ä��ѹ����������Ǥ����Τ�̵������ NULL ���֤���
204  *****************************************************************************/
xmame_config_get_sndopt_tbl(void)205 T_SNDDRV_CONFIG *xmame_config_get_sndopt_tbl(void)
206 {
207     static T_SNDDRV_CONFIG config[] =
208     {
209 	{
210 	    SNDDRV_INT,
211 #if 0
212 	    " Buffer size of PCM data (10 - 1000[ms])    ",
213 #else
214 	    " PCM �Хåե��Υ�����  (10 - 1000[ms])      ",
215 #endif
216 	    &g_pcm_bufsize,  10, 1000,
217 	},
218 	{
219 	    SNDDRV_NULL, 0, 0, 0, 0,
220 	},
221     };
222 
223     if (use_audiodevice) {
224 	return config;
225     } else {
226 	return NULL;
227     }
228 }
229 
230 
231 /******************************************************************************
232  * ������ɵ�ǽ�ξ�����������ؿ�
233  *
234  * int xmame_has_audiodevice(void)
235  *      ������ɥ��ǥХ������Ϥβ��ݤ��֤���
236  *      ���ʤ�ǥХ������ϲġ����ʤ��Բġ�
237  *
238  * int xmame_has_mastervolume(void)
239  *      ������ɥǥХ����β��̤��ѹ���ǽ���ɤ������֤���
240  *      ���ʤ��ѹ���ǽ�����ʤ��Բġ�
241  *
242  *****************************************************************************/
xmame_has_audiodevice(void)243 int	xmame_has_audiodevice(void)
244 {
245     if (use_sound) {
246 	if (device_opened) return TRUE;
247     }
248     return FALSE;
249 }
250 
xmame_has_mastervolume(void)251 int	xmame_has_mastervolume(void)
252 {
253     return FALSE;
254 }
255 
256 
257 /*===========================================================================*/
258 /*              MAME �ν����ؿ�����ƤӽФ���롢�����ƥ��¸�����ؿ�        */
259 /*===========================================================================*/
260 
261 /******************************************************************************
262  * ������ɥǥХ�������
263  *      �����δؿ��ϡ������Х��ѿ� use_sound �����ξ��ϡ��ƤӽФ���ʤ���
264  *
265  * int osd_start_audio_stream(int stereo)
266  *      ������ɥǥХ������������롣
267  *          stereo �����ʤ饹�ƥ쥪���ϡ����ʤ��Υ����Ϥǽ�������롣
268  *          (��Υ����Ϥϡ��Ť��С������� MAME/XMAME �� YM2203 ���������
269  *           ���Τߡ����Ѥ��Ƥ��롣����ʳ��Ϥ��٤ƥ��ƥ쥪���Ϥ���Ѥ��롣)
270  *      ���δؿ��ϡ����ߥ�졼�����γ��ϻ��˸ƤӽФ���롣
271  *          �������ϡ�1�ե졼�ढ����Υ���ץ�����֤���
272  *          ���Ի��ϡ�0 ���֤���
273  *              ���������� 0 ���֤��� QUASI88 ��������λ���Ƥ��ޤ��Τǡ�
274  *              ������ɥǥХ����ν�����˼��Ԥ������Ǥ⡢������ɽ��Ϥʤ���
275  *              ������ʤ᤿���Ȥ�����硢�Ȥˤ���Ŭ�����ͤ��֤�ɬ�פ����롣
276  *
277  * int osd_update_audio_stream(INT16 *buffer)
278  *      ������ɥǥХ����˽��Ϥ��롣
279  *      ���δؿ��ϡ�1�ե졼�������˸ƤӽФ���롣buffer �ˤ�1�ե졼��ʬ
280  *      (Machine->sample_rate / Machine->drv->frames_per_second) �Υ������
281  *      �ǡ�������Ǽ����Ƥ��롣�ǡ����� 16bit����դ��ǡ����ƥ쥪�ξ���
282  *      ���ȱ��Υ���ץ뤬��ߤ��¤�Ǥ��롣
283  *
284  *      �ºݤˤ��δؿ����ƤӽФ��줿�����ߥ��ǥǥХ����˽��Ϥ��뤫�����뤤��
285  *      �����ǥХåե�����������ӽ��Ϥ��뤫�ϡ���������Ǥ��롣
286  *
287  *      ���ͤϡ� osd_start_audio_stream() ��Ʊ��
288  *
289  * void osd_stop_audio_stream(void)
290  *      ������ɥǥХ�����λ���롣
291  *      ���δؿ��ϡ����ߥ�졼�����ν�λ���˸ƤӽФ���롣
292  *      �ʹߡ� osd_update_audio_stream() �ʤɤϸƤӽФ���ʤ������ߥ�졼�����
293  *      ��Ƴ�������ϡ� osd_start_audio_stream() ����ƤӽФ���롣
294  *
295  * void osd_update_video_and_audio(void)
296  *      ������ɥǥХ����ν��Ϥ��Σ�
297  *      �����ߥ�Ū�ˤϡ� osd_update_audio_stream() ��ľ��˸ƤӽФ���롣
298  *      XMAME 0.106 �˹�碌���������Ƥ��뤬�� osd_update_audio_stream() ��
299  *      ������ȼ����Ǥ��줤��С�������δؿ��ϥ��ߡ��Ǥ褤��
300  *
301  * void osd_sound_enable(int enable)
302  *      ������ɥǥХ����ؤν��Ϥ��ꡦ�ʤ������ꤹ�롣
303  *          enable �����ʤ���Ϥ��ꡢ���ʤ���Ϥʤ���
304  *      ���δؿ��ϡ������Х��ѿ� close_device �����ξ��Τߡ��ƤӽФ���롣
305  *          ��˥塼�⡼�ɤ����ä��ݤˡ��������Ȥ��ƸƤӽФ���
306  *          ��˥塼�⡼�ɤ���Ф�ݤˡ��������Ȥ��ƸƤӽФ���
307  *      ���δؿ��ϡ����������ξ��ˡ�������ɥǥХ�������� (close) ����
308  *      ���ξ��˳��� (open) ����褦�ʼ�������Ԥ��Ƥ��뤬��������ɥǥХ���
309  *      �������ݤ����ޤޤˤ���褦�ʼ����Ǥ���С����ߡ��δؿ��Ǥ褤��
310  *      �ʤ���������ɥǥХ����ؤν��Ϥʤ��ξ��� osd_update_audio_stream()
311  *      �ʤɤδؿ��ϸƤӽФ���롣
312  *
313  *****************************************************************************/
314 
315 static	int	create_sound_device(int stereo);
316 static	void	destroy_sound_device(void);
317 static	void	write_sound_device(unsigned char *data, int count);
318 
319 static int samples_per_frame = 0;
320 
321 
osd_start_audio_stream(int stereo)322 int	osd_start_audio_stream(int stereo)
323 {
324     if (use_audiodevice) {
325 	if (!(device_opened = create_sound_device(stereo))) {
326 	    /* �ǥХ����������ʤ��Ƥ⡢���ˤ���³�� */
327 	}
328     } else {
329 	device_opened = FALSE;
330     }
331 
332     /* calculate samples_per_frame */
333 #ifdef	XMAME_SNDDRV_071
334     samples_per_frame =(int)(Machine->sample_rate / Machine->drv->frames_per_second);
335 #else	/* ver 0.106 */
336     samples_per_frame =(int)(Machine->sample_rate / Machine->refresh_rate);
337 #endif
338 
339     return samples_per_frame;
340 }
341 
osd_update_audio_stream(INT16 * buffer)342 int	osd_update_audio_stream(INT16 *buffer)
343 {
344     if (device_opened) {
345 	write_sound_device((unsigned char *)buffer, samples_per_frame);
346     }
347 
348     return samples_per_frame;
349 }
350 
osd_stop_audio_stream(void)351 void	osd_stop_audio_stream(void)
352 {
353     if (device_opened) {
354 	destroy_sound_device();
355 	device_opened = FALSE;
356     }
357 }
358 
osd_update_video_and_audio(void)359 void	osd_update_video_and_audio(void)
360 {
361     /* DO NOTHING */
362 }
363 
osd_sound_enable(int enable)364 void	osd_sound_enable(int enable)
365 {
366     /* DO NOTHING */
367 }
368 
369 
370 /******************************************************************************
371  * ��������
372  *
373  * void osd_set_mastervolume(int attenuation)
374  *      ������ɥǥХ����β��̤����ꤹ�롣 attenuation �� ���̤ǡ� -32��0
375  *      (ñ�̤� db)�� �����ѹ��ΤǤ��ʤ��ǥХ����Ǥ���С����ߡ��Ǥ褤��
376  *
377  * int osd_get_mastervolume(void)
378  *      ���ߤΥ�����ɥǥХ����β��̤�������롣 ���ͤ� -32��0 (ñ�̤� db)��
379  *      �����ѹ��ΤǤ��ʤ��ǥХ����Ǥ���С����ߡ��Ǥ褤��
380  *
381  *****************************************************************************/
osd_set_mastervolume(int attenuation)382 void	osd_set_mastervolume(int attenuation)
383 {
384     /* waveOutSetVolume */
385 }
386 
osd_get_mastervolume(void)387 int	osd_get_mastervolume(void)
388 {
389     /* waveOutGetVolume */
390 
391     return VOL_MIN;
392 }
393 
394 
395 /*===========================================================================*/
396 /*									     */
397 /*===========================================================================*/
398 /* #define	USE_WAVE_OUT_PROC */
399 
400 #ifdef	USE_WAVE_OUT_PROC
401 static void CALLBACK waveOutProc(HWAVEOUT hwo , UINT msg,
402 				 DWORD dwInstance,
403 				 DWORD dwParam1, DWORD dwParam2);
404 #endif
405 
406 static HWAVEOUT hWaveOut;		/* �ǥХ��������ѥϥ�ɥ� */
407 
408 #define	BUFFER_NUM	(2)		/* ���֥�Хåե��ǽ�ʬ�餷�� */
409 static WAVEHDR whdr[BUFFER_NUM];
410 
411 static int byte_per_sample = 4;		/* 1����ץ뤢����ΥХ��ȿ�	*/
412 					/* (�Хåե��������׻����η���)	*/
413 					/* 4 = Stereo, 16bit		*/
414 					/* 2 = Mono,   16bit		*/
415 
416 /*
417   PCM�ǡ����Υ��塼�����ϡ� XMAME 0.106 ���ͤˤ��ޤ�����
418 
419   ���ͥ����� xmame-0.106/src/unix/sysdep/dsp-drivers/sdl.c
420   Copyright 2001 Jack Burton aka Stefano Ceccherini
421 */
422 
423 static struct {
424     unsigned char	*data;
425     int			dataSize;
426     int			amountRemain;
427     int			amountWrite;
428     int			amountRead;
429     int			tmp;
430     unsigned long	soundlen;
431     int			sound_n_pos;
432     int			sound_w_pos;
433     int			sound_r_pos;
434 } sample;
435 
436 
437 
create_sound_device(int stereo)438 static	int	create_sound_device(int stereo)
439 {
440     int i, err, bufsize;
441     WAVEFORMATEX f;
442 
443     if (stereo) byte_per_sample = 4;
444     else        byte_per_sample = 2;
445 
446     /* PCM�η��������� */
447     memset(&f, 0, sizeof(f));
448 
449     f.wFormatTag	= WAVE_FORMAT_PCM;		/* PCM����	*/
450     f.nChannels		= (stereo) ? 2 : 1;		/* stereo/mono	*/
451     f.wBitsPerSample	= 16;				/* �̻Ҳ� bit��	*/
452     f.nSamplesPerSec	= Machine->sample_rate;		/* ɸ�ܲ����ȿ�	*/
453     f.nBlockAlign	= f.nChannels * f.wBitsPerSample / 8;
454     f.nAvgBytesPerSec	= f.nSamplesPerSec * f.nBlockAlign;
455     f.cbSize		= 0;
456 
457     /* �ǥХ������� */
458     memset(&hWaveOut, 0, sizeof(hWaveOut));
459 
460     if (waveOutOpen(&hWaveOut,		/* �����ˡ��ϥ�ɥ뤬�֤����	     */
461 		    WAVE_MAPPER,	/* �ǥХ����ϡ��桼������Τ�Τ����*/
462 		    &f,			/* PCM�η���			     */
463 #ifdef	USE_WAVE_OUT_PROC
464 		    (DWORD)waveOutProc,	/* ������Хå��ؿ�		     */
465 		    0,			/* ������Хå��ؿ��ΰ����ǡ���	     */
466 		    CALLBACK_FUNCTION	/* ������Хå��ؿ������	     */
467 #else
468 		    (DWORD)g_hWnd,	/* ������ɥ��ϥ�ɥ�		     */
469 		    0,			/* ̤����			     */
470 		    CALLBACK_WINDOW	/* ������ɥ��ϥ�ɥ�����	     */
471 #endif
472 				) != MMSYSERR_NOERROR) {
473 
474 	fprintf(stderr, "failed opening audio device\n");
475 	return FALSE;
476 
477 	/* �������ϡ� MM_WOM_OPEN / WOM_OPEN ��ȯ������ */
478     }
479 
480     /* WAV�Хåե������� */
481     memset(&whdr, 0, sizeof(whdr));
482 
483     err = FALSE;
484     bufsize = Machine->sample_rate * byte_per_sample * g_pcm_bufsize / 1000;
485     /* �Хåե��������λ�������� (2�Τ٤���Ȥ�������ͤȤ�) ��̵���Ρ� */
486     for (i=0; i<BUFFER_NUM; i++) {
487 	whdr[i].lpData		= (LPSTR)calloc(1, bufsize);
488 	whdr[i].dwBufferLength	= bufsize;
489 	whdr[i].dwFlags		= WHDR_BEGINLOOP | WHDR_ENDLOOP;
490 	whdr[i].dwLoops		= 1;
491 	whdr[i].dwUser		= FALSE;    /* FALSE = Started, Need to Write*/
492 
493 	if (whdr[i].lpData == NULL) { err = TRUE; }
494     }
495 
496     /* WAV�Хåե��˥ǡ��������뤿��Ρ���֥Хåե����������� */
497     /* ��֥Хåե��ϡ�WAV�Хåե������礭���ʤ��Ȥ����ʤ�   */
498     if (err == FALSE) {
499 	memset(&sample, 0, sizeof(sample));
500 
501 	sample.dataSize = bufsize * 4;	/* �Хåե���4�ܤ���ݡ������ͤǤ���?*/
502 	if (!(sample.data = calloc(1, sample.dataSize))) {
503 	    err = TRUE;
504 	}
505     }
506 
507     /* �����ޤǤ˥��顼���ФƤ��顢��λ */
508     if (err){
509 	for (i=0; i<BUFFER_NUM; i++) {
510 	    if (whdr[i].lpData) { free(whdr[i].lpData); }
511 	}
512 	waveOutClose(hWaveOut);
513 	return FALSE;
514     }
515 
516 
517     if (verbose_proc)
518 	printf("  waveOutOpen=16bit, %s, %dHz : buf-size=%d\n",
519 	       (stereo) ? "stereo" : "mono",
520 	       f.nSamplesPerSec, bufsize / byte_per_sample);
521 
522     /* WAV�Хåե� (����̵��) ����� */
523     for (i=0; i<BUFFER_NUM; i++) {
524 	if (waveOutPrepareHeader(hWaveOut, &whdr[i], sizeof(WAVEHDR))
525 							== MMSYSERR_NOERROR) {
526 
527 	    waveOutWrite(hWaveOut, &whdr[i], sizeof(WAVEHDR));
528 	    /* BUFFER_NUM ����˺�������뤬�����Τ��κ�����λ����
529 	       MM_WOM_DONE / WOM_DONE ��ȯ������ */
530 	}
531     }
532 
533     return TRUE;
534 }
535 
destroy_sound_device(void)536 static	void	destroy_sound_device(void)
537 {
538     int i;
539 
540     for (i=0; i<BUFFER_NUM; i++) {
541 	whdr[i].dwUser = TRUE;		    /* TRUE = Stopped, Never Write */
542     }
543     waveOutReset(hWaveOut);
544     /* BUFFER_NUM �� MM_WOM_DONE / WOM_DONE ��ȯ������ */
545 
546     for (i=0; i<BUFFER_NUM; i++) {
547 	waveOutUnprepareHeader(hWaveOut, &whdr[i], sizeof(WAVEHDR));
548     }
549     waveOutClose(hWaveOut);
550     /* MM_WOM_CLOSE / WOM_CLOSE ��ȯ������ */
551 
552     for (i=0; i<BUFFER_NUM; i++) {
553 	free(whdr[i].lpData);
554     }
555 
556     if (sample.data) {
557 	free(sample.data);
558     }
559     memset(&sample, 0, sizeof(sample));
560     sample.data = NULL;
561 }
562 
563 /*
564  * ��֥Хåե��ˡ�PCM�ǡ������åȤ��롣
565  * (������ɥǥХ����˽��Ϥ���櫓�ǤϤʤ�)
566  * ���δؿ��ϡ�QUASI88��ꡢ1�ե졼����˸ƤӽФ����(�Ϥ�)
567  *
568  * ���� sdl_dsp_write()
569  */
write_sound_device(unsigned char * data,int count)570 static	void	write_sound_device(unsigned char *data, int count)
571 {
572     /* sound_n_pos = normal position
573        sound_r_pos = read position
574        and so on.			*/
575     unsigned char *src;
576     int bytes_written = 0;
577     /* Lock */
578 
579     sample.amountRemain = sample.dataSize - sample.sound_n_pos;
580     sample.amountWrite = count * byte_per_sample;
581 
582     if(sample.amountRemain <= 0) {
583 	/* Unlock */
584 	return;
585     }
586 
587     if(sample.amountRemain < sample.amountWrite) sample.amountWrite = sample.amountRemain;
588     sample.sound_n_pos += sample.amountWrite;
589 
590     src = (unsigned char *)data;
591     sample.tmp = sample.dataSize - sample.sound_w_pos;
592 
593     if(sample.tmp < sample.amountWrite){
594 	memcpy(sample.data + sample.sound_w_pos, src, sample.tmp);
595 	bytes_written += sample.tmp;
596 	sample.amountWrite -= sample.tmp;
597 	src += sample.tmp;
598 	memcpy(sample.data, src, sample.amountWrite);
599 	bytes_written += sample.amountWrite;
600 	sample.sound_w_pos = sample.amountWrite;
601     }
602     else{
603 	memcpy( sample.data + sample.sound_w_pos, src, sample.amountWrite);
604 	bytes_written += sample.amountWrite;
605 	sample.sound_w_pos += sample.amountWrite;
606     }
607     /* Unlock */
608 
609     return;
610 }
611 
612 /*
613  * ��֥Хåե��� PCM �ǡ������ǥХ����˽��Ϥ��롣
614  *
615  *
616  * ���� sdl_fill_sound()
617  */
618 #ifdef	USE_WAVE_OUT_PROC
619 /* waveOutProc �������ǡ� WaveOut��API��ƤӽФ��ΤϤ���餷����
620    �Ȥ������Ȥϡ����δؿ��ϻȤ��ʤ�?  WndProc ���������ƤӽФ�? */
waveOutProc(HWAVEOUT hwo,UINT msg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)621 static void CALLBACK waveOutProc(HWAVEOUT hwo,
622 				 UINT msg,
623 				 DWORD dwInstance,
624 				 DWORD dwParam1, DWORD dwParam2)
625 {
626     /* hwo      == hWaveOut                          */
627     /* dwParam1 == whdr[n]  ���٥��ȯ�����ΥХåե� */
628 
629     switch (msg) {
630     case WOM_OPEN:
631 	wave_event_open(hwo);
632 	break;
633 
634     case WOM_DONE:
635 	wave_event_done(hwo, (LPWAVEHDR)dwParam1);
636 	break;
637 
638     case WOM_CLOSE:
639 	wave_event_close(hwo);
640 	break;
641     }
642 }
643 #endif
644 
645 /*
646  * MM_WOM_OPEN / WOM_OPEN ȯ�����˸ƤӽФ��ؿ�
647  */
wave_event_open(HWAVEOUT hwo)648 void	wave_event_open(HWAVEOUT hwo)
649 {
650     /* printf("S:open\n"); */
651 }
652 
653 /*
654  * MM_WOM_DONE / WOM_DONW ȯ�����˸ƤӽФ��ؿ�
655  */
wave_event_done(HWAVEOUT hwo,LPWAVEHDR lpwhdr)656 void	wave_event_done(HWAVEOUT hwo, LPWAVEHDR lpwhdr)
657 {
658     if (lpwhdr->dwUser) {		    /* TRUE = Stopped, Never Write */
659 	/* printf("S:break\n"); */
660 	/* DO NOTHING */
661     } else {				    /* FALSE = Started, Need to Write*/
662 
663 	int result;
664 	unsigned char *dst = (unsigned char *) (lpwhdr->lpData);
665 	int len = lpwhdr->dwBufferLength;
666 
667 	/* int i; for (i=0; i<BUFFER_NUM; i++) if (lpwhdr == &whdr[i]) break;*/
668 	/* printf("S:done %d\n",i); */
669 
670 	sample.amountRead = len;
671 	if(sample.sound_n_pos <= 0) {
672 	    /* ��֥Хåե������ʤ顢���褦���ʤ��Τ�̵��������� */
673 	    memset(lpwhdr->lpData, 0, len);
674 /*
675 	    fprintf(debugfp, "sound empty\n");
676 */
677 	} else {
678 	    if(sample.sound_n_pos<sample.amountRead) sample.amountRead = sample.sound_n_pos;
679 	    result = (int)sample.amountRead;
680 	    sample.sound_n_pos -= sample.amountRead;
681 
682 	    sample.tmp = sample.dataSize - sample.sound_r_pos;
683 	    if(sample.tmp<sample.amountRead){
684 		memcpy( dst, sample.data + sample.sound_r_pos, sample.tmp);
685 		sample.amountRead -= sample.tmp;
686 		dst += sample.tmp;
687 		memcpy( dst, sample.data, sample.amountRead);
688 		sample.sound_r_pos = sample.amountRead;
689 	    }
690 	    else{
691 		memcpy( dst, sample.data + sample.sound_r_pos, sample.amountRead);
692 		sample.sound_r_pos += sample.amountRead;
693 	    }
694 	}
695 
696 	if (waveOutPrepareHeader(hWaveOut, lpwhdr, sizeof(WAVEHDR))
697 							== MMSYSERR_NOERROR) {
698 	    waveOutWrite(hWaveOut, lpwhdr, sizeof(WAVEHDR));
699 	    /* �� ������� MM_WOM_DONE / WOM_DONE ��ȯ������ */
700 	}
701     }
702 }
703 
704 /*
705  * MM_WOM_CLOSE / WOM_CLOSE ȯ�����˸ƤӽФ��ؿ�
706  */
wave_event_close(HWAVEOUT hwo)707 void	wave_event_close(HWAVEOUT hwo)
708 {
709     /* printf("S:close\n"); */
710 }
711 
712 #endif	/* USE_SOUND */
713