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