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