1 /*---------------------------------------------------------------------------*
2 Project: Standard Reverb (expanded version) Test
3 File: expreverbStd.c
4
5 Copyright (C)2006 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: expreverbStd.c,v $
14 Revision 1.5 2006/11/21 08:21:38 aka
15 Removed the zero buffer.
16
17 Revision 1.4 2006/10/23 02:05:52 aka
18 Changed from AXInit() to AXInitSpecifyMem().
19 Changed from MIXInit() to MIXInitSpecifyMem().
20 Changed from SYNInit() to SYNInitSpecifyMem().
21
22 Revision 1.3 2006/10/10 08:30:06 aka
23 Revised AXInit(), MIXInit() and SYNInit().
24
25 Revision 1.2 2006/09/18 04:28:22 aka
26 Modified using AX_MAX_VOICES instead of MAX_DEMO_VOICES.
27
28 Revision 1.1 2006/06/08 08:16:15 aka
29 Imported new demos for new AXFX made by Kawamura-san (EAD).
30
31 $NoKeywords: $
32 *---------------------------------------------------------------------------*/
33
34
35 /*---------------------------------------------------------------------------*
36 * Includes
37 *---------------------------------------------------------------------------*/
38
39 #include <demo.h>
40 #include <demo/DEMOWin.h>
41 #include <revolution.h>
42 #include <revolution/mix.h>
43 #include <revolution/sp.h>
44 #include <revolution/axfx.h>
45 #include <revolution/axfx_presets.h>
46 #include <revolution/mem.h>
47 #include <string.h>
48
49 #include "dpl2reverb.h"
50
51 /*---------------------------------------------------------------------------*
52 * SP data
53 *---------------------------------------------------------------------------*/
54
55 #define SPT_FILE "/axdemo/dpl2/dpl2reverb.spt"
56 #define SPD_FILE "/axdemo/dpl2/dpl2reverb.spd"
57
58 // use only a single SP sound table
59 static SPSoundTable *sp_table;
60 static u8 *sp_data;
61
62 /*---------------------------------------------------------------------------*
63 * Exp Heap
64 *---------------------------------------------------------------------------*/
65 static MEMHeapHandle hExpHeap;
66
67 /*---------------------------------------------------------------------------*
68 * AX and Application-layer voice abstraction
69 *---------------------------------------------------------------------------*/
70
71 // Checks SP entry 'type' to see if the voice is looped or not
72 #define mISLOOPED(x) ((x->type)&0x1)
73
74 int panX; // pan value for left/right
75 int panY; // pan value for front/back
76
77 // Each voice has an associated AX parameter block and an SP entry
78 typedef struct
79 {
80 AXVPB *ax_voice;
81 SPSoundEntry *sp_entry;
82 } DEMO_VOICE;
83
84 DEMO_VOICE demo_voices[AX_MAX_VOICES];
85
86 // Constructs for Aux-bus effects
87 static AXFX_REVERBSTD_EXP reverb;
88
89 // AX profiling structures
90
91 // store up to 8 frames, just to be safe
92 #define NUM_AX_PROFILE_FRAMES 8
93
94 static AXPROFILE ax_profile[NUM_AX_PROFILE_FRAMES];
95
96 /*---------------------------------------------------------------------------*
97 * Prototypes
98 *---------------------------------------------------------------------------*/
99
100 // for AX and voice abstraction layer
101 static void ax_demo_callback (void);
102 static void ax_drop_voice_callback (void *p);
103 static void stop_all_voices (void);
104 static void stop_voice (DEMO_VOICE *v);
105 static DEMO_VOICE *play_sfx (u32 sfx);
106
107 // for UI menus
108 static void MNU_sound (DEMOWinMenuInfo *menu, u32 item, u32 *result);
109 static void MNU_position (DEMOWinMenuInfo *menu, u32 item, u32 *result);
110 static void MNU_stop_sfx (DEMOWinMenuInfo *menu, u32 item, u32 *result);
111 static void MNU_auxa (DEMOWinMenuInfo *menu, u32 item, u32 *result);
112 static void MNU_compressor (DEMOWinMenuInfo *menu, u32 item, u32 *result);
113 static void MNU_kill_all (DEMOWinMenuInfo *menu, u32 item, u32 *result);
114
115 /*---------------------------------------------------------------------------*
116 * User Interface stuff
117 *---------------------------------------------------------------------------*/
118
119 static u32 soundIndex = 0; // current sound effect to play
120 static u32 positionIndex = 0; // current panning
121 static u32 auxaIndex = 0; // current effect to apply to AuxA bus
122 static u32 compressFlag = 0; // current compressor state
123
124 DEMOWinInfo *DebugWin;
125 DEMOWinInfo *PositionWin;
126
127 DEMOWinMenuItem MenuItem[] =
128 {
129 { "Sound : (none)", DEMOWIN_ITM_NONE, MNU_sound, NULL },
130 { "AuxA : (none)", DEMOWIN_ITM_NONE, MNU_auxa, NULL },
131 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
132 { "Position: C Stick", DEMOWIN_ITM_NONE, MNU_position, NULL },
133 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
134 { "Compress: No", DEMOWIN_ITM_NONE, MNU_compressor, NULL },
135 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
136 { "Kill All Voices", DEMOWIN_ITM_NONE, MNU_kill_all, NULL },
137 { "", DEMOWIN_ITM_TERMINATOR, NULL, NULL }
138
139 };
140
141 DEMOWinMenuInfo Menu =
142 {
143 "AX RevStdExp Test", // title
144 NULL, // window handle
145 MenuItem, // list of menu items
146 9, // max num of items to display at a time
147 DEMOWIN_MNU_NONE, // attribute flags
148
149 // user callbacks
150 NULL, // callback for menu open event
151 NULL, // callback for cursor move event
152 NULL, // callback for item select event
153 NULL, // callback for cancel event
154
155 // private members
156 0, 0, 0, 0, 0
157 };
158
159 DEMOWinMenuInfo *MenuPtr;
160
161 /*===========================================================================*
162 * F U N C T I O N D E F I N I T I O N S
163 *===========================================================================*/
164
165
166 /*---------------------------------------------------------------------------*
167 * VOICE ABSTRACTION LAYER STUFF
168 /*---------------------------------------------------------------------------*
169
170
171 /*---------------------------------------------------------------------------*
172 * Name :
173 * Description :
174 * Arguments :
175 * Returns :
176 *---------------------------------------------------------------------------*/
177
178
stop_voice(DEMO_VOICE * v)179 static void stop_voice(DEMO_VOICE *v)
180 {
181
182 u32 i;
183 BOOL old;
184
185 old = OSDisableInterrupts();
186
187 for (i=0; i<AX_MAX_VOICES; i++)
188 {
189 if (v == &demo_voices[i])
190 {
191 if (demo_voices[i].ax_voice)
192 {
193 if (mISLOOPED(demo_voices[i].sp_entry))
194 {
195 SPPrepareEnd(demo_voices[i].sp_entry, demo_voices[i].ax_voice);
196 }
197 else
198 {
199 AXSetVoiceState(demo_voices[i].ax_voice, AX_PB_STATE_STOP);
200 }
201
202 break;
203 }
204
205 }
206 }
207
208 (void)OSRestoreInterrupts(old);
209
210
211 } // end stop_voice()
212
213 /*---------------------------------------------------------------------------*
214 * Name :
215 * Description :
216 * Arguments :
217 * Returns :
218 *---------------------------------------------------------------------------*/
219
stop_all_voices(void)220 static void stop_all_voices(void)
221 {
222
223 u32 i;
224 BOOL old;
225
226
227
228 old = OSDisableInterrupts();
229
230 for (i=0; i<AX_MAX_VOICES; i++)
231 {
232 if (demo_voices[i].ax_voice)
233 {
234 if (mISLOOPED(demo_voices[i].sp_entry))
235 {
236 SPPrepareEnd(demo_voices[i].sp_entry, demo_voices[i].ax_voice);
237 }
238 else
239 {
240 AXSetVoiceState(demo_voices[i].ax_voice, AX_PB_STATE_STOP);
241 }
242
243 }
244
245 }
246
247 (void)OSRestoreInterrupts(old);
248
249
250 } // end stop_voice()
251
252 /*---------------------------------------------------------------------------*
253 * Name :
254 * Description :
255 * Arguments :
256 * Returns :
257 *---------------------------------------------------------------------------*/
258
259
play_sfx(u32 sfx)260 static DEMO_VOICE *play_sfx(u32 sfx)
261 {
262
263 AXVPB *ax_v;
264 DEMO_VOICE *v;
265
266 BOOL old;
267
268
269 old = OSDisableInterrupts();
270
271 ax_v = AXAcquireVoice(15, ax_drop_voice_callback, 0);
272
273 if (ax_v)
274 {
275 // use AX voice index to reference a voice in the demo abstraction layer
276 demo_voices[ax_v->index].ax_voice = ax_v;
277
278 // assign a pointer for convenience
279 v = &demo_voices[ax_v->index];
280
281 // grab the requested sound from the SP table
282 v->sp_entry = SPGetSoundEntry(sp_table, sfx);
283
284 SPPrepareSound(v->sp_entry, v->ax_voice, (v->sp_entry)->sampleRate);
285
286
287 MIXInitChannel(v->ax_voice, 0, 0, 0, -960, -960, panX, 127-panY, 0);
288 AXSetVoiceState(v->ax_voice, AX_PB_STATE_RUN);
289
290 (void)OSRestoreInterrupts(old);
291 }
292 else
293 {
294 v = NULL;
295 (void)OSRestoreInterrupts(old);
296 DEMOWinLogPrintf(DebugWin, "ERROR: AX voice allocation failed.\n");
297
298 }
299
300 return(v);
301
302 } // end play_sfx()
303
304
305 /*---------------------------------------------------------------------------*
306 * Name :
307 * Description :
308 * Arguments : None.
309 * Returns : None.
310 *---------------------------------------------------------------------------*/
ax_demo_callback(void)311 static void ax_demo_callback(void)
312 {
313
314 u32 i;
315
316 // check for voices which have stopped and remove them from the
317 // abstraction layer
318 for (i=0; i<AX_MAX_VOICES; i++)
319 {
320 if (demo_voices[i].ax_voice)
321 {
322 if ( AX_PB_STATE_STOP == ((demo_voices[i].ax_voice)->pb.state))
323 {
324 // if the voice has stopped, clear it from the abstraction layer
325 MIXReleaseChannel(demo_voices[i].ax_voice);
326 AXFreeVoice(demo_voices[i].ax_voice);
327 demo_voices[i].ax_voice = NULL;
328 }
329 else
330 {
331 // otherwise, update the panning
332 MIXSetPan(demo_voices[i].ax_voice, panX);
333 MIXSetSPan(demo_voices[i].ax_voice, 127 - panY);
334 MIXUpdateSettings();
335 }
336 }
337 }
338
339 } // end ax_demo_callback()
340
341
342 /*---------------------------------------------------------------------------*
343 * Name : ax_drop_voice_callback()
344 * Description : Invoked by AX when a voice has been forciby dropped.
345 * Must delete references to the voice from our abstraction layer
346 * and release the associated MIXer channel.
347 * Arguments : None.
348 * Returns : None.
349 *---------------------------------------------------------------------------*/
ax_drop_voice_callback(void * p)350 static void ax_drop_voice_callback(void *p)
351 {
352
353 AXVPB *v;
354
355 v = (AXVPB *)p;
356
357 MIXReleaseChannel(demo_voices[v->index].ax_voice);
358 demo_voices[v->index].ax_voice = NULL;
359 demo_voices[v->index].sp_entry = NULL;
360
361 } // end ax_demo_callback()
362
363
364
365 /*---------------------------------------------------------------------------*
366 * MENU FUNCTIONS
367 /*---------------------------------------------------------------------------*
368
369 /*---------------------------------------------------------------------------*
370 * Name :
371 * Description :
372 * Arguments :
373 * Returns :
374 *---------------------------------------------------------------------------*/
375
MNU_compressor(DEMOWinMenuInfo * menu,u32 item,u32 * result)376 static void MNU_compressor(DEMOWinMenuInfo *menu, u32 item, u32 *result)
377 {
378 #pragma unused(menu, item, result)
379
380 BOOL old;
381
382 old = OSDisableInterrupts();
383
384 compressFlag ^= 1;
385 AXSetCompressor(compressFlag);
386
387 (void)OSRestoreInterrupts(old);
388
389 if (compressFlag)
390 {
391 menu->items[item].name = "Compress: YES";
392 }
393 else
394 {
395 menu->items[item].name = "Compress: NO ";
396 }
397
398
399 } // end MNU_compressor()
400
401 /*---------------------------------------------------------------------------*
402 * Name :
403 * Description :
404 * Arguments :
405 * Returns :
406 *---------------------------------------------------------------------------*/
407
MNU_kill_all(DEMOWinMenuInfo * menu,u32 item,u32 * result)408 static void MNU_kill_all(DEMOWinMenuInfo *menu, u32 item, u32 *result)
409 {
410 #pragma unused(menu, item, result)
411
412
413 u32 i;
414 BOOL old;
415
416 old = OSDisableInterrupts();
417
418 for (i=0; i<AX_MAX_VOICES; i++)
419 {
420 if (demo_voices[i].ax_voice)
421 {
422 AXSetVoiceState(demo_voices[i].ax_voice, AX_PB_STATE_STOP);
423 }
424 }
425
426 (void)OSRestoreInterrupts(old);
427
428
429 } // end MNU_kill_all()
430
431
432
433 /*---------------------------------------------------------------------------*
434 * Name :
435 * Description :
436 * Arguments :
437 * Returns :
438 *---------------------------------------------------------------------------*/
439
MNU_auxa(DEMOWinMenuInfo * menu,u32 item,u32 * result)440 static void MNU_auxa(DEMOWinMenuInfo *menu, u32 item, u32 *result)
441 {
442 #pragma unused(menu, item, result)
443
444 auxaIndex++;
445
446 auxaIndex %= 13;
447
448 switch (auxaIndex)
449 {
450 case 0:
451 AXFXReverbStdExpShutdown(&reverb);
452 AXRegisterAuxACallback(NULL, NULL);
453 menu->items[item].name = "Reverb : (none)";
454 break;
455 case 1:
456 AXFX_PRESET_REVERBSTD_EXP_OLD_TYPE1(&reverb);
457 AXFXReverbStdExpSettings(&reverb);
458 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
459 menu->items[item].name = "Reverb : Old 1";
460 break;
461
462 case 2:
463 AXFX_PRESET_REVERBSTD_EXP_OLD_TYPE2(&reverb);
464 AXFXReverbStdExpSettings(&reverb);
465 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
466 menu->items[item].name = "Reverb : Old 2";
467 break;
468
469 case 3:
470 AXFX_PRESET_REVERBSTD_EXP_METAL_PIPE(&reverb);
471 AXFXReverbStdExpSettings(&reverb);
472 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
473 menu->items[item].name = "Reverb : Metal Pipe";
474 break;
475
476 case 4:
477 AXFX_PRESET_REVERBSTD_EXP_METAL_TANK(&reverb);
478 AXFXReverbStdExpSettings(&reverb);
479 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
480 menu->items[item].name = "Reverb : Metal Tank";
481 break;
482
483 case 5:
484 AXFX_PRESET_REVERBSTD_EXP_SMALL_ROOM(&reverb);
485 AXFXReverbStdExpSettings(&reverb);
486 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
487 menu->items[item].name = "Reverb : Small Room";
488 break;
489
490 case 6:
491 AXFX_PRESET_REVERBSTD_EXP_MEDIUM_ROOM(&reverb);
492 AXFXReverbStdExpSettings(&reverb);
493 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
494 menu->items[item].name = "Reverb : Medium Room";
495 break;
496
497 case 7:
498 AXFX_PRESET_REVERBSTD_EXP_LARGE_ROOM(&reverb);
499 AXFXReverbStdExpSettings(&reverb);
500 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
501 menu->items[item].name = "Reverb : Large Room";
502 break;
503
504 case 8:
505 AXFX_PRESET_REVERBSTD_EXP_LONG_ROOM(&reverb);
506 AXFXReverbStdExpSettings(&reverb);
507 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
508 menu->items[item].name = "Reverb : Long Room";
509 break;
510
511 case 9:
512 AXFX_PRESET_REVERBSTD_EXP_SMALL_HALL(&reverb);
513 AXFXReverbStdExpSettings(&reverb);
514 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
515 menu->items[item].name = "Reverb : Small Hall";
516 break;
517
518 case 10:
519 AXFX_PRESET_REVERBSTD_EXP_LARGE_HALL(&reverb);
520 AXFXReverbStdExpSettings(&reverb);
521 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
522 menu->items[item].name = "Reverb : Large Hall";
523 break;
524
525 case 11:
526 AXFX_PRESET_REVERBSTD_EXP_CAVERNOUS(&reverb);
527 AXFXReverbStdExpSettings(&reverb);
528 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
529 menu->items[item].name = "Reverb : Cavernous";
530 break;
531
532 case 12:
533 AXFX_PRESET_REVERBSTD_EXP_CATHEDRAL(&reverb);
534 AXFXReverbStdExpSettings(&reverb);
535 AXRegisterAuxACallback((void*)&AXFXReverbStdExpCallback, (void*)&reverb);
536 menu->items[item].name = "Reverb : Cathedral";
537 break;
538
539
540 }
541
542
543 } // end MNU_auxa()
544
545
546 /*---------------------------------------------------------------------------*
547 * Name :
548 * Description :
549 * Arguments :
550 * Returns :
551 *---------------------------------------------------------------------------*/
552
MNU_sound(DEMOWinMenuInfo * menu,u32 item,u32 * result)553 static void MNU_sound(DEMOWinMenuInfo *menu, u32 item, u32 *result)
554 {
555 #pragma unused(result)
556
557 soundIndex++;
558 soundIndex %= 5;
559
560
561 stop_all_voices();
562
563 switch (soundIndex)
564 {
565 case 0: // None
566
567 menu->items[item].name = "Sound : None";
568 break;
569
570 case 1:
571
572 play_sfx(SFX_TICK);
573 menu->items[item].name = "Sound : TICK";
574
575 break;
576
577 case 2:
578
579 play_sfx(SFX_EXPLODE);
580 menu->items[item].name = "Sound : EXPLOSION";
581
582 break;
583
584 case 3:
585
586 play_sfx(SFX_MACHINEGUN);
587 menu->items[item].name = "Sound : MACHINEGUN";
588
589 break;
590
591 case 4:
592
593 play_sfx(SFX_SYNTH);
594 menu->items[item].name = "Sound : SYNTH";
595
596 break;
597
598 } // end switch()
599
600 } // end MNU_sound
601
602
603
604
605
606 /*---------------------------------------------------------------------------*
607 * Name :
608 * Description :
609 * Arguments :
610 * Returns :
611 *---------------------------------------------------------------------------*/
612
MNU_position(DEMOWinMenuInfo * menu,u32 item,u32 * result)613 static void MNU_position(DEMOWinMenuInfo *menu, u32 item, u32 *result)
614 {
615 #pragma unused(result)
616
617 positionIndex++;
618 positionIndex %= 7;
619
620 switch (positionIndex)
621 {
622 case 0:
623
624 menu->items[item].name = "Position: C Stick";
625
626 break;
627
628 case 1:
629
630 panX = 0;
631 panY = 0;
632 menu->items[item].name = "Position: L";
633
634 break;
635
636 case 2:
637
638 panX = 63;
639 panY = 0;
640 menu->items[item].name = "Position: C";
641
642 break;
643
644 case 3:
645
646 panX = 127;
647 panY = 0;
648 menu->items[item].name = "Position: R";
649
650 break;
651
652 case 4:
653
654 panX = 0;
655 panY = 127;
656 menu->items[item].name = "Position: Ls";
657
658 break;
659
660 case 5:
661
662 panX = 127;
663 panY = 127;
664 menu->items[item].name = "Position: Rs";
665
666 break;
667
668 case 6:
669
670 panX = 63;
671 panY = 127;
672 menu->items[item].name = "Position: Bs";
673
674 break;
675
676 }
677
678 } // end MNU_position()
679
680
681 /*---------------------------------------------------------------------------*
682 * Name : position_win_update()
683 * Description : refresh callback for position window
684 * Arguments :
685 * Returns :
686 *---------------------------------------------------------------------------*/
687
position_win_update(DEMOWinInfo * window)688 static void position_win_update(DEMOWinInfo *window)
689 {
690
691
692 int substickX;
693 int substickY;
694
695 BOOL old;
696
697 u32 i;
698
699 u32 cpuCycles;
700 u32 userCycles;
701 u32 axCycles;
702 u32 voices;
703
704 u32 maxCpuCycles =0;
705 u32 maxUserCycles=0;
706 u32 maxAxCycles =0;
707 u32 maxVoices =0;
708
709
710 substickX = (MenuPtr->handle)->pad.pads[0].substickX;
711 substickY = (MenuPtr->handle)->pad.pads[0].substickY;
712
713 // Update panning position
714 if (positionIndex == 0)
715 {
716
717 // if positionIndex is zero, then get panning information from
718 // the C-stick
719 panX = substickX + 63;
720 panY = (substickY - 63) * -1;
721
722 }
723
724 DEMOWinPrintfXY(window, 0, 1, "Pan : %1.2f ", (f32)panX/127);
725 DEMOWinPrintfXY(window, 0, 2, "SPan : %1.2f ", (f32)panY/127);
726
727 old = OSDisableInterrupts();
728
729 i = AXGetProfile();
730
731 if (i)
732 {
733 // up to 4 audio frames can complete within a 60Hz video frame
734 // so spin thru the accumulated audio frame profiles and find the peak values
735 while (i)
736 {
737 i--;
738
739 cpuCycles = (u32)(ax_profile[i].axFrameEnd - ax_profile[i].axFrameStart);
740 userCycles = (u32)(ax_profile[i].userCallbackEnd - ax_profile[i].userCallbackStart);
741 axCycles = cpuCycles - userCycles;
742 voices = ax_profile[i].axNumVoices;
743
744 // find peak values over the last i audio frames
745 if (cpuCycles > maxCpuCycles) maxCpuCycles = cpuCycles;
746 if (userCycles > maxUserCycles) maxUserCycles = userCycles;
747 if (axCycles > maxAxCycles) maxAxCycles = axCycles;
748 if (voices > maxVoices) maxVoices = voices;
749
750 }
751 (void)OSRestoreInterrupts(old);
752
753 DEMOWinPrintfXY(window, 0, 4, "Total CPU : %5.2f\n", (f32)OSTicksToNanoseconds(maxCpuCycles) / 50000);
754 DEMOWinPrintfXY(window, 0, 6, "User : %5.2f\n", (f32)OSTicksToNanoseconds(maxUserCycles) / 50000);
755 DEMOWinPrintfXY(window, 0, 7, "AX : %5.2f\n", (f32)OSTicksToNanoseconds(maxAxCycles) / 50000);
756 DEMOWinPrintfXY(window, 0, 9, "Voices : %5d", maxVoices);
757
758 }
759
760 (void)OSRestoreInterrupts(old);
761
762 }
763
764 /*---------------------------------------------------------------------------*
765 *---------------------------------------------------------------------------*/
LoadFileIntoRam(char * path)766 static void* LoadFileIntoRam(char *path)
767 {
768 DVDFileInfo handle;
769 u32 round_length;
770 s32 read_length;
771 void *buffer;
772
773 // Open File
774 if (!DVDOpen(path, &handle))
775 {
776 OSReport("WARNING! Failed to open %s\n", path);
777 return NULL;
778 }
779
780 // Make sure file length is not 0
781 if (DVDGetLength(&handle) == 0)
782 {
783 OSReport("WARNING! File length is 0\n");
784 return NULL;
785 }
786
787 round_length = OSRoundUp32B(DVDGetLength(&handle));
788 buffer = MEMAllocFromExpHeapEx(hExpHeap, round_length, 32);
789
790 // Make sure we got a buffer
791 if (buffer == NULL)
792 {
793 OSReport("WARNING! Unable to allocate buffer\n");
794 return NULL;
795 }
796
797 // Read Files
798 read_length = DVDRead(&handle, buffer, (s32)(round_length), 0);
799
800 // Make sure we read the file correctly
801 if (read_length <= 0)
802 {
803 OSReport("WARNING! File lenght is wrong\n");
804 return NULL;
805 }
806
807 return buffer;
808 }
809
810 /*---------------------------------------------------------------------------*
811 *---------------------------------------------------------------------------*/
PrivateAlloc(u32 size)812 static void* PrivateAlloc(u32 size)
813 {
814 return MEMAllocFromExpHeapEx(hExpHeap, size, 32);
815 }
816
817 /*---------------------------------------------------------------------------*
818 *---------------------------------------------------------------------------*/
PrivateFree(void * addr)819 static void PrivateFree(void* addr)
820 {
821 MEMFreeToExpHeap(hExpHeap, addr);
822 }
823
824 /*---------------------------------------------------------------------------*
825 * Name : main()
826 * Description : Hold on to your seatbelts!
827 * Arguments : None.
828 * Returns : None.
829 *---------------------------------------------------------------------------*/
main(void)830 void main(void)
831 {
832 void *arenaMem2Lo;
833 void *arenaMem2Hi;
834 void *axBuffer;
835 void *mixBuffer;
836
837 // initialize system
838 DEMOInit(NULL);
839 DEMOWinInit();
840
841 SISetSamplingRate(5);
842
843 arenaMem2Lo = OSGetMEM2ArenaLo();
844 arenaMem2Hi = OSGetMEM2ArenaHi();
845 hExpHeap = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo);
846
847 // initialize AI subsystem
848 AIInit(NULL);
849
850 // initialize AX audio system and MIXer application
851 axBuffer = MEMAllocFromExpHeapEx(hExpHeap, AXGetMemorySize(AX_MAX_VOICES), 32);
852 mixBuffer = MEMAllocFromExpHeap(hExpHeap, MIXGetMemorySize(AX_MAX_VOICES));
853
854 AXInitSpecifyMem(AX_MAX_VOICES, axBuffer);
855 MIXInitSpecifyMem(mixBuffer);
856
857 AXSetMode(AX_MODE_SURROUND);
858 MIXSetSoundMode(MIX_SOUND_MODE_SURROUND);
859
860 // -----------------------------------------------------------
861 // Load SP data!
862 // -----------------------------------------------------------
863
864 // Load sound table
865 sp_table = LoadFileIntoRam(SPT_FILE);
866
867 // Load sound effects
868 sp_data = LoadFileIntoRam(SPD_FILE);
869
870 // -----------------------------------------------------------
871 // initialize sound table!
872 // -----------------------------------------------------------
873 SPInitSoundTable(sp_table, sp_data, NULL);
874
875 // -----------------------------------------------------------
876 // Initialize demo voice abstraction layer
877 // -----------------------------------------------------------
878 AXRegisterCallback(ax_demo_callback);
879
880 // -----------------------------------------------------------
881 // Initialize AUX-bus effects
882 // -----------------------------------------------------------
883 AXFXSetHooks((AXFXAlloc)PrivateAlloc, (AXFXFree)PrivateFree);
884 AXFX_PRESET_REVERBSTD_EXP_OLD_TYPE1(&reverb);
885 AXFXReverbStdExpInit(&reverb);
886
887 // -----------------------------------------------------------
888 // initialize profiling for AX
889 // -----------------------------------------------------------
890 AXInitProfile(ax_profile, NUM_AX_PROFILE_FRAMES);
891
892 // -----------------------------------------------------------
893 // Invoke menu system!
894 // -----------------------------------------------------------
895 MenuPtr = DEMOWinCreateMenuWindow(
896 &Menu,
897 20,
898 120
899 );
900
901 DebugWin = DEMOWinCreateWindow(
902 (u16)(MenuPtr->handle->x2+10),
903 20,
904 620,
905 440,
906 "Debug",
907 1024,
908 NULL
909 );
910
911 PositionWin = DEMOWinCreateWindow(
912 (u16)(MenuPtr->handle->x1),
913 (u16)(MenuPtr->handle->y2+10),
914 (u16)(MenuPtr->handle->x2),
915 (u16)(MenuPtr->handle->y2+120),
916 "Position",
917 0,
918 position_win_update
919 );
920
921 DEMOWinOpenWindow(DebugWin);
922 DEMOWinOpenWindow(PositionWin);
923
924 DEMOWinLogPrintf(DebugWin, "---------------------------------------\n");
925 DEMOWinLogPrintf(DebugWin, "Standard Reverb (expanded version) Test\n");
926 DEMOWinLogPrintf(DebugWin, "---------------------------------------\n");
927
928 DEMOWinLogPrintf(DebugWin, "\n");
929
930 DEMOWinLogPrintf(DebugWin, "Mode is AX_MODE_SURROUND.\n");
931
932 while (1)
933 {
934
935 DEMOWinMenu(MenuPtr);
936
937 }
938
939 } // end main()
940