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