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