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