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