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