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