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