/*---------------------------------------------------------------------------* Project: Revolution AX + sequencer Demo File: seqdemo.c Copyright (C)1998-2006 Nintendo All Rights Reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: seqdemo.c,v $ Revision 1.9 06/08/2006 06:06:07 aka Removed setting of tempDisableFX for new AXFX. Revision 1.8 02/21/2006 01:04:15 mitu modified am.h path. Revision 1.7 02/20/2006 04:13:07 mitu changed include path from dolphin/ to revolution/. Revision 1.6 02/02/2006 08:31:17 aka Added AXFXSetHooks() to alloc from MEM2 in AXFX. Revision 1.5 02/02/2006 07:03:05 aka Modified using MEM functions instead of OSAlloc()/OSFree(). Revision 1.4 02/01/2006 07:30:40 aka Added #ifndef(#ifdef) HOLLYWOOD_REV - #else - #endif. Revision 1.3 2006/01/31 08:07:20 aka Added cast from u32 to u8* in relation to changing API around ARAM. Revision 1.2 2006/01/27 04:54:59 ekwon Corrected "\%" escape sequence warning (replaced with "%%"). Revision 1.1 11/04/2005 05:01:39 aka Imported from dolphin tree. 14 03/04/01 16:20 Sak murakami: Remove unused variables 13 4/11/02 1:59p Billyjack 12 12/11/01 7:02p Billyjack - keep interrupts disabled during audio frame callback 11 9/06/01 3:17p Billyjack fixed profile bug 10 9/05/01 4:33p Eugene Updated AM API. 9 8/29/01 1:52p Billyjack 8 8/17/01 10:59a Billyjack changed AMLoadFile() API 7 8/16/01 12:25p Billyjack - now uses AM - changed code for SYN and SEQ init API change 6 8/03/01 4:32p Billyjack added OSEnableInterrupts() and OSRestoreInterrupts() to AX audio frame callback per change in AX lib. 5 7/06/01 11:50a Billyjack commented DCInvalidateRange for DVD to RAM transfers 4 5/21/01 12:01p Billyjack changed demowin.h location 3 5/14/01 1:39p Billyjack - reworked for DVDDATA file location and names - uses ARGetBaseAddress where applicable 2 5/10/01 7:03p Billyjack now uses DEMOWin 1 5/09/01 6:09p Billyjack created $NoKeywords: $ *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* This program shows how to set up and use the AX *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #ifndef HOLLYWOOD_REV #include #else #include #endif #include static u32 maxCpuCycles, maxAuxCycles, maxUserCycles, maxAxCycles, maxVoices; static AXFX_REVERBSTD reverbStd; static AXFX_REVERBHI reverbHi; static AXFX_CHORUS chorus; static AXFX_DELAY delay; static AXPROFILE profile[256]; static u32 auxa; static u32 auxb; static u32 sampleset; #ifndef HOLLYWOOD_REV #define MAX_ARAM_BLOCKS 2 static u32 aramMemArray[MAX_ARAM_BLOCKS]; #else static MEMHeapHandle hExpHeap; #endif static SEQSEQUENCE sequence; static u32 sequenceInitialized; static u8 *wavetable; static u8 *wavetablePcm; static u8 *wavetableAdpcm; static u8 *midiFile; static char filename[1024]; #ifndef HOLLYWOOD_REV static u32 arambase; static u32 aramBasePcm; static u32 aramBaseAdpcm; static u32 zeroBase; #else static u8 *samples; static u8 *samplesPcm; static u8 *samplesAdpcm; static u8 *zeroBuffer; #endif DEMOWinInfo *log_win; static u32 exitProgram; #ifdef HOLLYWOOD_REV #define ZEROBUFFER_BYTES 256 static void* LoadFileIntoRam(char *path); #endif /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void callbackAudioFrame(void) { // run the sequencer SEQRunAudioFrame(); // run the synth SYNRunAudioFrame(); // tell the mixer to update settings MIXUpdateSettings(); } /*---------------------------------------------------------------------------* setup the audio system for MIDI sequencer playback and profiling *---------------------------------------------------------------------------*/ static void setupAudioSystem(void) { AXInit(); // initialize AX MIXInit(); // initialize mixer SYNInit(); // initialize synthesizer SEQInit(); // initialize sequencer AXRegisterCallback(&callbackAudioFrame); AXInitProfile(profile, 256); // initialize profiling for AX reverbStd.time = 3.0f; reverbStd.preDelay = 0.1f; reverbStd.damping = 0.5f; reverbStd.coloration = 0.5f; reverbStd.mix = 1.0f; reverbHi.time = 3.0f; reverbHi.preDelay = 0.1f; reverbHi.damping = 0.5f; reverbHi.coloration = 0.5f; reverbHi.crosstalk = 0.0f; reverbHi.mix = 1.0f; chorus.baseDelay = 15; chorus.variation = 0; chorus.period = 500; delay.delay[0] = 500; delay.delay[1] = 500; delay.delay[2] = 500; delay.feedback[0] = 50; delay.feedback[1] = 50; delay.feedback[2] = 50; delay.output[0] = 100; delay.output[1] = 100; delay.output[2] = 100; AXFXReverbStdInit(&reverbStd); // initialize reverb AXFXReverbHiInit(&reverbHi); // initialize reverb AXFXChorusInit(&chorus); // initialize chorus AXFXDelayInit(&delay); // initialize delay } /*---------------------------------------------------------------------------* shutdown the audio system *---------------------------------------------------------------------------*/ static void shutdownAudioSystem(void) { AXFXReverbStdShutdown(&reverbStd); AXFXReverbHiShutdown(&reverbHi); AXFXChorusShutdown(&chorus); AXFXDelayShutdown(&delay); SEQQuit(); SYNQuit(); MIXQuit(); AXQuit(); } /*---------------------------------------------------------------------------* * Directory listing stuff! *---------------------------------------------------------------------------*/ #define MAX_DIR_ENTRIES 512 #define MAX_FILENAME_LENGTH 128 DEMOWinMenuItem dir_entry[MAX_DIR_ENTRIES+1]; DEMOWinMenuInfo dir_list; char dir_entry_name[MAX_DIR_ENTRIES][MAX_FILENAME_LENGTH]; /*---------------------------------------------------------------------------* * Name : * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void MNU_change_dir_up(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) menu->items[item].flags |= DEMOWIN_ITM_EOF; DEMOWinLogPrintf(log_win, "Changing to parent directory.\n"); DVDChangeDir(".."); *result = 0xDEADBEEF; } // MNU_change_dir_up /*---------------------------------------------------------------------------* * Name : * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static void MNU_change_dir(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) DVDDir dir; DVDDirEntry dirent; u32 i; DEMOWinLogPrintf(log_win, "Changing directory to: '%s'.\n", menu->items[item].name); DVDOpenDir(".", &dir); for (i=1; i<=item; i++) { DVDReadDir(&dir, &dirent); } if (dirent.isDir) { DVDChangeDir(dirent.name); menu->items[item].flags |= DEMOWIN_ITM_EOF; } else { DEMOWinLogPrintf(log_win, "Unable to change directory...??\n"); menu->items[item].flags &= ~DEMOWIN_ITM_EOF; } DVDCloseDir(&dir); *result = 0xDEADBEEF; } // MNU_change_dir static char toupper(char c) { if ((c >= 'a') && (c <= 'z')) return((char)(c-32)); else return(c); } static BOOL compare_strings(char *s1, char *s2) { u32 i; for (i=0; iitems[item].name); while ((i >=0) && (menu->items[item].name[i] != '.')) i--; if (compare_strings(&menu->items[item].name[i], ".mid")) { strcpy(filename, menu->items[item].name); DEMOWinLogPrintf(log_win, "Selected %s.\n", menu->items[item].name); #ifndef HOLLYWOOD_REV midiFile = AMLoadFile(menu->items[item].name, NULL); #else midiFile = LoadFileIntoRam(menu->items[item].name); #endif if (midiFile) { DEMOWinLogPrintf(log_win, "%s loaded into memory.\n", menu->items[item].name); #ifndef HOLLYWOOD_REV SEQAddSequence( &sequence, midiFile, wavetable, (u8*)arambase, (u8*)zeroBase, 16, 15, 1 ); #else SEQAddSequence( &sequence, midiFile, wavetable, samples, zeroBuffer, 16, 15, 1 ); #endif DEMOWinLogPrintf(log_win, "%s initialized\n", menu->items[item].name); sequenceInitialized = 1; } *result = sequenceInitialized; } else { DEMOWinLogPrintf(log_win, "--> File '%s' is not an .mid file!\n", menu->items[item].name); } } // end __select_file /*---------------------------------------------------------------------------* * Name : * Description : * Arguments : None. * Returns : None. *---------------------------------------------------------------------------*/ static DEMOWinMenuInfo *__create_dir_menu(void) { DVDDir dir; DVDDirEntry dirent; u32 index; u32 len; index = 0; // first entry is always parent directory strcpy(dir_entry_name[index], "../"); dir_entry[index].name = &dir_entry_name[index][0]; dir_entry[index].flags = DEMOWIN_ITM_EOF; dir_entry[index].function = MNU_change_dir_up; dir_entry[index].link = NULL; index++; DVDOpenDir(".", &dir); while ( (DVDReadDir(&dir, &dirent)) && (index < MAX_DIR_ENTRIES)) { // get name, append '/' if it's a directory strcpy(dir_entry_name[index], dirent.name); if (dirent.isDir) { len = strlen(dirent.name); dir_entry_name[index][len] = '/'; dir_entry_name[index][len+1] = 0; dir_entry[index].function = MNU_change_dir; dir_entry[index].flags = DEMOWIN_ITM_EOF; } else { dir_entry[index].function = MNU_select_file; dir_entry[index].flags = DEMOWIN_ITM_EOF; } dir_entry[index].name = &dir_entry_name[index][0]; dir_entry[index].link = NULL; index++; } // terminate list dir_entry[index].flags = DEMOWIN_ITM_TERMINATOR; dir_entry[index].function = NULL; dir_entry[index].link = NULL; // Initialize Menu info structure dir_list.title = "Directory Listing"; // later, init with directory name dir_list.handle = NULL; // placeholder for window handle dir_list.items = &dir_entry[0]; // list of items dir_list.max_display_items = 24; // display 22 files at a time dir_list.flags = 0; // no flags dir_list.cb_open = NULL; // no callbacks dir_list.cb_move = NULL; dir_list.cb_select = NULL; dir_list.cb_cancel = NULL; // private members; initialize to zero, they will be calculated at runtime dir_list.num_display_items = 0; dir_list.num_items = 0; dir_list.max_str_len = 0; dir_list.curr_pos = 0; dir_list.display_pos = 0; DVDCloseDir(&dir); if (index) { return(&dir_list); } else { return(NULL); } } // end __create_dir_menu() /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_select(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) DEMOWinInfo *p; // parent window DEMOWinMenuInfo *m; // directory menu u32 val = 0; DEMOWinLogPrintf(log_win, "Please select MIDI file to play.\n"); if (sequenceInitialized) { DEMOWinLogPrintf(log_win, "Removing sequence.\n"); SEQRemoveSequence(&sequence); sequenceInitialized = 0; if (midiFile) { DEMOWinLogPrintf(log_win, "Free MIDI file from memory.\n"); #ifndef HOLLYWOOD_REV OSFree(midiFile); #else MEMFreeToExpHeap(hExpHeap, midiFile); #endif } } p = menu->handle; do { m = __create_dir_menu(); if (m) { DEMOWinCreateMenuWindow(m, (u16)(p->x2-10), (u16)(p->y1+24)); val = DEMOWinMenu(m); DEMOWinDestroyMenuWindow(m); } else { DEMOWinLogPrintf(log_win, "Failed to create directory list.\n"); } } while (val == 0xDEADBEEF); } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_play(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) if (sequenceInitialized) { DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_RUN.\n"); SEQSetState(&sequence, SEQ_STATE_RUN); } else { DEMOWinLogPrintf(log_win, "Please select a MIDI file to play!!!\n"); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_playloop(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) if (sequenceInitialized) { DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_RUNLOOPED.\n"); SEQSetState(&sequence, SEQ_STATE_RUNLOOPED); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_pause(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) if (sequenceInitialized) { DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_PAUSE.\n"); SEQSetState(&sequence, SEQ_STATE_PAUSE); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_stop(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) if (sequenceInitialized) { DEMOWinLogPrintf(log_win, "Setting sequence state to SEQ_STATE_STOP.\n"); SEQSetState(&sequence, SEQ_STATE_STOP); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_auxa(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) auxa ++; switch(auxa % 3) { case 0: AXRegisterAuxACallback(NULL, NULL); menu->items[item].name = " AUX A None"; break; case 1: AXRegisterAuxACallback((void*)&AXFXReverbStdCallback, (void*)&reverbStd); menu->items[item].name = " AUX A AXFXReverbStd"; break; case 2: AXRegisterAuxACallback((void*)&AXFXReverbHiCallback, (void*)&reverbHi); menu->items[item].name = " AUX A AXFXReverbHi"; break; } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_auxb(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) auxb ++; switch(auxb % 3) { case 0: AXRegisterAuxBCallback(NULL, NULL); menu->items[item].name = " AUX B None"; break; case 1: AXRegisterAuxBCallback((void*)&AXFXChorusCallback, (void*)&chorus); menu->items[item].name = " AUX B AXFXChorus"; break; case 2: AXRegisterAuxBCallback((void*)&AXFXDelayCallback, (void*)&delay); menu->items[item].name = " AUX B AXFXDelay"; break; } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_sample(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) sampleset ++; switch(sampleset % 2) { case 0: wavetable = wavetablePcm; #ifndef HOLLYWOOD_REV arambase = aramBasePcm; #else samples = samplesPcm; #endif menu->items[item].name = " PCM Samples"; break; case 1: wavetable = wavetableAdpcm; #ifndef HOLLYWOOD_REV arambase = aramBaseAdpcm; #else samples = samplesAdpcm; #endif menu->items[item].name = " ADPCM Samples"; break; } // if the sequence is running, initialize the synth with the new wavetable if ((SEQGetState(&sequence) == SEQ_STATE_RUN) || (SEQGetState(&sequence) == SEQ_STATE_RUNLOOPED)) { u32 state = SEQGetState(&sequence); DEMOWinLogPrintf(log_win, "Stopping playback to change wavetable.\n"); SEQSetState(&sequence, SEQ_STATE_STOP); } if (sequenceInitialized) { SYNQuitSynth(&sequence.synth); #ifndef HOLLYWOOD_REV SYNInitSynth( &sequence.synth, wavetable, (u8*)arambase, (u8*)zeroBase, 16, 15, 1 ); #else SYNInitSynth( &sequence.synth, wavetable, samples, zeroBuffer, 16, 15, 1 ); #endif } #ifndef HOLLYWOOD_REV if (arambase == aramBasePcm) #else if (samples == samplesPcm) #endif DEMOWinLogPrintf(log_win, "Now using PCM samples.\n"); else DEMOWinLogPrintf(log_win, "Now using ADPCM samples.\n"); } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_clearmax(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) maxCpuCycles = maxAuxCycles = maxUserCycles = maxAxCycles = maxVoices = 0; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void MNU_exit(DEMOWinMenuInfo *menu, u32 item, u32 *result) { #pragma unused(menu) #pragma unused(item) #pragma unused(result) exitProgram = 1; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void updateProfile(DEMOWinInfo *window) { u32 cpuCycles, auxCycles, userCycles, axCycles, voices, i; i = AXGetProfile(); if (i) { while (i) { // i--; cpuCycles = (u32)(profile[i].axFrameEnd - profile[i].axFrameStart); auxCycles = (u32)(profile[i].auxProcessingEnd - profile[i].auxProcessingStart); userCycles = (u32)(profile[i].userCallbackEnd - profile[i].userCallbackStart); axCycles = cpuCycles - auxCycles - userCycles; voices = profile[i].axNumVoices; if (cpuCycles > maxCpuCycles) maxCpuCycles = cpuCycles; if (auxCycles > maxAuxCycles) maxAuxCycles = auxCycles; if (userCycles > maxUserCycles) maxUserCycles = userCycles; if (axCycles > maxAxCycles) maxAxCycles = axCycles; if (voices > maxVoices) maxVoices = voices; i--; } DEMOWinLogPrintf(window,"Current profile for 5ms frame\n\n"); DEMOWinLogPrintf(window,"Total: %f%%\n", (f32)OSTicksToNanoseconds(cpuCycles) / 50000); DEMOWinLogPrintf(window,"AX: %f%%\n", (f32)OSTicksToNanoseconds(axCycles) / 50000); DEMOWinLogPrintf(window,"AUX: %f%%\n", (f32)OSTicksToNanoseconds(auxCycles) / 50000); DEMOWinLogPrintf(window,"MIX, SYN, SEQ: %f%%\n", (f32)OSTicksToNanoseconds(userCycles) / 50000); DEMOWinLogPrintf(window,"Voices: %d\n", voices); DEMOWinLogPrintf(window,"\nMax profile for 5ms frame\n\n"); DEMOWinLogPrintf(window,"Total: %f%%\n", (f32)OSTicksToNanoseconds(maxCpuCycles) / 50000); DEMOWinLogPrintf(window,"AX: %f%%\n", (f32)OSTicksToNanoseconds(maxAxCycles) / 50000); DEMOWinLogPrintf(window,"AUX: %f%%\n", (f32)OSTicksToNanoseconds(maxAuxCycles) / 50000); DEMOWinLogPrintf(window,"MIX, SYN, SEQ: %f%%\n", (f32)OSTicksToNanoseconds(maxUserCycles) / 50000); DEMOWinLogPrintf(window,"Voices: %d\n", maxVoices); } } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void updateStatus(DEMOWinInfo *window) { if (sequenceInitialized) { DEMOWinLogPrintf(window, "MIDI File: %s\n", filename); DEMOWinLogPrintf(window, "Tracks: %d\n", sequence.nTracks); DEMOWinLogPrintf(window, "Remaining: %d\n", sequence.tracksRunning); } else { DEMOWinLogPrintf(window, "MIDI File: None\n"); DEMOWinLogPrintf(window, "Tracks: 0\n"); DEMOWinLogPrintf(window, "Running: 0\n"); } switch (SEQGetState(&sequence)) { case SEQ_STATE_STOP: DEMOWinLogPrintf(window, "State: SEQ_STATE_STOP\n"); break; case SEQ_STATE_RUN: DEMOWinLogPrintf(window, "State: SEQ_STATE_RUN\n"); break; case SEQ_STATE_RUNLOOPED: DEMOWinLogPrintf(window, "State: SEQ_STATE_RUNLOOPED\n"); break; case SEQ_STATE_PAUSE: DEMOWinLogPrintf(window, "State: SEQ_STATE_PAUSE\n"); break; } DEMOWinLogPrintf(window, "Voices: %d\n", SYNGetActiveNotes(&sequence.synth)); } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ DEMOWinMenuItem control_menu_items[] = { { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " Select MIDI File", DEMOWIN_ITM_NONE, MNU_select, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " Play", DEMOWIN_ITM_NONE, MNU_play, NULL }, { " Play Looped", DEMOWIN_ITM_NONE, MNU_playloop, NULL }, { " Pause", DEMOWIN_ITM_NONE, MNU_pause, NULL }, { " Stop", DEMOWIN_ITM_NONE, MNU_stop, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " AUX A None", DEMOWIN_ITM_NONE, MNU_auxa, NULL }, { " AUX B None", DEMOWIN_ITM_NONE, MNU_auxb, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " PCM Samples", DEMOWIN_ITM_NONE, MNU_sample, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " Clear Max Profile", DEMOWIN_ITM_NONE, MNU_clearmax, NULL }, { "", DEMOWIN_ITM_SEPARATOR, NULL, NULL }, { " Exit Program", DEMOWIN_ITM_EOF, MNU_exit, NULL }, { "", DEMOWIN_ITM_TERMINATOR, NULL, NULL } }; DEMOWinMenuInfo control_menu = { #ifdef NDEBUG "Seqdemo - NDEBUG build", // title #else "Seqdemo - DEBUG build", // title #endif NULL, // window handle control_menu_items, // list of menu items 18, // max num of items to display at a time DEMOWIN_MNU_NONE, // attribute flags? // user callbacks for misc menu operations NULL, NULL, NULL, NULL, // private menu info members; do not touch 0, 0, 0, 0, 0 }; #ifdef HOLLYWOOD_REV /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void* LoadFileIntoRam(char *path) { DVDFileInfo handle; u32 round_length; s32 read_length; void *buffer; // Open File if (!DVDOpen(path, &handle)) { OSReport("WARNING! Failed to open %s\n", path); return NULL; } // Make sure file length is not 0 if (DVDGetLength(&handle) == 0) { OSReport("WARNING! File length is 0\n"); return NULL; } round_length = OSRoundUp32B(DVDGetLength(&handle)); buffer = MEMAllocFromExpHeapEx(hExpHeap, round_length, 32); // Make sure we got a buffer if (buffer == NULL) { OSReport("WARNING! Unable to allocate buffer\n"); return NULL; } // Read Files read_length = DVDRead(&handle, buffer, (s32)(round_length), 0); // Make sure we read the file correctly if (read_length <= 0) { OSReport("WARNING! File lenght is wrong\n"); return NULL; } return buffer; } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void* PrivateAlloc(u32 size) { return MEMAllocFromExpHeapEx(hExpHeap, size, 32); } /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ static void PrivateFree(void* addr) { MEMFreeToExpHeap(hExpHeap, addr); } #endif /*---------------------------------------------------------------------------* *---------------------------------------------------------------------------*/ void main(void) { DEMOWinInfo *profile_win; DEMOWinInfo *status_win; DEMOWinMenuInfo *control_menu_ptr; #ifndef HOLLYWOOD_REV u32 aramBase; u32 aramSize; #else void *arenaMem2Lo; void *arenaMem2Hi; #endif // set flags used for menu auxa = auxb = sampleset = 0; exitProgram = 0; sequenceInitialized = 0; // initialize bean counters for profiling maxCpuCycles = maxAuxCycles = maxUserCycles = maxAxCycles = maxVoices = 0; // initialize subsystems DEMOInit(NULL); DEMOWinInit(); #ifndef HOLLYWOOD_REV ARInit(aramMemArray, MAX_ARAM_BLOCKS); ARQInit(); #else arenaMem2Lo = OSGetMEM2ArenaLo(); arenaMem2Hi = OSGetMEM2ArenaHi(); hExpHeap = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo); #endif AIInit(NULL); // initialize windows on the TV control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20); profile_win = DEMOWinCreateWindow(300, 20, 600, 170, "AX Profile", 1024, updateProfile); status_win = DEMOWinCreateWindow(300, 175, 600, 245, "Sequence Status", 1024, updateStatus); log_win = DEMOWinCreateWindow(20, 250, 600, 400, "Log", 1024, NULL); DEMOWinOpenWindow(control_menu_ptr->handle); DEMOWinOpenWindow(profile_win); DEMOWinOpenWindow(status_win); DEMOWinOpenWindow(log_win); DEMOWinLogPrintf(log_win, "Setting up audio\n"); setupAudioSystem(); #ifndef HOLLYWOOD_REV // for the purpose of this demo we take all the ARAM *chuckle* aramSize = ARGetSize() - ARGetBaseAddress(); aramBase = ARAlloc(aramSize); AMInit(aramBase, aramSize); // push sample data into ARAM aramBasePcm = AMPush("/axdemo/synth/gm16pcm.pcm"); aramBaseAdpcm = AMPush("/axdemo/synth/gm16adpcm.pcm"); // load table data into main memory wavetablePcm = AMLoadFile("/axdemo/synth/gm16pcm.wt", NULL); wavetableAdpcm = AMLoadFile("/axdemo/synth/gm16adpcm.wt", NULL); // default to PCM samples wavetable = wavetablePcm; arambase = aramBasePcm; zeroBase = AMGetZeroBuffer(); #else // load sample data into main memory samplesPcm = LoadFileIntoRam("/axdemo/synth/gm16pcm.pcm"); samplesAdpcm = LoadFileIntoRam("/axdemo/synth/gm16adpcm.pcm"); // load table data into main memory wavetablePcm = LoadFileIntoRam("/axdemo/synth/gm16pcm.wt"); wavetableAdpcm = LoadFileIntoRam("/axdemo/synth/gm16adpcm.wt"); // default to PCM samples wavetable = wavetablePcm; samples = samplesPcm; zeroBuffer = MEMAllocFromExpHeapEx(hExpHeap, ZEROBUFFER_BYTES, 8); memset(zeroBuffer, 0, ZEROBUFFER_BYTES); DCFlushRange(zeroBuffer, ZEROBUFFER_BYTES); #endif #ifdef HOLLYWOOD_REV AXFXSetHooks((AXFXAlloc)PrivateAlloc, (AXFXFree)PrivateFree); #endif while (1) { DEMOWinMenu(control_menu_ptr); if (exitProgram == 1) break; } DEMOWinLogPrintf(log_win, "Shutting down up audio\n"); DEMOBeforeRender(); DEMOWinRefresh(); DEMODoneRender(); shutdownAudioSystem(); DEMOWinLogPrintf(log_win, "Free wavetable\n"); DEMOBeforeRender(); DEMOWinRefresh(); DEMODoneRender(); #ifndef HOLLYWOOD_REV if (wavetablePcm) { OSFree(wavetablePcm); } if (wavetableAdpcm) { OSFree(wavetableAdpcm); } if (midiFile) { OSFree(midiFile); } #else if (wavetablePcm) { MEMFreeToExpHeap(hExpHeap, wavetablePcm); } if (wavetableAdpcm) { MEMFreeToExpHeap(hExpHeap, wavetableAdpcm); } if (midiFile) { MEMFreeToExpHeap(hExpHeap, midiFile); } if (samplesPcm) { MEMFreeToExpHeap(hExpHeap, samplesPcm); } if (samplesAdpcm) { MEMFreeToExpHeap(hExpHeap, samplesAdpcm); } if (zeroBuffer) { MEMFreeToExpHeap(hExpHeap, zeroBuffer); } #endif OSHalt("End of program\n"); }