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