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