1 /*---------------------------------------------------------------------------*
2 Project: Revolution AX + sequencer Demo
3 File: seqdemo.c
4
5 Copyright (C)1998-2006 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: seqdemo.c,v $
14 Revision 1.9 06/08/2006 06:06:07 aka
15 Removed setting of tempDisableFX for new AXFX.
16
17 Revision 1.8 02/21/2006 01:04:15 mitu
18 modified am.h path.
19
20 Revision 1.7 02/20/2006 04:13:07 mitu
21 changed include path from dolphin/ to revolution/.
22
23 Revision 1.6 02/02/2006 08:31:17 aka
24 Added AXFXSetHooks() to alloc from MEM2 in AXFX.
25
26 Revision 1.5 02/02/2006 07:03:05 aka
27 Modified using MEM functions instead of OSAlloc()/OSFree().
28
29 Revision 1.4 02/01/2006 07:30:40 aka
30 Added #ifndef(#ifdef) HOLLYWOOD_REV - #else - #endif.
31
32 Revision 1.3 2006/01/31 08:07:20 aka
33 Added cast from u32 to u8* in relation to changing API around ARAM.
34
35 Revision 1.2 2006/01/27 04:54:59 ekwon
36 Corrected "\%" escape sequence warning (replaced with "%%").
37
38 Revision 1.1 11/04/2005 05:01:39 aka
39 Imported from dolphin tree.
40
41 14 03/04/01 16:20 Sak
42 murakami: Remove unused variables
43
44 13 4/11/02 1:59p Billyjack
45
46 12 12/11/01 7:02p Billyjack
47 - keep interrupts disabled during audio frame callback
48
49 11 9/06/01 3:17p Billyjack
50 fixed profile bug
51
52 10 9/05/01 4:33p Eugene
53 Updated AM API.
54
55 9 8/29/01 1:52p Billyjack
56
57 8 8/17/01 10:59a Billyjack
58 changed AMLoadFile() API
59
60 7 8/16/01 12:25p Billyjack
61 - now uses AM
62 - changed code for SYN and SEQ init API change
63
64 6 8/03/01 4:32p Billyjack
65 added OSEnableInterrupts() and OSRestoreInterrupts() to AX audio frame
66 callback per change in AX lib.
67
68 5 7/06/01 11:50a Billyjack
69 commented DCInvalidateRange for DVD to RAM transfers
70
71 4 5/21/01 12:01p Billyjack
72 changed demowin.h location
73
74 3 5/14/01 1:39p Billyjack
75 - reworked for DVDDATA file location and names
76 - uses ARGetBaseAddress where applicable
77
78 2 5/10/01 7:03p Billyjack
79 now uses DEMOWin
80
81 1 5/09/01 6:09p Billyjack
82 created
83
84 $NoKeywords: $
85 *---------------------------------------------------------------------------*/
86
87 /*---------------------------------------------------------------------------*
88 This program shows how to set up and use the AX
89 *---------------------------------------------------------------------------*/
90
91 #include <string.h>
92 #include <demo.h>
93 #include <revolution.h>
94 #include <revolution/mix.h>
95 #include <revolution/seq.h>
96 #include <revolution/syn.h>
97 #include <revolution/axfx.h>
98 #ifndef HOLLYWOOD_REV
99 #include <dolphin/am.h>
100 #else
101 #include <revolution/mem.h>
102 #endif
103 #include <demo/demowin.h>
104
105 static u32 maxCpuCycles, maxAuxCycles, maxUserCycles, maxAxCycles, maxVoices;
106
107 static AXFX_REVERBSTD reverbStd;
108 static AXFX_REVERBHI reverbHi;
109 static AXFX_CHORUS chorus;
110 static AXFX_DELAY delay;
111 static AXPROFILE profile[256];
112 static u32 auxa;
113 static u32 auxb;
114 static u32 sampleset;
115
116 #ifndef HOLLYWOOD_REV
117 #define MAX_ARAM_BLOCKS 2
118 static u32 aramMemArray[MAX_ARAM_BLOCKS];
119 #else
120 static MEMHeapHandle hExpHeap;
121 #endif
122
123 static SEQSEQUENCE sequence;
124 static u32 sequenceInitialized;
125
126 static u8 *wavetable;
127 static u8 *wavetablePcm;
128 static u8 *wavetableAdpcm;
129 static u8 *midiFile;
130 static char filename[1024];
131
132 #ifndef HOLLYWOOD_REV
133 static u32 arambase;
134 static u32 aramBasePcm;
135 static u32 aramBaseAdpcm;
136 static u32 zeroBase;
137 #else
138 static u8 *samples;
139 static u8 *samplesPcm;
140 static u8 *samplesAdpcm;
141 static u8 *zeroBuffer;
142 #endif
143
144 DEMOWinInfo *log_win;
145
146 static u32 exitProgram;
147
148 #ifdef HOLLYWOOD_REV
149 #define ZEROBUFFER_BYTES 256
150
151 static void* LoadFileIntoRam(char *path);
152 #endif
153
154 /*---------------------------------------------------------------------------*
155 *---------------------------------------------------------------------------*/
callbackAudioFrame(void)156 static void callbackAudioFrame(void)
157 {
158 // run the sequencer
159 SEQRunAudioFrame();
160
161 // run the synth
162 SYNRunAudioFrame();
163
164 // tell the mixer to update settings
165 MIXUpdateSettings();
166 }
167
168
169 /*---------------------------------------------------------------------------*
170 setup the audio system for MIDI sequencer playback and profiling
171 *---------------------------------------------------------------------------*/
setupAudioSystem(void)172 static void setupAudioSystem(void)
173 {
174 AXInit(); // initialize AX
175 MIXInit(); // initialize mixer
176 SYNInit(); // initialize synthesizer
177 SEQInit(); // initialize sequencer
178
179 AXRegisterCallback(&callbackAudioFrame);
180 AXInitProfile(profile, 256); // initialize profiling for AX
181
182 reverbStd.time = 3.0f;
183 reverbStd.preDelay = 0.1f;
184 reverbStd.damping = 0.5f;
185 reverbStd.coloration = 0.5f;
186 reverbStd.mix = 1.0f;
187
188 reverbHi.time = 3.0f;
189 reverbHi.preDelay = 0.1f;
190 reverbHi.damping = 0.5f;
191 reverbHi.coloration = 0.5f;
192 reverbHi.crosstalk = 0.0f;
193 reverbHi.mix = 1.0f;
194
195 chorus.baseDelay = 15;
196 chorus.variation = 0;
197 chorus.period = 500;
198
199 delay.delay[0] = 500;
200 delay.delay[1] = 500;
201 delay.delay[2] = 500;
202 delay.feedback[0] = 50;
203 delay.feedback[1] = 50;
204 delay.feedback[2] = 50;
205 delay.output[0] = 100;
206 delay.output[1] = 100;
207 delay.output[2] = 100;
208
209 AXFXReverbStdInit(&reverbStd); // initialize reverb
210 AXFXReverbHiInit(&reverbHi); // initialize reverb
211 AXFXChorusInit(&chorus); // initialize chorus
212 AXFXDelayInit(&delay); // initialize delay
213 }
214
215
216 /*---------------------------------------------------------------------------*
217 shutdown the audio system
218 *---------------------------------------------------------------------------*/
shutdownAudioSystem(void)219 static void shutdownAudioSystem(void)
220 {
221 AXFXReverbStdShutdown(&reverbStd);
222 AXFXReverbHiShutdown(&reverbHi);
223 AXFXChorusShutdown(&chorus);
224 AXFXDelayShutdown(&delay);
225
226 SEQQuit();
227 SYNQuit();
228 MIXQuit();
229 AXQuit();
230 }
231
232
233 /*---------------------------------------------------------------------------*
234 * Directory listing stuff!
235 *---------------------------------------------------------------------------*/
236 #define MAX_DIR_ENTRIES 512
237 #define MAX_FILENAME_LENGTH 128
238
239 DEMOWinMenuItem dir_entry[MAX_DIR_ENTRIES+1];
240 DEMOWinMenuInfo dir_list;
241
242 char dir_entry_name[MAX_DIR_ENTRIES][MAX_FILENAME_LENGTH];
243
244
245 /*---------------------------------------------------------------------------*
246 * Name :
247 * Description :
248 * Arguments : None.
249 * Returns : None.
250 *---------------------------------------------------------------------------*/
251
MNU_change_dir_up(DEMOWinMenuInfo * menu,u32 item,u32 * result)252 static void MNU_change_dir_up(DEMOWinMenuInfo *menu, u32 item, u32 *result)
253 {
254 #pragma unused(menu)
255 #pragma unused(item)
256 #pragma unused(result)
257
258 menu->items[item].flags |= DEMOWIN_ITM_EOF;
259
260 DEMOWinLogPrintf(log_win, "Changing to parent directory.\n");
261
262 DVDChangeDir("..");
263
264 *result = 0xDEADBEEF;
265
266 } // MNU_change_dir_up
267
268
269 /*---------------------------------------------------------------------------*
270 * Name :
271 * Description :
272 * Arguments : None.
273 * Returns : None.
274 *---------------------------------------------------------------------------*/
MNU_change_dir(DEMOWinMenuInfo * menu,u32 item,u32 * result)275 static void MNU_change_dir(DEMOWinMenuInfo *menu, u32 item, u32 *result)
276 {
277 #pragma unused(menu)
278 #pragma unused(item)
279 #pragma unused(result)
280
281
282 DVDDir dir;
283 DVDDirEntry dirent;
284
285 u32 i;
286
287 DEMOWinLogPrintf(log_win, "Changing directory to: '%s'.\n", menu->items[item].name);
288
289 DVDOpenDir(".", &dir);
290 for (i=1; i<=item; i++)
291 {
292 DVDReadDir(&dir, &dirent);
293 }
294 if (dirent.isDir)
295 {
296 DVDChangeDir(dirent.name);
297 menu->items[item].flags |= DEMOWIN_ITM_EOF;
298
299 }
300 else
301 {
302 DEMOWinLogPrintf(log_win, "Unable to change directory...??\n");
303 menu->items[item].flags &= ~DEMOWIN_ITM_EOF;
304 }
305
306 DVDCloseDir(&dir);
307
308 *result = 0xDEADBEEF;
309
310 } // MNU_change_dir
311
toupper(char c)312 static char toupper(char c)
313 {
314
315 if ((c >= 'a') && (c <= 'z'))
316 return((char)(c-32));
317 else
318 return(c);
319 }
320
321
compare_strings(char * s1,char * s2)322 static BOOL compare_strings(char *s1, char *s2)
323 {
324 u32 i;
325
326 for (i=0; i<strlen(s1); i++)
327 {
328 if (toupper(s1[i]) != toupper(s2[i]))
329 return(FALSE);
330 }
331 return(TRUE);
332 }
333
334
MNU_select_file(DEMOWinMenuInfo * menu,u32 item,u32 * result)335 static void MNU_select_file(DEMOWinMenuInfo *menu, u32 item, u32 *result)
336 {
337 u32 i;
338
339 i = strlen(menu->items[item].name);
340
341 while ((i >=0) && (menu->items[item].name[i] != '.'))
342 i--;
343
344 if (compare_strings(&menu->items[item].name[i], ".mid"))
345 {
346 strcpy(filename, menu->items[item].name);
347
348 DEMOWinLogPrintf(log_win, "Selected %s.\n", menu->items[item].name);
349
350 #ifndef HOLLYWOOD_REV
351 midiFile = AMLoadFile(menu->items[item].name, NULL);
352 #else
353 midiFile = LoadFileIntoRam(menu->items[item].name);
354 #endif
355
356 if (midiFile)
357 {
358 DEMOWinLogPrintf(log_win, "%s loaded into memory.\n", menu->items[item].name);
359
360 #ifndef HOLLYWOOD_REV
361 SEQAddSequence(
362 &sequence,
363 midiFile,
364 wavetable,
365 (u8*)arambase,
366 (u8*)zeroBase,
367 16,
368 15,
369 1
370 );
371 #else
372 SEQAddSequence(
373 &sequence,
374 midiFile,
375 wavetable,
376 samples,
377 zeroBuffer,
378 16,
379 15,
380 1
381 );
382 #endif
383
384 DEMOWinLogPrintf(log_win, "%s initialized\n", menu->items[item].name);
385 sequenceInitialized = 1;
386 }
387
388 *result = sequenceInitialized;
389 }
390 else
391 {
392 DEMOWinLogPrintf(log_win, "--> File '%s' is not an .mid file!\n", menu->items[item].name);
393 }
394
395 } // end __select_file
396
397 /*---------------------------------------------------------------------------*
398 * Name :
399 * Description :
400 * Arguments : None.
401 * Returns : None.
402 *---------------------------------------------------------------------------*/
__create_dir_menu(void)403 static DEMOWinMenuInfo *__create_dir_menu(void)
404 {
405
406 DVDDir dir;
407 DVDDirEntry dirent;
408
409 u32 index;
410 u32 len;
411
412 index = 0;
413
414
415 // first entry is always parent directory
416 strcpy(dir_entry_name[index], "../");
417
418 dir_entry[index].name = &dir_entry_name[index][0];
419 dir_entry[index].flags = DEMOWIN_ITM_EOF;
420 dir_entry[index].function = MNU_change_dir_up;
421 dir_entry[index].link = NULL;
422
423 index++;
424
425
426 DVDOpenDir(".", &dir);
427
428 while ( (DVDReadDir(&dir, &dirent)) && (index < MAX_DIR_ENTRIES))
429 {
430 // get name, append '/' if it's a directory
431 strcpy(dir_entry_name[index], dirent.name);
432 if (dirent.isDir)
433 {
434 len = strlen(dirent.name);
435 dir_entry_name[index][len] = '/';
436 dir_entry_name[index][len+1] = 0;
437
438 dir_entry[index].function = MNU_change_dir;
439 dir_entry[index].flags = DEMOWIN_ITM_EOF;
440 }
441 else
442 {
443 dir_entry[index].function = MNU_select_file;
444 dir_entry[index].flags = DEMOWIN_ITM_EOF;
445 }
446
447 dir_entry[index].name = &dir_entry_name[index][0];
448 dir_entry[index].link = NULL;
449 index++;
450 }
451
452 // terminate list
453 dir_entry[index].flags = DEMOWIN_ITM_TERMINATOR;
454 dir_entry[index].function = NULL;
455 dir_entry[index].link = NULL;
456
457
458 // Initialize Menu info structure
459
460 dir_list.title = "Directory Listing"; // later, init with directory name
461 dir_list.handle = NULL; // placeholder for window handle
462 dir_list.items = &dir_entry[0]; // list of items
463
464 dir_list.max_display_items = 24; // display 22 files at a time
465 dir_list.flags = 0; // no flags
466
467 dir_list.cb_open = NULL; // no callbacks
468 dir_list.cb_move = NULL;
469 dir_list.cb_select = NULL;
470 dir_list.cb_cancel = NULL;
471
472 // private members; initialize to zero, they will be calculated at runtime
473 dir_list.num_display_items = 0;
474 dir_list.num_items = 0;
475 dir_list.max_str_len = 0;
476 dir_list.curr_pos = 0;
477 dir_list.display_pos = 0;
478
479 DVDCloseDir(&dir);
480
481 if (index)
482 {
483 return(&dir_list);
484 }
485 else
486 {
487 return(NULL);
488 }
489
490
491 } // end __create_dir_menu()
492
493 /*---------------------------------------------------------------------------*
494 *---------------------------------------------------------------------------*/
MNU_select(DEMOWinMenuInfo * menu,u32 item,u32 * result)495 static void MNU_select(DEMOWinMenuInfo *menu, u32 item, u32 *result)
496 {
497 #pragma unused(menu)
498 #pragma unused(item)
499 #pragma unused(result)
500
501 DEMOWinInfo *p; // parent window
502 DEMOWinMenuInfo *m; // directory menu
503
504 u32 val = 0;
505
506 DEMOWinLogPrintf(log_win, "Please select MIDI file to play.\n");
507
508 if (sequenceInitialized)
509 {
510 DEMOWinLogPrintf(log_win, "Removing sequence.\n");
511
512 SEQRemoveSequence(&sequence);
513 sequenceInitialized = 0;
514
515 if (midiFile)
516 {
517 DEMOWinLogPrintf(log_win, "Free MIDI file from memory.\n");
518 #ifndef HOLLYWOOD_REV
519 OSFree(midiFile);
520 #else
521 MEMFreeToExpHeap(hExpHeap, midiFile);
522 #endif
523 }
524 }
525
526 p = menu->handle;
527
528 do
529 {
530 m = __create_dir_menu();
531
532 if (m)
533 {
534 DEMOWinCreateMenuWindow(m, (u16)(p->x2-10), (u16)(p->y1+24));
535 val = DEMOWinMenu(m);
536 DEMOWinDestroyMenuWindow(m);
537 }
538 else
539 {
540 DEMOWinLogPrintf(log_win, "Failed to create directory list.\n");
541 }
542
543 } while (val == 0xDEADBEEF);
544 }
545
546
547 /*---------------------------------------------------------------------------*
548 *---------------------------------------------------------------------------*/
MNU_play(DEMOWinMenuInfo * menu,u32 item,u32 * result)549 static void MNU_play(DEMOWinMenuInfo *menu, u32 item, u32 *result)
550 {
551 #pragma unused(menu)
552 #pragma unused(item)
553 #pragma unused(result)
554
555 if (sequenceInitialized)
556 {
557 DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_RUN.\n");
558 SEQSetState(&sequence, SEQ_STATE_RUN);
559 }
560 else
561 {
562 DEMOWinLogPrintf(log_win, "Please select a MIDI file to play!!!\n");
563 }
564 }
565
566 /*---------------------------------------------------------------------------*
567 *---------------------------------------------------------------------------*/
MNU_playloop(DEMOWinMenuInfo * menu,u32 item,u32 * result)568 static void MNU_playloop(DEMOWinMenuInfo *menu, u32 item, u32 *result)
569 {
570 #pragma unused(menu)
571 #pragma unused(item)
572 #pragma unused(result)
573
574 if (sequenceInitialized)
575 {
576 DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_RUNLOOPED.\n");
577 SEQSetState(&sequence, SEQ_STATE_RUNLOOPED);
578 }
579 }
580
581
582 /*---------------------------------------------------------------------------*
583 *---------------------------------------------------------------------------*/
MNU_pause(DEMOWinMenuInfo * menu,u32 item,u32 * result)584 static void MNU_pause(DEMOWinMenuInfo *menu, u32 item, u32 *result)
585 {
586 #pragma unused(menu)
587 #pragma unused(item)
588 #pragma unused(result)
589
590 if (sequenceInitialized)
591 {
592 DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_PAUSE.\n");
593 SEQSetState(&sequence, SEQ_STATE_PAUSE);
594 }
595 }
596
597
598 /*---------------------------------------------------------------------------*
599 *---------------------------------------------------------------------------*/
MNU_stop(DEMOWinMenuInfo * menu,u32 item,u32 * result)600 static void MNU_stop(DEMOWinMenuInfo *menu, u32 item, u32 *result)
601 {
602 #pragma unused(menu)
603 #pragma unused(item)
604 #pragma unused(result)
605
606 if (sequenceInitialized)
607 {
608 DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_STOP.\n");
609 SEQSetState(&sequence, SEQ_STATE_STOP);
610 }
611 }
612
613
614 /*---------------------------------------------------------------------------*
615 *---------------------------------------------------------------------------*/
MNU_auxa(DEMOWinMenuInfo * menu,u32 item,u32 * result)616 static void MNU_auxa(DEMOWinMenuInfo *menu, u32 item, u32 *result)
617 {
618 #pragma unused(menu)
619 #pragma unused(item)
620 #pragma unused(result)
621
622 auxa ++;
623
624 switch(auxa % 3)
625 {
626 case 0:
627
628 AXRegisterAuxACallback(NULL, NULL);
629 menu->items[item].name = " AUX A None";
630
631 break;
632
633 case 1:
634
635 AXRegisterAuxACallback((void*)&AXFXReverbStdCallback, (void*)&reverbStd);
636 menu->items[item].name = " AUX A AXFXReverbStd";
637
638 break;
639
640 case 2:
641
642 AXRegisterAuxACallback((void*)&AXFXReverbHiCallback, (void*)&reverbHi);
643 menu->items[item].name = " AUX A AXFXReverbHi";
644
645 break;
646 }
647 }
648
649
650 /*---------------------------------------------------------------------------*
651 *---------------------------------------------------------------------------*/
MNU_auxb(DEMOWinMenuInfo * menu,u32 item,u32 * result)652 static void MNU_auxb(DEMOWinMenuInfo *menu, u32 item, u32 *result)
653 {
654 #pragma unused(menu)
655 #pragma unused(item)
656 #pragma unused(result)
657
658 auxb ++;
659
660 switch(auxb % 3)
661 {
662 case 0:
663
664 AXRegisterAuxBCallback(NULL, NULL);
665 menu->items[item].name = " AUX B None";
666
667 break;
668
669 case 1:
670
671 AXRegisterAuxBCallback((void*)&AXFXChorusCallback, (void*)&chorus);
672 menu->items[item].name = " AUX B AXFXChorus";
673
674 break;
675
676 case 2:
677
678 AXRegisterAuxBCallback((void*)&AXFXDelayCallback, (void*)&delay);
679 menu->items[item].name = " AUX B AXFXDelay";
680
681 break;
682 }
683 }
684
685
686 /*---------------------------------------------------------------------------*
687 *---------------------------------------------------------------------------*/
MNU_sample(DEMOWinMenuInfo * menu,u32 item,u32 * result)688 static void MNU_sample(DEMOWinMenuInfo *menu, u32 item, u32 *result)
689 {
690 #pragma unused(menu)
691 #pragma unused(item)
692 #pragma unused(result)
693
694 sampleset ++;
695
696 switch(sampleset % 2)
697 {
698 case 0:
699
700 wavetable = wavetablePcm;
701 #ifndef HOLLYWOOD_REV
702 arambase = aramBasePcm;
703 #else
704 samples = samplesPcm;
705 #endif
706
707 menu->items[item].name = " PCM Samples";
708
709 break;
710
711 case 1:
712
713 wavetable = wavetableAdpcm;
714 #ifndef HOLLYWOOD_REV
715 arambase = aramBaseAdpcm;
716 #else
717 samples = samplesAdpcm;
718 #endif
719
720 menu->items[item].name = " ADPCM Samples";
721
722 break;
723 }
724
725 // if the sequence is running, initialize the synth with the new wavetable
726 if ((SEQGetState(&sequence) == SEQ_STATE_RUN) ||
727 (SEQGetState(&sequence) == SEQ_STATE_RUNLOOPED))
728 {
729 u32 state = SEQGetState(&sequence);
730
731 DEMOWinLogPrintf(log_win, "Stopping playback to change wavetable.\n");
732 SEQSetState(&sequence, SEQ_STATE_STOP);
733 }
734
735 if (sequenceInitialized)
736 {
737 SYNQuitSynth(&sequence.synth);
738
739 #ifndef HOLLYWOOD_REV
740 SYNInitSynth(
741 &sequence.synth,
742 wavetable,
743 (u8*)arambase,
744 (u8*)zeroBase,
745 16,
746 15,
747 1
748 );
749 #else
750 SYNInitSynth(
751 &sequence.synth,
752 wavetable,
753 samples,
754 zeroBuffer,
755 16,
756 15,
757 1
758 );
759 #endif
760 }
761
762 #ifndef HOLLYWOOD_REV
763 if (arambase == aramBasePcm)
764 #else
765 if (samples == samplesPcm)
766 #endif
767 DEMOWinLogPrintf(log_win, "Now using PCM samples.\n");
768 else
769 DEMOWinLogPrintf(log_win, "Now using ADPCM samples.\n");
770 }
771
772
773 /*---------------------------------------------------------------------------*
774 *---------------------------------------------------------------------------*/
MNU_clearmax(DEMOWinMenuInfo * menu,u32 item,u32 * result)775 static void MNU_clearmax(DEMOWinMenuInfo *menu, u32 item, u32 *result)
776 {
777 #pragma unused(menu)
778 #pragma unused(item)
779 #pragma unused(result)
780
781 maxCpuCycles = maxAuxCycles = maxUserCycles = maxAxCycles = maxVoices = 0;
782 }
783
784
785 /*---------------------------------------------------------------------------*
786 *---------------------------------------------------------------------------*/
MNU_exit(DEMOWinMenuInfo * menu,u32 item,u32 * result)787 static void MNU_exit(DEMOWinMenuInfo *menu, u32 item, u32 *result)
788 {
789 #pragma unused(menu)
790 #pragma unused(item)
791 #pragma unused(result)
792
793 exitProgram = 1;
794 }
795
796
797 /*---------------------------------------------------------------------------*
798 *---------------------------------------------------------------------------*/
updateProfile(DEMOWinInfo * window)799 static void updateProfile(DEMOWinInfo *window)
800 {
801 u32 cpuCycles, auxCycles, userCycles, axCycles, voices, i;
802
803 i = AXGetProfile();
804
805 if (i)
806 {
807 while (i)
808 {
809 // i--;
810
811 cpuCycles = (u32)(profile[i].axFrameEnd - profile[i].axFrameStart);
812 auxCycles = (u32)(profile[i].auxProcessingEnd - profile[i].auxProcessingStart);
813 userCycles = (u32)(profile[i].userCallbackEnd - profile[i].userCallbackStart);
814 axCycles = cpuCycles - auxCycles - userCycles;
815 voices = profile[i].axNumVoices;
816
817 if (cpuCycles > maxCpuCycles) maxCpuCycles = cpuCycles;
818 if (auxCycles > maxAuxCycles) maxAuxCycles = auxCycles;
819 if (userCycles > maxUserCycles) maxUserCycles = userCycles;
820 if (axCycles > maxAxCycles) maxAxCycles = axCycles;
821 if (voices > maxVoices) maxVoices = voices;
822
823 i--;
824 }
825
826 DEMOWinLogPrintf(window,"Current profile for 5ms frame\n\n");
827 DEMOWinLogPrintf(window,"Total: %f%%\n", (f32)OSTicksToNanoseconds(cpuCycles) / 50000);
828 DEMOWinLogPrintf(window,"AX: %f%%\n", (f32)OSTicksToNanoseconds(axCycles) / 50000);
829 DEMOWinLogPrintf(window,"AUX: %f%%\n", (f32)OSTicksToNanoseconds(auxCycles) / 50000);
830 DEMOWinLogPrintf(window,"MIX, SYN, SEQ: %f%%\n", (f32)OSTicksToNanoseconds(userCycles) / 50000);
831 DEMOWinLogPrintf(window,"Voices: %d\n", voices);
832
833 DEMOWinLogPrintf(window,"\nMax profile for 5ms frame\n\n");
834 DEMOWinLogPrintf(window,"Total: %f%%\n", (f32)OSTicksToNanoseconds(maxCpuCycles) / 50000);
835 DEMOWinLogPrintf(window,"AX: %f%%\n", (f32)OSTicksToNanoseconds(maxAxCycles) / 50000);
836 DEMOWinLogPrintf(window,"AUX: %f%%\n", (f32)OSTicksToNanoseconds(maxAuxCycles) / 50000);
837 DEMOWinLogPrintf(window,"MIX, SYN, SEQ: %f%%\n", (f32)OSTicksToNanoseconds(maxUserCycles) / 50000);
838 DEMOWinLogPrintf(window,"Voices: %d\n", maxVoices);
839 }
840 }
841
842
843 /*---------------------------------------------------------------------------*
844 *---------------------------------------------------------------------------*/
updateStatus(DEMOWinInfo * window)845 static void updateStatus(DEMOWinInfo *window)
846 {
847 if (sequenceInitialized)
848 {
849 DEMOWinLogPrintf(window, "MIDI File: %s\n", filename);
850 DEMOWinLogPrintf(window, "Tracks: %d\n", sequence.nTracks);
851 DEMOWinLogPrintf(window, "Remaining: %d\n", sequence.tracksRunning);
852 }
853 else
854 {
855 DEMOWinLogPrintf(window, "MIDI File: None\n");
856 DEMOWinLogPrintf(window, "Tracks: 0\n");
857 DEMOWinLogPrintf(window, "Running: 0\n");
858 }
859
860 switch (SEQGetState(&sequence))
861 {
862 case SEQ_STATE_STOP:
863
864 DEMOWinLogPrintf(window, "State: SEQ_STATE_STOP\n");
865
866 break;
867
868 case SEQ_STATE_RUN:
869
870 DEMOWinLogPrintf(window, "State: SEQ_STATE_RUN\n");
871
872 break;
873
874 case SEQ_STATE_RUNLOOPED:
875
876 DEMOWinLogPrintf(window, "State: SEQ_STATE_RUNLOOPED\n");
877
878 break;
879
880 case SEQ_STATE_PAUSE:
881
882 DEMOWinLogPrintf(window, "State: SEQ_STATE_PAUSE\n");
883
884 break;
885 }
886
887
888 DEMOWinLogPrintf(window, "Voices: %d\n", SYNGetActiveNotes(&sequence.synth));
889 }
890
891
892 /*---------------------------------------------------------------------------*
893 *---------------------------------------------------------------------------*/
894 DEMOWinMenuItem control_menu_items[] =
895 {
896 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
897 { " Select MIDI File", DEMOWIN_ITM_NONE, MNU_select, NULL },
898 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
899 { " Play", DEMOWIN_ITM_NONE, MNU_play, NULL },
900 { " Play Looped", DEMOWIN_ITM_NONE, MNU_playloop, NULL },
901 { " Pause", DEMOWIN_ITM_NONE, MNU_pause, NULL },
902 { " Stop", DEMOWIN_ITM_NONE, MNU_stop, NULL },
903 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
904 { " AUX A None", DEMOWIN_ITM_NONE, MNU_auxa, NULL },
905 { " AUX B None", DEMOWIN_ITM_NONE, MNU_auxb, NULL },
906 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
907 { " PCM Samples", DEMOWIN_ITM_NONE, MNU_sample, NULL },
908 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
909 { " Clear Max Profile", DEMOWIN_ITM_NONE, MNU_clearmax, NULL },
910 { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL },
911 { " Exit Program", DEMOWIN_ITM_EOF, MNU_exit, NULL },
912 { "", DEMOWIN_ITM_TERMINATOR, NULL, NULL }
913 };
914
915 DEMOWinMenuInfo control_menu =
916 {
917 #ifdef NDEBUG
918 "Seqdemo - NDEBUG build", // title
919 #else
920 "Seqdemo - DEBUG build", // title
921 #endif
922 NULL, // window handle
923 control_menu_items, // list of menu items
924 18, // max num of items to display at a time
925 DEMOWIN_MNU_NONE, // attribute flags?
926
927 // user callbacks for misc menu operations
928 NULL, NULL, NULL, NULL,
929 // private menu info members; do not touch
930 0, 0, 0, 0, 0
931 };
932
933 #ifdef HOLLYWOOD_REV
934 /*---------------------------------------------------------------------------*
935 *---------------------------------------------------------------------------*/
LoadFileIntoRam(char * path)936 static void* LoadFileIntoRam(char *path)
937 {
938 DVDFileInfo handle;
939 u32 round_length;
940 s32 read_length;
941 void *buffer;
942
943 // Open File
944 if (!DVDOpen(path, &handle))
945 {
946 OSReport("WARNING! Failed to open %s\n", path);
947 return NULL;
948 }
949
950 // Make sure file length is not 0
951 if (DVDGetLength(&handle) == 0)
952 {
953 OSReport("WARNING! File length is 0\n");
954 return NULL;
955 }
956
957 round_length = OSRoundUp32B(DVDGetLength(&handle));
958 buffer = MEMAllocFromExpHeapEx(hExpHeap, round_length, 32);
959
960 // Make sure we got a buffer
961 if (buffer == NULL)
962 {
963 OSReport("WARNING! Unable to allocate buffer\n");
964 return NULL;
965 }
966
967 // Read Files
968 read_length = DVDRead(&handle, buffer, (s32)(round_length), 0);
969
970 // Make sure we read the file correctly
971 if (read_length <= 0)
972 {
973 OSReport("WARNING! File lenght is wrong\n");
974 return NULL;
975 }
976
977 return buffer;
978 }
979
980 /*---------------------------------------------------------------------------*
981 *---------------------------------------------------------------------------*/
PrivateAlloc(u32 size)982 static void* PrivateAlloc(u32 size)
983 {
984 return MEMAllocFromExpHeapEx(hExpHeap, size, 32);
985 }
986
987 /*---------------------------------------------------------------------------*
988 *---------------------------------------------------------------------------*/
PrivateFree(void * addr)989 static void PrivateFree(void* addr)
990 {
991 MEMFreeToExpHeap(hExpHeap, addr);
992 }
993
994 #endif
995
996 /*---------------------------------------------------------------------------*
997 *---------------------------------------------------------------------------*/
main(void)998 void main(void)
999 {
1000 DEMOWinInfo *profile_win;
1001 DEMOWinInfo *status_win;
1002 DEMOWinMenuInfo *control_menu_ptr;
1003
1004 #ifndef HOLLYWOOD_REV
1005 u32 aramBase;
1006 u32 aramSize;
1007 #else
1008 void *arenaMem2Lo;
1009 void *arenaMem2Hi;
1010 #endif
1011
1012
1013 // set flags used for menu
1014 auxa = auxb = sampleset = 0;
1015 exitProgram = 0;
1016 sequenceInitialized = 0;
1017
1018 // initialize bean counters for profiling
1019 maxCpuCycles = maxAuxCycles = maxUserCycles = maxAxCycles = maxVoices = 0;
1020
1021 // initialize subsystems
1022 DEMOInit(NULL);
1023 DEMOWinInit();
1024
1025 #ifndef HOLLYWOOD_REV
1026 ARInit(aramMemArray, MAX_ARAM_BLOCKS);
1027 ARQInit();
1028 #else
1029 arenaMem2Lo = OSGetMEM2ArenaLo();
1030 arenaMem2Hi = OSGetMEM2ArenaHi();
1031 hExpHeap = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo);
1032 #endif
1033
1034 AIInit(NULL);
1035
1036 // initialize windows on the TV
1037 control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20);
1038
1039 profile_win = DEMOWinCreateWindow(300, 20, 600, 170, "AX Profile", 1024, updateProfile);
1040 status_win = DEMOWinCreateWindow(300, 175, 600, 245, "Sequence Status", 1024, updateStatus);
1041 log_win = DEMOWinCreateWindow(20, 250, 600, 400, "Log", 1024, NULL);
1042
1043 DEMOWinOpenWindow(control_menu_ptr->handle);
1044 DEMOWinOpenWindow(profile_win);
1045 DEMOWinOpenWindow(status_win);
1046 DEMOWinOpenWindow(log_win);
1047
1048 DEMOWinLogPrintf(log_win, "Setting up audio\n");
1049 setupAudioSystem();
1050
1051 #ifndef HOLLYWOOD_REV
1052 // for the purpose of this demo we take all the ARAM *chuckle*
1053 aramSize = ARGetSize() - ARGetBaseAddress();
1054 aramBase = ARAlloc(aramSize);
1055 AMInit(aramBase, aramSize);
1056
1057 // push sample data into ARAM
1058 aramBasePcm = AMPush("/axdemo/synth/gm16pcm.pcm");
1059 aramBaseAdpcm = AMPush("/axdemo/synth/gm16adpcm.pcm");
1060
1061 // load table data into main memory
1062 wavetablePcm = AMLoadFile("/axdemo/synth/gm16pcm.wt", NULL);
1063 wavetableAdpcm = AMLoadFile("/axdemo/synth/gm16adpcm.wt", NULL);
1064
1065 // default to PCM samples
1066 wavetable = wavetablePcm;
1067 arambase = aramBasePcm;
1068 zeroBase = AMGetZeroBuffer();
1069 #else
1070 // load sample data into main memory
1071 samplesPcm = LoadFileIntoRam("/axdemo/synth/gm16pcm.pcm");
1072 samplesAdpcm = LoadFileIntoRam("/axdemo/synth/gm16adpcm.pcm");
1073
1074 // load table data into main memory
1075 wavetablePcm = LoadFileIntoRam("/axdemo/synth/gm16pcm.wt");
1076 wavetableAdpcm = LoadFileIntoRam("/axdemo/synth/gm16adpcm.wt");
1077
1078 // default to PCM samples
1079 wavetable = wavetablePcm;
1080 samples = samplesPcm;
1081 zeroBuffer = MEMAllocFromExpHeapEx(hExpHeap, ZEROBUFFER_BYTES, 8);
1082
1083 memset(zeroBuffer, 0, ZEROBUFFER_BYTES);
1084 DCFlushRange(zeroBuffer, ZEROBUFFER_BYTES);
1085 #endif
1086
1087 #ifdef HOLLYWOOD_REV
1088 AXFXSetHooks((AXFXAlloc)PrivateAlloc, (AXFXFree)PrivateFree);
1089 #endif
1090
1091 while (1)
1092 {
1093 DEMOWinMenu(control_menu_ptr);
1094
1095 if (exitProgram == 1)
1096 break;
1097 }
1098
1099 DEMOWinLogPrintf(log_win, "Shutting down up audio\n");
1100 DEMOBeforeRender();
1101 DEMOWinRefresh();
1102 DEMODoneRender();
1103
1104 shutdownAudioSystem();
1105
1106 DEMOWinLogPrintf(log_win, "Free wavetable\n");
1107 DEMOBeforeRender();
1108 DEMOWinRefresh();
1109 DEMODoneRender();
1110
1111 #ifndef HOLLYWOOD_REV
1112 if (wavetablePcm)
1113 {
1114 OSFree(wavetablePcm);
1115 }
1116
1117 if (wavetableAdpcm)
1118 {
1119 OSFree(wavetableAdpcm);
1120 }
1121
1122 if (midiFile)
1123 {
1124 OSFree(midiFile);
1125 }
1126 #else
1127 if (wavetablePcm)
1128 {
1129 MEMFreeToExpHeap(hExpHeap, wavetablePcm);
1130 }
1131
1132 if (wavetableAdpcm)
1133 {
1134 MEMFreeToExpHeap(hExpHeap, wavetableAdpcm);
1135 }
1136
1137 if (midiFile)
1138 {
1139 MEMFreeToExpHeap(hExpHeap, midiFile);
1140 }
1141
1142 if (samplesPcm)
1143 {
1144 MEMFreeToExpHeap(hExpHeap, samplesPcm);
1145 }
1146
1147 if (samplesAdpcm)
1148 {
1149 MEMFreeToExpHeap(hExpHeap, samplesAdpcm);
1150 }
1151
1152 if (zeroBuffer)
1153 {
1154 MEMFreeToExpHeap(hExpHeap, zeroBuffer);
1155 }
1156 #endif
1157
1158 OSHalt("End of program\n");
1159 }
1160