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