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