comparison src/nas.c @ 613:023b83f4e54b

[xemacs-hg @ 2001-06-10 10:42:16 by ben] ------ signal-code changes ------ data.c, device-tty.c, emacs.c, floatfns.c, linuxplay.c, nas.c, process-unix.c, signal.c, sunplay.c, sysdep.c, syssignal.h: use EMACS_SIGNAL everywhere instead of playing preprocessing games with signal(). s\windowsnt.h, s\mingw32.h, syssignal.h: Remove mswindows signal code from s+m headers and move to syssignal.h as one of the five ways of signal handling, instead of playing preprocessing games. fileio.c, sysdep.c: Rename sys_do_signal to qxe_reliable_signal. signal.c, process-unix.c, profile.c: Create set_timeout_signal(); use instead of just EMACS_SIGNAL to establish a signal handler on a timeout signal; this does special things under Cygwin. nt.c: Eliminate term_ntproc(), which is blank; used as a SIGABRT handler, which was wrong anyway. nt.c, win32.c: Move signal code from nt.c to win32.c, since Cygwin needs it too when dealing with timeout signals. s\cygwin32.h: Define CYGWIN_BROKEN_SIGNALS. ------ other changes ------ s\mingw32.h: Fix problems with NOT_C_CODE being in the wrong place and excluding defines needed when building Makefile.in.in. filelock.c, mule-canna.c, mule-ccl.c, mule-ccl.h, ralloc.c, unexalpha.c, unexapollo.c, unexcw.c, unexelfsgi.c, unexnt.c, unexsni.c, s\aix3-1.h, s\bsd4-1.h, s\bsd4-2.h, s\bsd4-3.h, s\cxux.h, s\cygwin32.h, s\dgux.h, s\dgux5-4r2.h, s\dgux5-4r3.h, s\dgux5-4r4.h, s\ewsux5r4.h, s\gnu.h, s\hpux.h, s\iris3-5.h, s\iris3-6.h, s\irix3-3.h, s\linux.h, s\mingw32.h, s\newsos5.h, s\nextstep.h, s\ptx.h, s\riscix1-1.h, s\riscix1-2.h, s\rtu.h, s\sco4.h, s\sco5.h, s\template.h, s\ultrix.h, s\umax.h, s\umips.h, s\unipl5-0.h, s\unipl5-2.h, s\usg5-0.h, s\usg5-2-2.h, s\usg5-2.h, s\usg5-3.h, s\usg5-4.h, s\windowsnt.h, s\xenix.h: Rename 'GNU Emacs' to XEmacs in the copyright and comments. nas.c: Stylistic cleanup. Avoid preprocessing games with names such as play_sound_file. ------ signal-code changes ------ data.c, device-tty.c, emacs.c, floatfns.c, linuxplay.c, nas.c, process-unix.c, signal.c, sunplay.c, sysdep.c, syssignal.h: use EMACS_SIGNAL everywhere instead of playing preprocessing games with signal(). s\windowsnt.h, s\mingw32.h, syssignal.h: Remove mswindows signal code from s+m headers and move to syssignal.h as one of the five ways of signal handling, instead of playing preprocessing games. fileio.c, sysdep.c: Rename sys_do_signal to qxe_reliable_signal. signal.c, process-unix.c, profile.c: Create set_timeout_signal(); use instead of just EMACS_SIGNAL to establish a signal handler on a timeout signal; this does special things under Cygwin. nt.c: Eliminate term_ntproc(), which is blank; used as a SIGABRT handler, which was wrong anyway. nt.c, win32.c: Move signal code from nt.c to win32.c, since Cygwin needs it too when dealing with timeout signals. s\cygwin32.h: Define CYGWIN_BROKEN_SIGNALS. ------ other changes ------ s\mingw32.h: Fix problems with NOT_C_CODE being in the wrong place and excluding defines needed when building Makefile.in.in. filelock.c, mule-canna.c, mule-ccl.c, mule-ccl.h, ralloc.c, unexalpha.c, unexapollo.c, unexcw.c, unexelfsgi.c, unexnt.c, unexsni.c, s\aix3-1.h, s\bsd4-1.h, s\bsd4-2.h, s\bsd4-3.h, s\cxux.h, s\cygwin32.h, s\dgux.h, s\dgux5-4r2.h, s\dgux5-4r3.h, s\dgux5-4r4.h, s\ewsux5r4.h, s\gnu.h, s\hpux.h, s\iris3-5.h, s\iris3-6.h, s\irix3-3.h, s\linux.h, s\mingw32.h, s\newsos5.h, s\nextstep.h, s\ptx.h, s\riscix1-1.h, s\riscix1-2.h, s\rtu.h, s\sco4.h, s\sco5.h, s\template.h, s\ultrix.h, s\umax.h, s\umips.h, s\unipl5-0.h, s\unipl5-2.h, s\usg5-0.h, s\usg5-2-2.h, s\usg5-2.h, s\usg5-3.h, s\usg5-4.h, s\windowsnt.h, s\xenix.h: Rename 'GNU Emacs' to XEmacs in the copyright and comments. nas.c: Stylistic cleanup. Avoid preprocessing games with names such as play_sound_file. xemacs-faq.texi: Update sections on Windows and MacOS availability. alist.el, apropos.el, autoload.el, bytecomp.el, cl-compat.el, cl-extra.el, cl-macs.el, cl-seq.el, cl.el, cmdloop.el, cus-edit.el, derived.el, gpm.el, itimer.el, lisp-mode.el, shadow.el, version.el, wid-browse.el: Rename 'GNU Emacs' to XEmacs in the copyright. Fix other references to GNU Emacs that should be XEmacs or just Emacs. files.el: Fix warning. simple.el: transpose-line-up/down will now move the region up or down by a line if active. cvtmail.c, fakemail.c, gnuserv.c, gnuserv.h, gnuslib.c, make-msgfile.c, make-path.c, pop.c, pop.h, profile.c, tcp.c: Rename 'GNU Emacs' to XEmacs in the copyright. Fix comments in similar ways. digest-doc.c, sorted-doc.c: Fix program and author name to reflect XEmacs.
author ben
date Sun, 10 Jun 2001 10:42:39 +0000
parents 183866b06e0b
children 6728e641994e
comparison
equal deleted inserted replaced
612:ff0d9e7facba 613:023b83f4e54b
80 #include <audio/wave.h> 80 #include <audio/wave.h>
81 #include <audio/fileutil.h> 81 #include <audio/fileutil.h>
82 82
83 /* NAS <= 1.2p5 <audio/fileutil.h> doesn't define the NAS_ versions */ 83 /* NAS <= 1.2p5 <audio/fileutil.h> doesn't define the NAS_ versions */
84 #ifndef NAS_LITTLE_ENDIAN 84 #ifndef NAS_LITTLE_ENDIAN
85 #define NAS_LITTLE_ENDIAN LITTLE_ENDIAN 85 # define NAS_LITTLE_ENDIAN LITTLE_ENDIAN
86 #define NAS_BIG_ENDIAN BIG_ENDIAN 86 # define NAS_BIG_ENDIAN BIG_ENDIAN
87 #endif 87 #endif
88 88
89 # define XTOOLKIT 89 #define XTOOLKIT
90 # define XTEVENTS 90 #define XTEVENTS
91 # define ROBUST_PLAY 91 #define ROBUST_PLAY
92 # define CACHE_SOUNDS 92 #define CACHE_SOUNDS
93 93
94 /* 94 /*
95 * For old NAS libraries, force playing to be synchronous 95 * For old NAS libraries, force playing to be synchronous
96 * and declare the long jump point locally. 96 * and declare the long jump point locally.
97 */ 97 */
98 98
99 # if defined (NAS_NO_ERROR_JUMP) 99 #if defined (NAS_NO_ERROR_JUMP)
100 100 # undef XTEVENTS
101 # undef XTEVENTS 101 # include <setjmp.h>
102 102 jmp_buf AuXtErrorJump;
103 # include <setjmp.h> 103 #endif
104 jmp_buf AuXtErrorJump;
105 # endif
106
107 # define play_sound_file nas_play_sound_file
108 # define play_sound_data nas_play_sound_data
109 # define wait_for_sounds nas_wait_for_sounds
110 # define init_play nas_init_play
111 # define close_down_play nas_close_down_play
112 104
113 #ifdef XTOOLKIT 105 #ifdef XTOOLKIT
114 # include <X11/Intrinsic.h> 106 # include <X11/Intrinsic.h>
115 # include <audio/Xtutil.h> 107 # include <audio/Xtutil.h>
116 #endif 108 #endif
117 109
118 #if defined (ROBUST_PLAY) 110 #if defined (ROBUST_PLAY)
119 static AuBool CatchIoErrorAndJump (AuServer *aud); 111 static AuBool CatchIoErrorAndJump (AuServer *aud);
120 static AuBool CatchErrorAndJump (AuServer *aud, AuErrorEvent *event); 112 static AuBool CatchErrorAndJump (AuServer *aud, AuErrorEvent *event);
137 #else 129 #else
138 static Extbyte *aud_server; 130 static Extbyte *aud_server;
139 #endif /* XTOOLKIT */ 131 #endif /* XTOOLKIT */
140 132
141 Extbyte * 133 Extbyte *
142 init_play ( 134 nas_init_play (
143 #ifdef XTOOLKIT 135 #ifdef XTOOLKIT
144 Display *display 136 Display *display
145 #else 137 #else
146 Extbyte *server 138 Extbyte *server
147 #endif 139 #endif
148 ); 140 );
149 Extbyte * 141 Extbyte *
150 init_play ( 142 nas_init_play (
151 #ifdef XTOOLKIT 143 #ifdef XTOOLKIT
152 Display *display 144 Display *display
153 #else 145 #else
154 Extbyte *server 146 Extbyte *server
155 #endif 147 #endif
167 159
168 aud_server = server; 160 aud_server = server;
169 #endif 161 #endif
170 162
171 #ifdef ROBUST_PLAY 163 #ifdef ROBUST_PLAY
172 old_sigpipe = signal (SIGPIPE, sigpipe_handle); 164 old_sigpipe = EMACS_SIGNAL (SIGPIPE, sigpipe_handle);
173 if (setjmp (AuXtErrorJump)) 165 if (setjmp (AuXtErrorJump))
174 { 166 {
175 signal (SIGPIPE, old_sigpipe); 167 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
176 #ifdef emacs 168 #ifdef emacs
177 start_interrupts (); 169 start_interrupts ();
178 #endif 170 #endif
179 return "error in NAS"; 171 return "error in NAS";
180 } 172 }
193 start_interrupts (); 185 start_interrupts ();
194 #endif 186 #endif
195 if (!aud) 187 if (!aud)
196 { 188 {
197 #ifdef ROBUST_PLAY 189 #ifdef ROBUST_PLAY
198 signal (SIGPIPE, old_sigpipe); 190 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
199 #endif 191 #endif
200 if (err_message == NULL) 192 if (err_message == NULL)
201 return "Can't connect to audio server"; 193 return "Can't connect to audio server";
202 else 194 else
203 return err_message; 195 return err_message;
220 #ifdef CACHE_SOUNDS 212 #ifdef CACHE_SOUNDS
221 AuSetCloseDownMode (aud, AuCloseDownRetainPermanent, NULL); 213 AuSetCloseDownMode (aud, AuCloseDownRetainPermanent, NULL);
222 #endif 214 #endif
223 215
224 #ifdef ROBUST_PLAY 216 #ifdef ROBUST_PLAY
225 signal (SIGPIPE, old_sigpipe); 217 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
226 #endif 218 #endif
227 219
228 sounds_in_play = 0; 220 sounds_in_play = 0;
229 221
230 return NULL; 222 return NULL;
231 } 223 }
232 224
233 static void 225 static void
234 close_down_play (void) 226 nas_close_down_play (void)
235 227
236 { 228 {
237 AuCloseServer (aud); 229 AuCloseServer (aud);
238 sound_warn ("disconnected from audio server"); 230 sound_warn ("disconnected from audio server");
239 } 231 }
327 319
328 } 320 }
329 #endif /* CACHE_SOUNDS */ 321 #endif /* CACHE_SOUNDS */
330 322
331 323
332 void wait_for_sounds (void); 324 void nas_wait_for_sounds (void);
333 void 325 void
334 wait_for_sounds (void) 326 nas_wait_for_sounds (void)
335 327
336 { 328 {
337 AuEvent ev; 329 AuEvent ev;
338 330
339 while (sounds_in_play>0) 331 while (sounds_in_play>0)
341 AuNextEvent (aud, AuTrue, &ev); 333 AuNextEvent (aud, AuTrue, &ev);
342 AuDispatchEvent (aud, &ev); 334 AuDispatchEvent (aud, &ev);
343 } 335 }
344 } 336 }
345 337
346 int play_sound_file (Extbyte *sound_file, int volume); 338 int nas_play_sound_file (Extbyte *sound_file, int volume);
347 int 339 int
348 play_sound_file (Extbyte *sound_file, 340 nas_play_sound_file (Extbyte *sound_file,
349 int volume) 341 int volume)
350 { 342 {
351 SIGTYPE (*old_sigpipe) (int); 343 SIGTYPE (*old_sigpipe) (int);
352 344
353 #ifdef ROBUST_PLAY 345 #ifdef ROBUST_PLAY
354 old_sigpipe=signal (SIGPIPE, sigpipe_handle); 346 old_sigpipe = EMACS_SIGNAL (SIGPIPE, sigpipe_handle);
355 if (setjmp (AuXtErrorJump)) 347 if (setjmp (AuXtErrorJump))
356 { 348 {
357 signal (SIGPIPE, old_sigpipe); 349 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
358 return 0; 350 return 0;
359 } 351 }
360 #endif 352 #endif
361 353
362 if (aud==NULL) { 354 if (aud==NULL)
363 if (aud_server != NULL) 355 {
364 { 356 if (aud_server != NULL)
365 Extbyte *m; 357 {
366 /* attempt to reconect */ 358 Extbyte *m;
367 if ((m=init_play (aud_server))!= NULL) 359 /* attempt to reconect */
368 { 360 if ((m = nas_init_play (aud_server)) != NULL)
369 361 {
370 #ifdef ROBUST_PLAY 362
371 signal (SIGPIPE, old_sigpipe); 363 #ifdef ROBUST_PLAY
372 #endif 364 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
373 return 0; 365 #endif
374 } 366 return 0;
375 } 367 }
376 else 368 }
377 { 369 else
378 sound_warn ("Attempt to play with no audio init\n"); 370 {
379 #ifdef ROBUST_PLAY 371 sound_warn ("Attempt to play with no audio init\n");
380 signal (SIGPIPE, old_sigpipe); 372 #ifdef ROBUST_PLAY
381 #endif 373 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
382 return 0; 374 #endif
383 } 375 return 0;
384 } 376 }
377 }
385 378
386 #ifndef CACHE_SOUNDS 379 #ifndef CACHE_SOUNDS
387 sounds_in_play++; 380 sounds_in_play++;
388 AuSoundPlayFromFile (aud, 381 AuSoundPlayFromFile (aud,
389 sound_file, 382 sound_file,
401 Sound s; 394 Sound s;
402 395
403 if ((s = SoundOpenFileForReading (sound_file))==NULL) 396 if ((s = SoundOpenFileForReading (sound_file))==NULL)
404 { 397 {
405 #ifdef ROBUST_PLAY 398 #ifdef ROBUST_PLAY
406 signal (SIGPIPE, old_sigpipe); 399 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
407 #endif 400 #endif
408 return 0; 401 return 0;
409 } 402 }
410 403
411 if (SoundComment (s) == NULL || SoundComment (s)[0] == '\0') 404 if (SoundComment (s) == NULL || SoundComment (s)[0] == '\0')
419 412
420 } 413 }
421 #endif /* CACHE_SOUNDS */ 414 #endif /* CACHE_SOUNDS */
422 415
423 #ifndef XTEVENTS 416 #ifndef XTEVENTS
424 wait_for_sounds (); 417 nas_wait_for_sounds ();
425 #else 418 #else
426 if (!NILP (Vsynchronous_sounds)) 419 if (!NILP (Vsynchronous_sounds))
427 { 420 nas_wait_for_sounds ();
428 wait_for_sounds (); 421 #endif
429 } 422
430 #endif 423 #ifdef ROBUST_PLAY
431 424 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
432 #ifdef ROBUST_PLAY
433 signal (SIGPIPE, old_sigpipe);
434 #endif 425 #endif
435 426
436 return 1; 427 return 1;
437 } 428 }
438 429
439 int play_sound_data (UChar_Binary *data, int length, int volume); 430 int nas_play_sound_data (UChar_Binary *data, int length, int volume);
440 int 431 int
441 play_sound_data (UChar_Binary *data, 432 nas_play_sound_data (UChar_Binary *data, int length, int volume)
442 int length,
443 int volume)
444 { 433 {
445 Sound s; 434 Sound s;
446 int offset; 435 int offset;
447 SIGTYPE (*old_sigpipe) (int); 436 SIGTYPE (*old_sigpipe) (int);
448 437
449 #if !defined (XTEVENTS) 438 #if !defined (XTEVENTS)
450 AuEvent ev; 439 AuEvent ev;
451 #endif 440 #endif
452 441
453 #ifdef ROBUST_PLAY 442 #ifdef ROBUST_PLAY
454 old_sigpipe = signal (SIGPIPE, sigpipe_handle); 443 old_sigpipe = EMACS_SIGNAL (SIGPIPE, sigpipe_handle);
455 if (setjmp (AuXtErrorJump) !=0) 444 if (setjmp (AuXtErrorJump) != 0)
456 { 445 {
457 signal (SIGPIPE, old_sigpipe); 446 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
458 return 0; 447 return 0;
459 } 448 }
460 #endif 449 #endif
461 450
462 451
463 if (aud == NULL) { 452 if (aud == NULL) {
464 if (aud_server != NULL) 453 if (aud_server != NULL)
465 { 454 {
466 Extbyte *m; 455 Extbyte *m;
467 /* attempt to reconect */ 456 /* attempt to reconect */
468 if ((m = init_play (aud_server)) != NULL) 457 if ((m = nas_init_play (aud_server)) != NULL)
469 { 458 {
470 #ifdef ROBUST_PLAY 459 #ifdef ROBUST_PLAY
471 signal (SIGPIPE, old_sigpipe); 460 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
472 #endif 461 #endif
473 return 0; 462 return 0;
474 } 463 }
475 } 464 }
476 else 465 else
477 { 466 {
478 sound_warn ("Attempt to play with no audio init\n"); 467 sound_warn ("Attempt to play with no audio init\n");
479 #ifdef ROBUST_PLAY 468 #ifdef ROBUST_PLAY
480 signal (SIGPIPE, old_sigpipe); 469 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
481 #endif 470 #endif
482 return 0; 471 return 0;
483 } 472 }
484 } 473 }
485 474
486 if ((s=SoundOpenDataForReading (data, length))==NULL) 475 if ((s=SoundOpenDataForReading (data, length))==NULL)
487 { 476 {
488 sound_warn ("unknown sound type"); 477 sound_warn ("unknown sound type");
489 #ifdef ROBUST_PLAY 478 #ifdef ROBUST_PLAY
490 signal (SIGPIPE, old_sigpipe); 479 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
491 #endif 480 #endif
492 return 0; 481 return 0;
493 } 482 }
494 483
495 if (SoundFileFormat (s) == SoundFileFormatSnd) 484 if (SoundFileFormat (s) == SoundFileFormatSnd)
504 else 493 else
505 { 494 {
506 sound_warn ("only understand snd and wave files at the moment"); 495 sound_warn ("only understand snd and wave files at the moment");
507 SoundCloseFile (s); 496 SoundCloseFile (s);
508 #ifdef ROBUST_PLAY 497 #ifdef ROBUST_PLAY
509 signal (SIGPIPE, old_sigpipe); 498 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
510 #endif 499 #endif
511 return 0; 500 return 0;
512 } 501 }
513 502
514 #ifndef CACHE_SOUNDS 503 #ifndef CACHE_SOUNDS
524 NULL, 513 NULL,
525 NULL); 514 NULL);
526 #else 515 #else
527 /* Cache the sounds in buckets on the server */ 516 /* Cache the sounds in buckets on the server */
528 517
529 { 518 do_caching_play (s, volume, data+offset);
530 do_caching_play (s, volume, data+offset);
531 }
532 #endif /* CACHE_SOUNDS */ 519 #endif /* CACHE_SOUNDS */
533 520
534 521
535 #ifndef XTEVENTS 522 #ifndef XTEVENTS
536 wait_for_sounds (); 523 nas_wait_for_sounds ();
537 #else 524 #else
538 if (!NILP (Vsynchronous_sounds)) 525 if (!NILP (Vsynchronous_sounds))
539 { 526 nas_wait_for_sounds ();
540 wait_for_sounds ();
541 }
542 #endif 527 #endif
543 528
544 SoundCloseFile (s); 529 SoundCloseFile (s);
545 530
546 #ifdef ROBUST_PLAY 531 #ifdef ROBUST_PLAY
547 signal (SIGPIPE, old_sigpipe); 532 EMACS_SIGNAL (SIGPIPE, old_sigpipe);
548 #endif 533 #endif
549 534
550 return 1; 535 return 1;
551 } 536 }
552 537
568 else 553 else
569 sound_warn ("Audio Server connection broken because of signal"); 554 sound_warn ("Audio Server connection broken because of signal");
570 555
571 #ifdef XTEVENTS 556 #ifdef XTEVENTS
572 #ifdef XTOOLKIT 557 #ifdef XTOOLKIT
573 { 558 AuXtAppRemoveAudioHandler (aud, input_id);
574 AuXtAppRemoveAudioHandler (aud, input_id);
575 }
576 #endif 559 #endif
577 560
578 if (aud) 561 if (aud)
579 AuCloseServer (aud); 562 AuCloseServer (aud);
580 aud = NULL; 563 aud = NULL;
806 /* Data buffer analogs for FileReadS and FileReadL in NAS. */ 789 /* Data buffer analogs for FileReadS and FileReadL in NAS. */
807 790
808 static unsigned short 791 static unsigned short
809 DataReadS (int swapit) 792 DataReadS (int swapit)
810 { 793 {
811 unsigned short us; 794 unsigned short us;
812 795
813 dread(&us, 2, 1); 796 dread(&us, 2, 1);
814 if (swapit) 797 if (swapit)
815 us = FileSwapS(us); 798 us = FileSwapS(us);
816 return us; 799 return us;
817 } 800 }
818 801
819 static AuUint32 802 static AuUint32
820 DataReadL (int swapit) 803 DataReadL (int swapit)
821 { 804 {
822 AuUint32 ul; 805 AuUint32 ul;
823 806
824 dread(&ul, 4, 1); 807 dread(&ul, 4, 1);
825 if (swapit) 808 if (swapit)
826 ul = FileSwapL(ul); 809 ul = FileSwapL(ul);
827 return ul; 810 return ul;
828 } 811 }
829 812
830 static int 813 static int
831 readChunk (RiffChunk *c) 814 readChunk (RiffChunk *c)
832 { 815 {
833 int status; 816 int status;
834 Char_Binary n; 817 Char_Binary n;
835 818
836 if ((status = dread(c, sizeof(RiffChunk), 1))) 819 if ((status = dread(c, sizeof(RiffChunk), 1)))
837 if (NAS_BIG_ENDIAN) 820 if (NAS_BIG_ENDIAN)
838 swapl(&c->ckSize, n); 821 swapl(&c->ckSize, n);
839 822
840 return status; 823 return status;
841 } 824 }
842 825
843 /* A very straight-forward translation of WaveOpenFileForReading to 826 /* A very straight-forward translation of WaveOpenFileForReading to
844 read the wave data from a buffer in memory. */ 827 read the wave data from a buffer in memory. */
845 828
846 static WaveInfo * 829 static WaveInfo *
847 WaveOpenDataForReading (const Char_Binary *data, 830 WaveOpenDataForReading (const Char_Binary *data,
848 int length) 831 int length)
849 { 832 {
850 RiffChunk ck; 833 RiffChunk ck;
851 RIFF_FOURCC fourcc; 834 RIFF_FOURCC fourcc;
852 AuInt32 fileSize; 835 AuInt32 fileSize;
853 WaveInfo *wi; 836 WaveInfo *wi;
854 837
855 838
856 if (!(wi = (WaveInfo *) malloc(sizeof(WaveInfo)))) 839 if (!(wi = (WaveInfo *) malloc(sizeof(WaveInfo))))
857 return NULL; 840 return NULL;
858 841
859 wi->comment = NULL; 842 wi->comment = NULL;
860 wi->dataOffset = wi->format = wi->writing = 0; 843 wi->dataOffset = wi->format = wi->writing = 0;
861 844
862 dopen(data, length); 845 dopen(data, length);
863 846
864 if (!readChunk(&ck) || 847 if (!readChunk(&ck) ||
865 cmpID(&ck.ckID, RIFF_RiffID) || 848 cmpID(&ck.ckID, RIFF_RiffID) ||
866 !readFourcc(&fourcc) || 849 !readFourcc(&fourcc) ||
867 cmpID(&fourcc, RIFF_WaveID)) 850 cmpID(&fourcc, RIFF_WaveID))
851 Err();
852
853 fileSize = PAD2(ck.ckSize) - sizeof(RIFF_FOURCC);
854
855 while (fileSize >= sizeof(RiffChunk))
856 {
857 if (!readChunk(&ck))
868 Err(); 858 Err();
869 859
870 fileSize = PAD2(ck.ckSize) - sizeof(RIFF_FOURCC); 860 fileSize -= sizeof(RiffChunk) + PAD2(ck.ckSize);
871 861
872 while (fileSize >= sizeof(RiffChunk)) 862 /* LIST chunk */
873 { 863 if (!cmpID(&ck.ckID, RIFF_ListID))
874 if (!readChunk(&ck)) 864 {
865 if (!readFourcc(&fourcc))
875 Err(); 866 Err();
876 867
877 fileSize -= sizeof(RiffChunk) + PAD2(ck.ckSize); 868 /* INFO chunk */
878 869 if (!cmpID(&fourcc, RIFF_ListInfoID))
879 /* LIST chunk */
880 if (!cmpID(&ck.ckID, RIFF_ListID))
881 {
882 if (!readFourcc(&fourcc))
883 Err();
884
885 /* INFO chunk */
886 if (!cmpID(&fourcc, RIFF_ListInfoID))
887 { 870 {
888 ck.ckSize -= sizeof(RIFF_FOURCC); 871 ck.ckSize -= sizeof(RIFF_FOURCC);
889 872
890 while (ck.ckSize) 873 while (ck.ckSize)
891 { 874 {
892 RiffChunk c; 875 RiffChunk c;
893 876
894 if (!readChunk(&c)) 877 if (!readChunk(&c))
878 Err();
879
880 /* ICMT chunk */
881 if (!cmpID(&c.ckID, RIFF_InfoIcmtID))
882 {
883 if (!(wi->comment = (Extbyte *) malloc(c.ckSize)) ||
884 !dread(wi->comment, c.ckSize, 1))
895 Err(); 885 Err();
896 886
897 /* ICMT chunk */ 887 if (c.ckSize & 1)
898 if (!cmpID(&c.ckID, RIFF_InfoIcmtID)) 888 dgetc(); /* eat the pad byte */
899 {
900 if (!(wi->comment = (Extbyte *) malloc(c.ckSize)) ||
901 !dread(wi->comment, c.ckSize, 1))
902 Err();
903
904 if (c.ckSize & 1)
905 dgetc(); /* eat the pad byte */
906 } 889 }
907 else 890 else
908 /* skip unknown chunk */ 891 /* skip unknown chunk */
909 dseek(PAD2(c.ckSize), 1); 892 dseek(PAD2(c.ckSize), 1);
910 893
911 ck.ckSize -= sizeof(RiffChunk) + PAD2(c.ckSize); 894 ck.ckSize -= sizeof(RiffChunk) + PAD2(c.ckSize);
912 } 895 }
913 } 896 }
914 else 897 else
915 /* skip unknown chunk */ 898 /* skip unknown chunk */
916 dseek(PAD2(ck.ckSize) - sizeof(RIFF_FOURCC), 1); 899 dseek(PAD2(ck.ckSize) - sizeof(RIFF_FOURCC), 1);
917 } 900 }
918 /* wave format chunk */ 901 /* wave format chunk */
919 else if (!cmpID(&ck.ckID, RIFF_WaveFmtID) && !wi->format) 902 else if (!cmpID(&ck.ckID, RIFF_WaveFmtID) && !wi->format)
920 { 903 {
921 AuInt32 dummy; 904 AuInt32 dummy;
922 905
923 wi->format = DataReadS(NAS_BIG_ENDIAN); 906 wi->format = DataReadS(NAS_BIG_ENDIAN);
924 wi->channels = DataReadS(NAS_BIG_ENDIAN); 907 wi->channels = DataReadS(NAS_BIG_ENDIAN);
925 wi->sampleRate = DataReadL(NAS_BIG_ENDIAN); 908 wi->sampleRate = DataReadL(NAS_BIG_ENDIAN);
926 909
927 /* we don't care about the next two fields */ 910 /* we don't care about the next two fields */
928 dummy = DataReadL(NAS_BIG_ENDIAN); 911 dummy = DataReadL(NAS_BIG_ENDIAN);
929 dummy = DataReadS(NAS_BIG_ENDIAN); 912 dummy = DataReadS(NAS_BIG_ENDIAN);
930 913
931 if (wi->format != RIFF_WAVE_FORMAT_PCM) 914 if (wi->format != RIFF_WAVE_FORMAT_PCM)
932 Err(); 915 Err();
933 916
934 wi->bitsPerSample = DataReadS(NAS_BIG_ENDIAN); 917 wi->bitsPerSample = DataReadS(NAS_BIG_ENDIAN);
935 918
936 /* skip any other format specific fields */ 919 /* skip any other format specific fields */
937 dseek(PAD2(ck.ckSize - 16), 1); 920 dseek(PAD2(ck.ckSize - 16), 1);
938 } 921 }
939 /* wave data chunk */ 922 /* wave data chunk */
940 else if (!cmpID(&ck.ckID, RIFF_WaveDataID) && !wi->dataOffset) 923 else if (!cmpID(&ck.ckID, RIFF_WaveDataID) && !wi->dataOffset)
941 { 924 {
942 long endOfFile; 925 long endOfFile;
943 926
944 wi->dataOffset = dtell(); 927 wi->dataOffset = dtell();
945 wi->dataSize = ck.ckSize; 928 wi->dataSize = ck.ckSize;
946 dseek(0, 2); 929 dseek(0, 2);
947 endOfFile = dtell(); 930 endOfFile = dtell();
948 931
949 /* seek past the data */ 932 /* seek past the data */
950 if (dseek(wi->dataOffset + PAD2(ck.ckSize), 0) || 933 if (dseek(wi->dataOffset + PAD2(ck.ckSize), 0) ||
951 dtell() > endOfFile) 934 dtell() > endOfFile)
952 { 935 {
953 /* the seek failed, assume the size is bogus */ 936 /* the seek failed, assume the size is bogus */
954 dseek(0, 2); 937 dseek(0, 2);
955 wi->dataSize = dtell() - wi->dataOffset; 938 wi->dataSize = dtell() - wi->dataOffset;
956 } 939 }
957 940
958 wi->dataOffset -= sizeof(long); 941 wi->dataOffset -= sizeof(long);
959 } 942 }
960 else 943 else
961 /* skip unknown chunk */ 944 /* skip unknown chunk */
962 dseek(PAD2(ck.ckSize), 1); 945 dseek(PAD2(ck.ckSize), 1);
963 } 946 }
964 947
965 if (!wi->dataOffset) 948 if (!wi->dataOffset)
966 Err(); 949 Err();
967 950
968 wi->numSamples = wi->dataSize / wi->channels / (wi->bitsPerSample >> 3); 951 wi->numSamples = wi->dataSize / wi->channels / (wi->bitsPerSample >> 3);
969 952
970 if (!wi->comment) 953 if (!wi->comment)
971 wi->comment = NameFromData (data + wi->dataOffset, 954 wi->comment = NameFromData (data + wi->dataOffset,
972 length - wi->dataOffset); 955 length - wi->dataOffset);
973 956
974 wi->fp = NULL; 957 wi->fp = NULL;
975 958
976 return wi; 959 return wi;
977 } 960 }
978 961
979 962
980 static Sound 963 static Sound
981 SoundOpenDataForReading (UChar_Binary *data, 964 SoundOpenDataForReading (UChar_Binary *data,