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