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