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