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