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