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