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