1 /* Sound module for Koules/2 2 * 3 * This module loads the RAW sample datas and plays it 4 */ 5 6 #define INCL_OS2MM 7 #define INCL_DOSPROCESS 8 #define INCL_DOSSEMAPHORES 9 #include <os2.h> 10 #include <os2me.h> 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <fcntl.h> 15 #include <unistd.h> 16 17 #ifdef DEBUG 18 #include <stdio.h> 19 #endif /* 20 */ 21 22 /* prototypes */ 23 void read_sound (int); 24 25 26 #define NUMBER_OF_COMMANDS 2 27 28 /* RAW sample parameters */ 29 #define SAMPLESPERSEC 8000 30 #define BITSPERSAMPLE 8 31 #define CHANNELS 1 32 33 /* The samples to load */ 34 char *FILENAME[] = 35 { 36 "start.raw", 37 "end.raw", 38 "colize.raw", 39 "destroy1.raw", 40 "destroy2.raw", 41 "creator1.raw", 42 "creator2.raw" 43 }; 44 45 46 #define NUM_SOUNDS (sizeof(FILENAME)/sizeof(char*)) 47 48 49 signed char *sound_buffer[NUM_SOUNDS]; 50 51 int sound_size[NUM_SOUNDS]; 52 53 #define fragsize 512 54 55 typedef struct pls 56 { 57 58 ULONG ulCommand; 59 60 ULONG ulOperandOne; 61 62 ULONG ulOperandTwo; 63 64 ULONG ulOperandThree; 65 66 } 67 PLAY_LIST_STRUCTURE; 68 69 70 /* This is the memory playlist we'll be using */ 71 PLAY_LIST_STRUCTURE PlayList[NUMBER_OF_COMMANDS] = 72 { 73 74 DATA_OPERATION, 0, 0, 0, /* play command */ 75 EXIT_OPERATION, 0, 0, 0 /* terminate command */ 76 }; 77 78 79 80 BOOL soundPlaying = FALSE; 81 82 HEV hevSoundEvent; 83 84 MCI_OPEN_PARMS mciOpenParameters; /* Open structure. */ 85 86 MCI_WAVE_SET_PARMS mwspWaveFormParameters; /* Waveform parameters. */ 87 88 USHORT usSoundDeviceID; /* device ID */ 89 90 TID tidSoundThread; /* sound-thread ID */ 91 92 93 int fd[2]; /* for unnamed pipe */ 94 95 int soundfd; 96 97 int wavtoPlay; 98 99 100 extern int sound; 101 102 103 /* experimental real-time mixing code */ 104 #ifdef 0 105 void 106 __play_sound (void) 107 { 108 109 char k; 110 111 int i, j; 112 113 int terminate = -1; 114 115 int playing[16]; /* sound numbers that we are playing */ 116 117 int position[16]; /* Current position in each file */ 118 119 int playnum = 0; /* number of sounds currently being played */ 120 121 int finalBuf = 0; 122 123 signed char final[10 * fragsize]; /* 10 buffers */ 124 125 int premix[fragsize]; 126 127 128 char *sample; 129 130 ULONG mciRC; 131 132 133 #ifdef DEBUG 134 printf ("starting SoundThread\n"); 135 136 #endif /* 137 */ 138 fcntl (soundfd, F_SETFL, O_NDELAY); 139 140 for (;;) 141 142 { 143 144 i = read (soundfd, &k, sizeof (k)); 145 146 #ifdef DEBUG 147 printf ("i=%d, k=%d, playnum=%d\n", i, (int) k, (int) playnum); 148 149 #endif /* 150 */ 151 if (i == 0) /* EOF */ 152 153 _endthread (); 154 155 156 if (i != -1) /* there was something in the pipe */ 157 158 { 159 160 #ifdef DEBUG 161 printf ("Just read a %d from pipe\n", (int) k); 162 163 #endif /* 164 */ 165 if (k < 0) 166 167 { 168 169 terminate = 0; 170 171 } 172 173 else 174 175 { 176 177 if (sound_size[(int) k] > 0 && playnum < 16) 178 179 { 180 181 position[playnum] = 0; 182 183 playing[playnum++] = k; 184 185 #ifdef SOUND 186 printf ("Adding sound %d to queue, total %d\n", (int) k, playnum); 187 188 #endif /* 189 */ 190 } 191 192 } 193 194 } 195 196 197 /* terminate a sound if necessary */ 198 for (i = 0; i < playnum; i++) 199 200 { 201 202 if ((position[i] == sound_size[playing[i]]) || (terminate == i)) 203 204 { 205 206 #ifdef SOUND 207 printf ("removing %d\n", (int) i); 208 209 #endif /* 210 */ 211 memmove (playing + i, 212 playing + i + 1, 213 (playnum - i) * sizeof (int)); 214 215 memmove (position + i, 216 position + i + 1, 217 (playnum - i) * sizeof (int)); 218 219 playnum--; 220 221 i--; 222 223 }; 224 225 }; 226 227 228 if (playnum) /* play sound */ 229 230 { 231 232 for (i = 0; i < playnum; i++) 233 234 { 235 236 #ifdef SOUND 237 printf ("sample %d at position %d\n", playing[i], position[i]); 238 239 #endif /* 240 */ 241 memset (premix, 0, sizeof (premix)); 242 243 244 sample = sound_buffer[playing[i]] + position[i] * fragsize; 245 246 for (j = 0; j < fragsize; j++) 247 248 { 249 250 premix[j] += *(sample + j); 251 252 }; 253 254 position[i]++; 255 256 }; 257 258 for (i = 0; i < fragsize; i++) 259 { 260 261 final[i + finalBuf * fragsize] = (premix[i] > 255) ? 255 : 262 (premix[i] < -256 ? 0 : (premix[i] >> 1) + 128); 263 264 /* final[i+finalBuf*fragsize] ^=0x80; */ 265 } 266 267 } 268 269 else 270 271 { 272 273 /* 274 We have no sounds to play 275 Just fill the buffer with silence and maybe play it 276 */ 277 memset (final + finalBuf * fragsize, 0, fragsize); 278 279 } 280 281 282 283 /* setup wave file in playlist */ 284 PlayList[0].ulOperandOne = (ULONG) (final + finalBuf * fragsize); 285 286 PlayList[0].ulOperandTwo = fragsize; 287 288 289 mciRC = mciSendCommand (usSoundDeviceID, 290 MCI_STOP, 291 MCI_WAIT, 292 (PVOID) & mciOpenParameters, 293 0); 294 295 296 if (mciRC != 0) 297 { 298 299 sound = FALSE; 300 301 #ifdef DEBUG 302 printf ("Error MCI_STOP device\n"); 303 304 #endif /* 305 */ 306 } 307 308 309 /* rewind sound */ 310 mciRC = mciSendCommand (usSoundDeviceID, 311 MCI_SEEK, 312 MCI_TO_START, 313 (PVOID) & mciOpenParameters, 314 0); 315 316 317 /* play sound */ 318 mciRC = mciSendCommand (usSoundDeviceID, 319 MCI_PLAY, 320 MCI_WAIT, 321 (PVOID) & mciOpenParameters, 322 0); 323 324 325 if (mciRC != 0) 326 { 327 328 sound = FALSE; 329 330 #ifdef DEBUG 331 printf ("Error MCI_PLAY device\n"); 332 333 #endif /* 334 */ 335 } 336 337 338 finalBuf++; 339 340 if (finalBuf == 10) 341 finalBuf = 0; 342 343 344 } 345 346 347 _endthread (); 348 349 } 350 351 352 void 353 play_sound (int k) 354 { 355 356 char c; 357 358 359 c = k; 360 361 if (sound) 362 play_sound(int k)363 write (fd[1], &c, sizeof (c)); 364 365 } 366 367 368 #endif /* 369 */ 370 371 372 int 373 play_sound (int k) 374 { 375 376 ULONG mciRC; 377 378 379 if (TRUE) 380 { 381 382 wavtoPlay = k; 383 384 385 mciRC = mciSendCommand (usSoundDeviceID, 386 MCI_STOP, 387 MCI_WAIT, 388 (PVOID) & mciOpenParameters, 389 0); 390 391 if (mciRC != 0) 392 { 393 394 sound = FALSE; 395 396 #ifdef DEBUG 397 printf ("Error MCI_STOP device\n"); 398 399 #endif /* 400 */ 401 } 402 403 404 /* rewind sound */ 405 mciRC = mciSendCommand (usSoundDeviceID, 406 MCI_SEEK, 407 MCI_TO_START, 408 (PVOID) & mciOpenParameters, 409 0); 410 411 412 if (mciRC != 0) 413 { 414 415 sound = FALSE; 416 417 #ifdef DEBUG 418 printf ("Error MCI_SEEK device\n"); 419 420 #endif /* 421 */ 422 } 423 424 425 __play_sound(void)426 DosPostEventSem (hevSoundEvent); 427 428 } 429 430 431 return 0; 432 433 } 434 435 436 /* Tries to play sound k, if anything fails, sound will be disabled. */ 437 void 438 __play_sound (void) 439 { 440 441 int k; 442 443 ULONG mciRC; 444 445 ULONG ulCount; 446 447 448 while (TRUE) 449 { 450 451 DosWaitEventSem (hevSoundEvent, SEM_INDEFINITE_WAIT); 452 453 soundPlaying = TRUE; 454 455 k = wavtoPlay; 456 457 458 PlayList[0].ulOperandOne = (ULONG) sound_buffer[k]; 459 460 PlayList[0].ulOperandTwo = (sound_size[k] + 1) * fragsize; 461 462 463 /* play sound */ 464 mciRC = mciSendCommand (usSoundDeviceID, 465 MCI_PLAY, 466 MCI_WAIT, 467 (PVOID) & mciOpenParameters, 468 0); 469 470 471 if (mciRC != 0) 472 { 473 474 sound = FALSE; 475 476 #ifdef DEBUG 477 printf ("Error MCI_PLAY device\n"); 478 479 #endif /* 480 */ 481 482 } 483 484 485 soundPlaying = FALSE; 486 init_sound(void)487 DosResetEventSem (hevSoundEvent, &ulCount); 488 489 } 490 491 492 _endthread (); 493 494 } 495 496 497 498 /* opens the device and reads the samples */ 499 void 500 init_sound (void) 501 { 502 503 int i; 504 505 506 ULONG mciRC; 507 508 ULONG ulOpenFlags = (MCI_WAIT | MCI_OPEN_PLAYLIST | 509 MCI_OPEN_TYPE_ID); 510 511 512 /* Open the correct waveform device for the waves with MCI_OPEN */ 513 mciOpenParameters.pszDeviceType = (PSZ) 514 MAKEULONG (MCI_DEVTYPE_WAVEFORM_AUDIO, 1); 515 516 517 /* The address of the buffer containing the waveform file. */ 518 mciOpenParameters.pszElementName = (PSZ) & PlayList[0]; 519 520 521 mciOpenParameters.hwndCallback = (HWND) NULL; 522 523 mciOpenParameters.pszAlias = (CHAR) NULL; 524 525 526 /* Open the waveform file in the playlist mode. */ 527 mciRC = mciSendCommand (0, 528 MCI_OPEN, 529 ulOpenFlags, 530 (PVOID) & mciOpenParameters, 531 0); 532 533 534 if (mciRC != 0) 535 { 536 537 sound = FALSE; 538 539 #ifdef DEBUG 540 printf ("Error opening device\n"); 541 542 #endif /* 543 */ 544 return; 545 546 } 547 548 549 /* save device ID */ 550 usSoundDeviceID = mciOpenParameters.usDeviceID; 551 552 553 /* Fill the structure with zeros. */ 554 memset (&mwspWaveFormParameters, 0, sizeof (mwspWaveFormParameters)); 555 556 557 /* copy samps/sec */ 558 mwspWaveFormParameters.ulSamplesPerSec = SAMPLESPERSEC; 559 560 mwspWaveFormParameters.usBitsPerSample = BITSPERSAMPLE; 561 562 mwspWaveFormParameters.usChannels = CHANNELS; 563 564 mwspWaveFormParameters.ulAudio = MCI_SET_AUDIO_ALL; 565 566 567 mciRC = mciSendCommand (usSoundDeviceID, 568 MCI_SET, 569 (MCI_WAIT | 570 MCI_WAVE_SET_SAMPLESPERSEC | 571 MCI_WAVE_SET_BITSPERSAMPLE | 572 MCI_WAVE_SET_CHANNELS), 573 (PVOID) & mwspWaveFormParameters, 574 0); 575 576 if (mciRC != 0) 577 { 578 579 sound = FALSE; 580 581 #ifdef DEBUG 582 printf ("Error setting device\n"); 583 584 #endif /* 585 */ 586 return; 587 588 } 589 590 591 #ifdef DEBUG 592 printf ("%d sounds to be loaded\n", (int) NUM_SOUNDS); 593 594 #endif /* 595 */ 596 597 /* read the samples */ 598 for (i = 0; i < NUM_SOUNDS; i++) 599 read_sound (i); 600 601 602 /* open unnamed pipe */ 603 if ((pipe (fd)) != 0) 604 { 605 606 #ifdef DEBUG 607 printf ("error creating pipe\n"); 608 609 #endif /* 610 */ 611 } 612 613 614 /* make the read pipe, non-blocking */ 615 fcntl (fd[0], F_SETFL, O_NDELAY); 616 617 fcntl (fd[1], F_SETFL, O_NDELAY); read_sound(int k)618 619 620 soundfd = fd[0]; 621 622 623 DosCreateEventSem (NULL, &hevSoundEvent, 0, FALSE); 624 625 /* start soundthread */ 626 tidSoundThread = _beginthread ((void *) __play_sound, NULL, 16384L, NULL); 627 628 DosSetPriority (PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tidSoundThread); 629 630 } 631 632 633 634 void 635 read_sound (int k) 636 { 637 638 int fd, size, i; 639 640 char filename[20]; 641 642 643 #ifdef DEBUG 644 printf ("Opening no.%d %s\n", k, FILENAME[k]); 645 646 #endif /* 647 */ 648 sprintf (filename, "sounds/%s", FILENAME[k]); 649 650 fd = open (filename, O_RDONLY); 651 652 if (fd <= 0) 653 654 { 655 656 #ifdef DEBUG 657 fprintf (stderr, "koules.sndsrv: The sound %s number %i could not be opened\n", FILENAME[k], k); 658 659 #endif /* 660 */ 661 sound_size[k] = -1; 662 663 return; 664 665 }; 666 667 size = lseek (fd, 0, SEEK_END); 668 669 sound_size[k] = (size / fragsize) + 1; 670 671 #ifdef DEBUG 672 printf ("size = %d\n", (int) sound_size[k]); 673 674 #endif /* 675 */ 676 sound_buffer[k] = malloc ((sound_size[k] + 1) * fragsize); 677 close_device(void)678 lseek (fd, 0, SEEK_SET); 679 680 read (fd, sound_buffer[k], size); 681 682 close (fd); 683 684 685 /* 686 for (i = 0; i < size; i++) 687 sound_buffer[k][i] ^= 0x80; 688 */ 689 690 /* fill rest of buffer with 0's */ 691 memset (sound_buffer[k] + size, 0, sound_size[k] * fragsize - size); 692 693 } 694 695 696 697 void 698 close_device (void) 699 { 700 play_wave(USHORT usSoundFileID)701 MCI_GENERIC_PARMS mciGenericParms; 702 703 704 /* close devide */ 705 mciSendCommand (mciOpenParameters.usDeviceID, 706 MCI_CLOSE, 707 MCI_WAIT, 708 (PVOID) & mciGenericParms, 709 (ULONG) NULL); 710 711 /* close the pipe */ 712 close (fd[0]); 713 714 close (fd[1]); 715 716 } 717 718 719 720 #ifdef DEBUG 721 VOID play_wave (USHORT usSoundFileID) 722 { 723 724 ULONG mciRC; 725 726 727 /* setup wave file in playlist */ 728 PlayList[0].ulOperandOne = (ULONG) sound_buffer[usSoundFileID]; 729 730 PlayList[0].ulOperandTwo = (sound_size[usSoundFileID] + 1) * fragsize; 731 732 733 mciRC = mciSendCommand (usSoundDeviceID, 734 MCI_STOP, 735 MCI_WAIT, 736 (PVOID) & mciOpenParameters, 737 0); 738 739 740 if (mciRC != 0) 741 { 742 743 sound = FALSE; 744 745 #ifdef DEBUG 746 printf ("Error MCI_STOP device\n"); 747 748 #endif /* 749 */ 750 } 751 752 753 /* rewind sound */ 754 mciRC = mciSendCommand (usSoundDeviceID, 755 MCI_SEEK, 756 MCI_TO_START, 757 (PVOID) & mciOpenParameters, 758 0); 759 760 761 if (mciRC != 0) 762 { 763 764 sound = FALSE; 765 766 #ifdef DEBUG 767 printf ("Error MCI_SEEK device\n"); 768 769 #endif /* 770 */ 771 } 772 773 774 /* play sound */ 775 mciRC = mciSendCommand (usSoundDeviceID, 776 MCI_PLAY, 777 MCI_WAIT, 778 (PVOID) & mciOpenParameters, 779 0); 780 main()781 782 if (mciRC != 0) 783 { 784 785 sound = FALSE; 786 787 #ifdef DEBUG 788 printf ("Error MCI_PLAY device\n"); 789 790 #endif /* 791 */ 792 } 793 794 } 795 796 #endif /* 797 */ 798 799 800 #ifdef DEBUG 801 int sound = TRUE; 802 803 804 int 805 main () 806 { 807 808 init_sound (); 809 810 811 /* play_wave(1); */ 812 play_sound (0); 813 814 815 play_sound (1); 816 817 play_sound (2); 818 819 play_sound (3); 820 821 play_sound (4); 822 823 play_sound (5); 824 825 while (1); 826 827 828 close_device (); 829 830 831 return 0; 832 833 } 834 835 #endif /* 836 */ 837