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