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