1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24 #include <stdio.h>
25 #ifndef NO_STRING_H
26 #include <string.h>
27 #else
28 #include <strings.h>
29 #endif
30 #include <mme/mme_api.h>
31 #include "timidity.h"
32 #include "aenc.h"
33 #include "audriv.h"
34 #include "timer.h"
35
36 #define DATA_BLOCK_SIZE 2048
37 #define DATA_BLOCK_NUM 48
38 #define AUDIO_CLOSE_ID -1
39 #define IS_AUDIO_PLAY_OPEN (play_wave_format && play_wave_format->hWave != AUDIO_CLOSE_ID)
40 #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
41
42 struct wave_format_t
43 {
44 HWAVE hWave;
45 PCMWAVEFORMAT format;
46 WAVEHDR waveHdr;
47 UINT DevID;
48 };
49 static struct wave_format_t *play_wave_format = NULL;
50 static MMTIME *wave_time_info = NULL;
51 static LPDWORD lpdword_buff = NULL;
52 static LPWAVEOUTCAPS wave_out_caps = NULL;
53
54 #define AUDRIV_WRITE 1
55
56 struct data_block_t
57 {
58 LPSTR data;
59 int data_start;
60 int data_size;
61 int blockno;
62 int in_use; /* 0, AUDRIV_WRITE */
63 struct data_block_t *next;
64 };
65
66 static struct data_block_t all_data_block[DATA_BLOCK_NUM];
67 static struct data_block_t *free_data_block;
68 static int data_block_length; /* used data block length */
69 void (* audriv_error_handler)(const char *errmsg) = NULL;
70
71 static Bool audio_write_noblocking = False;
72 static double play_start_time;
73 static long play_counter, reset_samples;
74 static int output_port = AUDRIV_OUTPUT_SPEAKER;
75
76 char audriv_errmsg[BUFSIZ];
77
78 static const char *mme_mmsyserr_code_string[] =
79 {
80 "no error",
81 "unspecified error",
82 "device ID out of range",
83 "driver failed enable",
84 "device already allocated",
85 "device handle is invalid",
86 "no device driver present",
87 "memory allocation error",
88 "function isn't supported",
89 "error value out of range",
90 "invalid flag passed",
91 "invalid parameter passed",
92 "handle being used",
93 "simultaneously on another",
94 "thread (eg callback)",
95 "Specified alias not found in WIN.INI",
96 };
97
98 static const char *mme_waverr_code_sring[] =
99 {
100 "unsupported wave format",
101 "still something playing",
102 "header not prepared",
103 "device is synchronous",
104 "Device in use",
105 "Device in use",
106 };
107
108 static const char *mme_midierr_code_sring[] =
109 {
110 "header not prepared",
111 "still something playing",
112 "no current map",
113 "hardware is still busy",
114 "port no longer connected",
115 "invalid setup",
116 };
117
mme_error_code_string(MMRESULT err_code)118 static const char *mme_error_code_string(MMRESULT err_code)
119 {
120 if(err_code >= TIMERR_BASE)
121 {
122 switch(err_code)
123 {
124 case TIMERR_NOCANDO:
125 return "request not completed";
126 case TIMERR_STRUCT:
127 return "time struct size";
128 }
129 return "";
130 }
131 if(err_code >= MIDIERR_BASE)
132 {
133 err_code -= MIDIERR_BASE;
134 if(err_code > ARRAY_SIZE(mme_midierr_code_sring))
135 return "";
136 return mme_midierr_code_sring[err_code];
137 }
138 if(err_code >= WAVERR_BASE)
139 {
140 err_code -= WAVERR_BASE;
141 if(err_code > ARRAY_SIZE(mme_waverr_code_sring))
142 return "";
143 return mme_waverr_code_sring[err_code];
144 }
145 if(err_code > ARRAY_SIZE(mme_mmsyserr_code_string))
146 return "";
147 return mme_mmsyserr_code_string[err_code];
148 }
149
audriv_err(const char * msg)150 static void audriv_err(const char *msg)
151 {
152 strncpy(audriv_errmsg, msg, sizeof(audriv_errmsg) - 1);
153 if(audriv_error_handler != NULL)
154 audriv_error_handler(audriv_errmsg);
155 }
156
new_data_block()157 static struct data_block_t *new_data_block()
158 {
159 struct data_block_t *p;
160 if(free_data_block == NULL)
161 return NULL;
162 p = free_data_block;
163 free_data_block = free_data_block->next;
164 data_block_length++;
165 p->next = NULL;
166 p->data_start = 0;
167 p->data_size = DATA_BLOCK_SIZE;
168 return p;
169 }
170
reuse_data_block(int blockno)171 static void reuse_data_block(int blockno)
172 {
173 if(all_data_block[blockno].in_use)
174 {
175 all_data_block[blockno].next = free_data_block;
176 all_data_block[blockno].in_use = 0;
177 free_data_block = all_data_block + blockno;
178 data_block_length--;
179 }
180 }
181
reset_data_block(void)182 static void reset_data_block(void)
183 {
184 int i;
185
186 all_data_block[0].blockno = 0;
187 all_data_block[0].next = all_data_block + 1;
188 for(i = 1; i < DATA_BLOCK_NUM - 1; i++)
189 {
190 all_data_block[i].blockno = i;
191 all_data_block[i].in_use = 0;
192 all_data_block[i].next = all_data_block + i + 1;
193 }
194 all_data_block[i].blockno = i;
195 all_data_block[i].in_use = 0;
196 all_data_block[i].next = NULL;
197 free_data_block = all_data_block;
198 data_block_length = 0;
199 }
200
audriv_setup_audio(void)201 Bool audriv_setup_audio(void)
202 /* �����ǥ����ν������Ԥ��ޤ���
203 * ������������ True ���Ԥ������� False ���֤��ޤ���
204 */
205 {
206 int i;
207
208 play_wave_format = (struct wave_format_t *)
209 mmeAllocMem(sizeof(struct wave_format_t));
210 if(play_wave_format == NULL)
211 {
212 audriv_err(mme_error_code_string(MMSYSERR_NOMEM));
213 return False;
214 }
215 play_wave_format->DevID = 0;
216
217 wave_time_info = (MMTIME *)mmeAllocMem(sizeof(MMTIME));
218 if(wave_time_info == NULL)
219 {
220 audriv_free_audio();
221 audriv_err(mme_error_code_string(MMSYSERR_NOMEM));
222 return False;
223 }
224
225 lpdword_buff = (LPDWORD)mmeAllocMem(sizeof(DWORD));
226 if(lpdword_buff == NULL)
227 {
228 audriv_free_audio();
229 audriv_err(mme_error_code_string(MMSYSERR_NOMEM));
230 return False;
231 }
232
233 wave_out_caps = (LPWAVEOUTCAPS)mmeAllocMem(sizeof(WAVEOUTCAPS));
234 if(wave_out_caps == NULL)
235 {
236 audriv_free_audio();
237 audriv_err(mme_error_code_string(MMSYSERR_NOMEM));
238 return False;
239 }
240
241 all_data_block[0].data = mmeAllocBuffer(DATA_BLOCK_NUM * DATA_BLOCK_SIZE);
242
243 #ifdef DEBUG
244 fprintf(stderr, "%d shared audio buffer memory is allocated.\n",
245 DATA_BLOCK_NUM * DATA_BLOCK_SIZE);
246 #endif /* DEBUG */
247
248 if(all_data_block[0].data == NULL)
249 {
250 audriv_free_audio();
251 audriv_err(mme_error_code_string(MMSYSERR_NOMEM));
252 return False;
253 }
254 for(i = 1; i < DATA_BLOCK_NUM; i++)
255 all_data_block[i].data = all_data_block[0].data + i * DATA_BLOCK_SIZE;
256 reset_data_block();
257
258 play_wave_format->hWave = AUDIO_CLOSE_ID;
259 play_wave_format->format.wf.wFormatTag = WAVE_FORMAT_MULAW;
260 play_wave_format->format.wf.nChannels = 1;
261 play_wave_format->format.wf.nSamplesPerSec = 8000;
262 play_wave_format->format.wf.nAvgBytesPerSec = 8000;
263 play_wave_format->format.wf.nBlockAlign = 1;
264 play_wave_format->format.wBitsPerSample = 8;
265
266 audriv_play_open();
267 audriv_play_close();
268 return True;
269 }
270
audriv_free_audio(void)271 void audriv_free_audio(void)
272 /* audio �θ������Ԥ��ޤ���
273 */
274 {
275 audriv_play_close();
276
277 if(all_data_block[0].data)
278 mmeFreeBuffer(all_data_block[0].data);
279 all_data_block[0].data = NULL;
280
281 if(play_wave_format)
282 mmeFreeMem(play_wave_format);
283 play_wave_format = NULL;
284
285 if(wave_time_info)
286 mmeFreeMem(wave_time_info);
287 wave_time_info = NULL;
288
289 if(lpdword_buff)
290 mmeFreeMem(lpdword_buff);
291 lpdword_buff = NULL;
292
293 if(wave_out_caps)
294 mmeFreeMem(wave_out_caps);
295 wave_out_caps = NULL;
296 }
297
callback_message_string(UINT msg)298 static const char *callback_message_string(UINT msg)
299 {
300 switch(msg)
301 {
302 case WOM_OPEN:
303 return "WOM_OPEN";
304 case WOM_CLOSE:
305 return "WOM_CLOSE";
306 case WOM_DONE:
307 return "WOM_DONE";
308 case WIM_OPEN:
309 return "WIM_OPEN";
310 case WIM_CLOSE:
311 return "WIM_CLOSE";
312 case WIM_DATA:
313 return "WIM_DATA";
314 default:
315 return "Unknown";
316 }
317 }
318
audriv_callback_mme(HANDLE Hwave,UINT wMsg,DWORD dwInstance,LPARAM lParam1,LPARAM lParam2)319 static void audriv_callback_mme(HANDLE Hwave, UINT wMsg, DWORD dwInstance,
320 LPARAM lParam1, LPARAM lParam2)
321 {
322 #ifdef DEBUGALL
323 fprintf(stderr, "audriv_callback_mme: mMsg=%d (%s)\n",
324 wMsg, callback_message_string(wMsg));
325 #endif
326
327 if(wMsg == WOM_DONE)
328 {
329 WAVEHDR *wp = (WAVEHDR *)lParam1;
330 #ifdef DEBUGALL
331 fprintf(stderr, "output wp->dwUser = %d\n", wp->dwUser);
332 #endif
333 reuse_data_block(wp->dwUser);
334 }
335 }
336
337 #ifdef DEBUG
ProductID_names(WORD id)338 static const char *ProductID_names(WORD id)
339 {
340 switch(id)
341 {
342 case MM_MIDI_MAPPER: return "MIDI Mapper";
343 case MM_WAVE_MAPPER: return "Wave Mapper";
344 case MM_SNDBLST_MIDIOUT: return "Sound Blaster MIDI output port";
345 case MM_SNDBLST_MIDIIN: return "Sound Blaster MIDI input port";
346 case MM_SNDBLST_SYNTH: return "Sound Blaster internal synthesizer";
347 case MM_SNDBLST_WAVEOUT: return "Sound Blaster waveform output";
348 case MM_SNDBLST_WAVEIN: return "Sound Blaster waveform input";
349 case MM_ADLIB: return "Ad Lib-compatible synthesizer";
350 case MM_MPU401_MIDIOUT: return "MPU401-compatible MIDI output port";
351 case MM_MPU401_MIDIIN: return "MPU401-compatible MIDI input port";
352 case MM_PC_JOYSTICK: return "Joystick adapter";
353
354 #ifdef MM_DIGITAL_BBA
355 case MM_DIGITAL_BBA: return "DEC BaseBoard Audio for ALPHA-AXP";
356 #endif /* MM_DIGITAL_BBA */
357
358 #ifdef MM_DIGITAL_J300AUDIO
359 case MM_DIGITAL_J300AUDIO: return "DEC J300 TC option card";
360 #endif /* MM_DIGITAL_J300AUDIO */
361
362 #ifdef MM_DIGITAL_MSB
363 case MM_DIGITAL_MSB: return "DEC Microsoft Sound Board compatible card";
364 #endif /* MM_DIGITAL_MSB */
365
366 #ifdef MM_DIGITAL_IMAADPCM
367 case MM_DIGITAL_IMAADPCM: return "DEC IMA ADPCM ACM driver";
368 #endif /* MM_DIGITAL_IMAADPCM */
369 }
370 return "Unknown";
371 }
372 #endif /* DEBUG */
373
audriv_play_open(void)374 Bool audriv_play_open(void)
375 {
376 MMRESULT status;
377
378 if(IS_AUDIO_PLAY_OPEN)
379 return True;
380
381 play_counter = 0;
382 reset_samples = 0;
383
384 play_wave_format->hWave = 0;
385 status = waveOutOpen(&play_wave_format->hWave,
386 WAVE_MAPPER,
387 &play_wave_format->format.wf,
388 audriv_callback_mme,
389 NULL,
390 CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE);
391
392 if(status != MMSYSERR_NOERROR)
393 {
394 audriv_err(mme_error_code_string(status));
395 play_wave_format->hWave = AUDIO_CLOSE_ID;
396 return False;
397 }
398
399 status = waveOutGetID(play_wave_format->hWave,
400 &play_wave_format->DevID);
401 if(status != MMSYSERR_NOERROR)
402 {
403 audriv_err(mme_error_code_string(status));
404 audriv_play_close();
405 return False;
406 }
407
408 status = waveOutGetDevCaps(play_wave_format->DevID,
409 wave_out_caps, sizeof(WAVEOUTCAPS));
410 if(status != MMSYSERR_NOERROR)
411 {
412 audriv_err(mme_error_code_string(status));
413 audriv_play_close();
414 return False;
415 }
416
417 #ifdef DEBUG
418 fprintf(stderr, "Play Device ID: %d\n", play_wave_format->DevID);
419 #ifdef MM_MICROSOFT
420 if(wave_out_caps->wMid == MM_MICROSOFT)
421 fputs("Manufacture: Microsoft Corp.", stderr);
422 #endif /* MM_MICROSOFT */
423 #ifdef MM_DIGITAL
424 if(wave_out_caps->wMid == MM_DIGITAL)
425 fputs("Manufacture: Digital Eq. Corp.", stderr);
426 #endif /* MM_DIGITAL */
427
428 fprintf(stderr, "Product: %s\n", ProductID_names(wave_out_caps->wPid));
429 fprintf(stderr, "Version of the driver: %d\n", wave_out_caps->vDriverVersion);
430 fprintf(stderr, "Product name: %s\n", wave_out_caps->szPname);
431 fprintf(stderr, "Formats supported: 0x%x\n", wave_out_caps->dwFormats);
432 fprintf(stderr, "number of sources supported: 0x%x\n", wave_out_caps->wChannels);
433 fprintf(stderr, "functionality supported by driver: 0x%x\n",
434 wave_out_caps->dwSupport);
435 #endif
436
437 mmeProcessCallbacks();
438
439 return True;
440 }
441
audriv_play_close(void)442 void audriv_play_close(void)
443 {
444 if(!IS_AUDIO_PLAY_OPEN)
445 return;
446 waveOutClose(play_wave_format->hWave);
447 mmeProcessCallbacks();
448 play_wave_format->hWave = AUDIO_CLOSE_ID;
449 }
450
calculate_play_samples(void)451 static long calculate_play_samples(void)
452 {
453 double es;
454
455 if(play_counter <= 0)
456 return 0;
457
458 es = (double)(play_wave_format->format.wf.nSamplesPerSec
459 * play_wave_format->format.wf.nBlockAlign)
460 * (get_current_calender_time() - play_start_time);
461 if(es > play_counter)
462 return play_counter / play_wave_format->format.wf.nBlockAlign;
463 return (long)(es / play_wave_format->format.wf.nBlockAlign);
464 }
465
audriv_play_stop(void)466 long audriv_play_stop(void)
467 /* ���դ�¨�¤���ߤ������ľ���Υ���ץ�����֤��ޤ���
468 * audriv_play_stop() �θƤӽФ��ˤ�äơ�audio ���Ĥ��ޤ���
469 * audio �������Ĥ��Ƥ������ audriv_play_stop() ��ƤӽФ������� 0 ��
470 * �֤��ޤ���
471 * ���顼�ξ��� -1 ���֤��ޤ���
472 */
473 {
474 MMRESULT status;
475
476 if(!IS_AUDIO_PLAY_OPEN)
477 return 0;
478
479 status = waveOutReset(play_wave_format->hWave);
480 if(status != MMSYSERR_NOERROR)
481 {
482 audriv_err(mme_error_code_string(status));
483 return -1;
484 }
485
486 waveOutClose(play_wave_format->hWave);
487 mmeProcessCallbacks();
488 play_wave_format->hWave = AUDIO_CLOSE_ID;
489
490 return calculate_play_samples();
491 }
492
audriv_is_play_open(void)493 Bool audriv_is_play_open(void)
494 /* audio �����դǥ����ץ�Ƥ������ True,
495 * �Ĥ��Ƥ������ False ���֤��ޤ���
496 */
497 {
498 return IS_AUDIO_PLAY_OPEN;
499 }
500
audriv_set_play_volume(int volume)501 Bool audriv_set_play_volume(int volume)
502 /* ���ղ��̤� 0 �� 255 ���ϰ�������ꤷ�ޤ���0 ��̵����255 �Ϻ��粻�̡�
503 * 0 ̤���� 0��255 ��Ķ�����ͤ� 255 ��������
504 * ������������ True ���Ԥ������� False ���֤��ޤ���
505 */
506 {
507 unsigned short left, right;
508 DWORD vol;
509 MMRESULT status;
510
511 if(volume < 0)
512 volume = 0;
513 else if(volume > 255)
514 volume = 255;
515
516 left = right = ((unsigned)volume) * 257;
517 vol = ((DWORD)left | (((DWORD)right) << 16));
518
519 status = waveOutSetVolume(play_wave_format->DevID, vol);
520 if(status != MMSYSERR_NOERROR)
521 {
522 audriv_err(mme_error_code_string(status));
523 return False;
524 }
525
526 return True;
527 }
528
audriv_get_play_volume(void)529 int audriv_get_play_volume(void)
530 /* ���ղ��̤� 0 �� 255 ������ޤ���0 ��̵����255 �Ϻ��粻�̡�
531 * ���Ԥ���� -1 ���֤��������Ǥʤ����� 0 �� 255 ��β��̤��֤��ޤ���
532 */
533 {
534 MMRESULT status;
535 unsigned short left, right;
536
537 status = waveOutGetVolume(play_wave_format->DevID, lpdword_buff);
538 if(status != MMSYSERR_NOERROR)
539 {
540 audriv_err(mme_error_code_string(status));
541 return -1;
542 }
543
544 left = (*lpdword_buff & 0xffff) / 257;
545 right = ((UINT)*lpdword_buff >> 16) / 257;
546
547 return (int)((left + right) / 2);
548 }
549
550 /* FIXME */
audriv_set_play_output(int port)551 Bool audriv_set_play_output(int port)
552 /* audio �ν����� port ����ꤷ�ޤ���port �ˤϰʲ��Τɤ줫����ꤷ�ޤ���
553 *
554 * AUDRIV_OUTPUT_SPEAKER ���ԡ����˽��ϡ�
555 * AUDRIV_OUTPUT_HEADPHONE �إåɥۥ�˽��ϡ�
556 * AUDRIV_OUTPUT_LINE_OUT �饤���Ȥ˽��ϡ�
557 *
558 * ������������ True ���Ԥ������� False ���֤��ޤ���
559 */
560 {
561 switch(port)
562 {
563 case AUDRIV_OUTPUT_SPEAKER:
564 case AUDRIV_OUTPUT_HEADPHONE:
565 case AUDRIV_OUTPUT_LINE_OUT:
566 output_port = port;
567 break;
568 default:
569 audriv_err("���곰�ν��ϥݡ��Ȥ����ꤵ��ޤ�����");
570 return False;
571 }
572 return True;
573 }
574
575 /* FIXME */
audriv_get_play_output(void)576 int audriv_get_play_output(void)
577 /* audio �ν����� port �����ޤ���
578 * ���Ԥ���� -1 ���֤�����������Ȱʲ��Τ����줫���ͤ��֤��ޤ���
579 *
580 * AUDRIV_OUTPUT_SPEAKER ���ԡ����˽��ϡ�
581 * AUDRIV_OUTPUT_HEADPHONE �إåɥۥ�˽��ϡ�
582 * AUDRIV_OUTPUT_LINE_OUT �饤���Ȥ˽��ϡ�
583 *
584 */
585 {
586 return output_port;
587 }
588
audriv_write(char * buff,int n)589 int audriv_write(char *buff, int n)
590 /* audio �� buff �� n �Х���ʬή�����ߤޤ���
591 * audriv_set_noblock_write() ����֥�å����⡼�ɤ����ꤵ�줿
592 * ���ϡ����δؿ��θƤӽФ���¨�¤˽������֤�ޤ���
593 * �֤��ͤϼºݤ�ή�����ޤ줿�Х��ȿ��Ǥ��ꡤ��֥�å����⡼�ɤ�����
594 * ����Ƥ�����ϡ����� n ��꾯�ʤ���礬����ޤ���
595 * ���Ԥ���� -1 ���֤�����������ȡ��ºݤ�ή�����ޤ줿�Х��ȿ����֤��ޤ���
596 */
597 {
598 struct data_block_t *block;
599 int len, total, loop_cnt;
600 MMRESULT status;
601
602 total = 0;
603 loop_cnt = 0;
604 while(n > 0)
605 {
606 mmeProcessCallbacks();
607
608 if((block = new_data_block()) == NULL)
609 {
610 if(audio_write_noblocking)
611 return total;
612 mmeWaitForCallbacks (); /* block so we don't hog 100% of the CPU */
613 continue;
614 }
615 block->in_use = AUDRIV_WRITE;
616 if(n <= DATA_BLOCK_SIZE)
617 len = n;
618 else
619 len = DATA_BLOCK_SIZE;
620 memcpy(block->data, buff + total, len);
621 play_wave_format->waveHdr.dwBufferLength = len;
622 play_wave_format->waveHdr.lpData = block->data;
623 play_wave_format->waveHdr.dwUser = block->blockno;
624 status = waveOutWrite(play_wave_format->hWave,
625 &play_wave_format->waveHdr,
626 sizeof(WAVEHDR));
627 if(status != MMSYSERR_NOERROR)
628 {
629 audriv_err(mme_error_code_string(status));
630 return -1;
631 }
632
633 if(audriv_play_active() == 0)
634 {
635 reset_samples +=
636 play_counter / play_wave_format->format.wf.nBlockAlign;
637 play_counter = 0;
638 }
639 if(play_counter == 0)
640 play_start_time = get_current_calender_time();
641 play_counter += len;
642 total += len;
643
644 n -= len;
645 loop_cnt++;
646 if(audio_write_noblocking && loop_cnt >= DATA_BLOCK_NUM/2)
647 break;
648 }
649 return total;
650 }
651
audriv_set_noblock_write(Bool noblock)652 Bool audriv_set_noblock_write(Bool noblock)
653 /* noblock �� True ����ꤹ��ȡ�audriv_write() �ƤӽФ��ǥ֥�å����ޤ���
654 * False ����ꤹ��ȡ��ǥե���Ȥξ��֤��ᤷ�ޤ���
655 * ��������������� True ���Ԥ���� False ���֤��ޤ���
656 */
657 {
658 audio_write_noblocking = noblock;
659 return True;
660 }
661
audriv_play_active(void)662 int audriv_play_active(void)
663 /* ������ʤ� 1��������Ǥʤ��ʤ� 0, ���顼�ʤ� -1 ���֤��ޤ���
664 */
665 {
666 double es;
667
668 if(play_counter <= 0)
669 return 0;
670 es = (double)(play_wave_format->format.wf.nSamplesPerSec
671 * play_wave_format->format.wf.nBlockAlign)
672 * (get_current_calender_time() - play_start_time);
673 if(es > play_counter)
674 return 0;
675 return 1;
676 }
677
audriv_play_samples(void)678 long audriv_play_samples(void)
679 /* ���߱�����Υ���ץ���֤��֤��ޤ���
680 */
681 {
682 #if 1 /* audriv_play_samples() */
683 return reset_samples + calculate_play_samples();
684 #else
685 MMRESULT status;
686 int sample;
687
688 wave_time_info->wType = TIME_SAMPLES;
689 status = waveOutGetPosition(play_wave_format->hWave,
690 wave_time_info,
691 sizeof(MMTIME));
692 if(status != MMSYSERR_NOERROR)
693 {
694 audriv_err(mme_error_code_string(status));
695 return -1;
696 }
697 sample = (int)wave_time_info->u.sample;
698 if(sample < 0)
699 return 0;
700 return (long)sample;
701 #endif
702 }
703
audriv_get_filled(void)704 long audriv_get_filled(void)
705 /* �����ǥ����Хåե���ΥХ��ȿ����֤��ޤ���
706 * ���顼�ξ��� -1 ���֤��ޤ���
707 */
708 {
709 double es;
710
711 if(play_counter <= 0)
712 return 0;
713 es = (double)(play_wave_format->format.wf.nSamplesPerSec *
714 play_wave_format->format.wf.nBlockAlign)
715 * (get_current_calender_time() - play_start_time);
716 if(es > play_counter)
717 return 0;
718 return play_counter - (long)es;
719 }
720
audriv_available_encodings(int * n_ret)721 const long *audriv_available_encodings(int *n_ret)
722 /* �ޥ����ݡ��Ȥ��Ƥ��뤹�٤Ƥ���沽�ꥹ�Ȥ��֤��ޤ���n_ret �ˤ�
723 * ���μ���ο������֤���ޤ�����沽��魯����ͤ�
724 * aenc.h ����������Ƥ��� enum audio_encoding_types ���ͤǤ���
725 * �֤��ͤ� free ���ƤϤʤ�ޤ���
726 */
727 {
728 static const long encoding_list[] =
729 {
730 AENC_UNSIGBYTE, /* WAVE_FORMAT_PCM */
731 AENC_G711_ULAW, /* WAVE_FORMAT_MULAW */
732 AENC_SIGWORDL, /* WAVE_FORMAT_PCM */
733 };
734
735 *n_ret = 3;
736 return encoding_list;
737 }
738
audriv_available_sample_rates(int * n_ret)739 const long *audriv_available_sample_rates(int *n_ret)
740 /* �ޥ����ݡ��Ȥ��Ƥ��뤹�٤ƤΥ���ץ�졼�ȤΥꥹ�Ȥ��֤��ޤ���
741 * n_ret �ˤϤ��μ���ο������֤���ޤ���
742 * �֤��ͤ� free ���ƤϤʤ�ޤ���
743 */
744 {
745 static const long sample_rates[] =
746 {
747 5512, 6615, 8000, 9600, 11025, 16000, 18900, 22050, 32000, 37800,
748 44100, 48000
749 };
750 *n_ret = 12;
751 return sample_rates;
752 }
753
audriv_available_channels(int * n_ret)754 const long *audriv_available_channels(int *n_ret)
755 /* �ޥ����ݡ��Ȥ��Ƥ��뤹�٤ƤΥ���ͥ���Υꥹ�Ȥ��֤��ޤ���
756 * n_ret �ˤϤ��μ���ο������֤���ޤ���
757 * �֤��ͤ� free ���ƤϤʤ�ޤ���
758 */
759 {
760 static const long channels[] = {1, 2};
761 *n_ret = 2;
762 return channels;
763 }
764
set_wave_format_encoding(PCMWAVEFORMAT * format,long encoding)765 static void set_wave_format_encoding(PCMWAVEFORMAT *format, long encoding)
766 {
767 switch(encoding)
768 {
769 case AENC_UNSIGBYTE:
770 format->wf.wFormatTag = WAVE_FORMAT_PCM;
771 format->wBitsPerSample = 8;
772 break;
773 case AENC_G711_ULAW:
774 format->wf.wFormatTag = WAVE_FORMAT_MULAW;
775 format->wBitsPerSample = 8;
776 break;
777 case AENC_G711_ALAW:
778 format->wf.wFormatTag = WAVE_FORMAT_ALAW;
779 format->wBitsPerSample = 8;
780 break;
781 case AENC_SIGWORDL:
782 format->wf.wFormatTag = WAVE_FORMAT_PCM;
783 format->wBitsPerSample = 16;
784 break;
785 case AENC_UNSIGWORDL:
786 format->wf.wFormatTag = WAVE_FORMAT_PCM;
787 format->wBitsPerSample = 16;
788 break;
789 }
790 format->wf.nBlockAlign =
791 format->wf.nChannels * (format->wBitsPerSample / 8);
792 }
793
audriv_set_play_encoding(long encoding)794 Bool audriv_set_play_encoding(long encoding)
795 /* audio ���ջ�����沽��������ꤷ�ޤ���
796 * ������������ True ���Ԥ������� False ���֤��ޤ���
797 */
798 {
799 int i, n;
800 const long *enc;
801
802 enc = audriv_available_encodings(&n);
803 for(i = 0; i < n; i++)
804 if(enc[i] == encoding)
805 {
806 set_wave_format_encoding(&play_wave_format->format, encoding);
807 return True;
808 }
809 return False;
810 }
811
audriv_set_play_sample_rate(long sample_rate)812 Bool audriv_set_play_sample_rate(long sample_rate)
813 /* audio ���ջ��Υ���ץ�졼�Ȥ���ꤷ�ޤ���
814 * ������������ True ���Ԥ������� False ���֤��ޤ���
815 */
816 {
817 int i, n;
818 const long *r;
819
820 r = audriv_available_sample_rates(&n);
821 for(i = 0; i < n; i++)
822 if(r[i] == sample_rate)
823 {
824 play_wave_format->format.wf.nSamplesPerSec = sample_rate;
825 play_wave_format->format.wf.nAvgBytesPerSec =
826 play_wave_format->format.wf.nSamplesPerSec *
827 play_wave_format->format.wf.nBlockAlign;
828 return True;
829 }
830 return False;
831 }
832
audriv_set_play_channels(long channels)833 Bool audriv_set_play_channels(long channels)
834 /* �����ѤΥ���ͥ�������ꤷ�ޤ���
835 * ���Ԥ���� False ���֤������������ True ���֤��ޤ���
836 */
837 {
838 int i, n;
839 const long *c = audriv_available_channels(&n);
840
841 for(i = 0; i < n; i++)
842 if(channels == c[i])
843 {
844 play_wave_format->format.wf.nChannels = channels;
845 play_wave_format->format.wf.nBlockAlign =
846 channels * (play_wave_format->format.wBitsPerSample / 8);
847 play_wave_format->format.wf.nAvgBytesPerSec =
848 play_wave_format->format.wf.nSamplesPerSec *
849 play_wave_format->format.wf.nBlockAlign;
850 return True;
851 }
852 return False;
853 }
854
audriv_wait_play(void)855 void audriv_wait_play(void)
856 /* CPU �ѥ��ϲ�ʤ��褦�ˤ��뤿��ˡ����Ū����ߤ��ޤ���*/
857 {
858 mmeWaitForCallbacks();
859 }
860