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