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