void dKPMusic::execute() { if (!s_playing) return; if (s_handle.GetSound() == 0) { nw4r::db::Exception_Printf_("SOUND IS NOT PLAYING!\n"); return; } if (s_countdownToSwitch >= 0) { s_countdownToSwitch--; if (s_countdownToSwitch == 0) { nw4r::db::Exception_Printf_("Switching brstm files to song %d.\n", s_nextSong); char brstmPath[48]; sprintf(brstmPath, "/Sound/new/map%d.er", s_nextSong); u8 *sound = (u8*)(s_handle.GetSound()); u8 *player = sound+0x110; u8 **fileStreamPointer = (u8**)(player+0x808); u8 *fileStream = *fileStreamPointer; DVDHandle *fileInfo = (DVDHandle*)(fileStream+0x28); if (fileInfo->unk4 == 1) { OSReport("Was reading chunk, will try again next frame...\n"); s_countdownToSwitch++; return; } if (s_nextSong > 0) s_countdownToFadeIn = BUFFER_CLEAR_DELAY; DVDCancel(fileInfo); //OSReport("CANCEL successfully called!\n"); bool result = DVDFastOpen(DVDConvertPathToEntrynum(brstmPath), fileInfo); nw4r::db::Exception_Printf_("StrmSound is at %p, StrmPlayer is at %p, FileStream pointer is at %p, FileStream is at %p, FileInfo is at %p\n", sound, player, fileStreamPointer, fileStream, fileInfo); nw4r::db::Exception_Printf_("Changed to name %s. FastOpen returned: %d\n", brstmPath, result); u8 *trackArray = player+0xB58; u8 *track = (trackArray + (0x38 * 1)); u8 **voicePointer = (u8**)(track+4); u8 *voice = *voicePointer; nw4r::db::Exception_Printf_("Track Array: %p; Track: %p; Voice Pointer: %p; Voice: %p\n", trackArray, track, voicePointer, voice); for (int i = 0; i < 2; i++) { int sourceBlockID = (s_nextSong*2)+i; u8 *sourceData = ((u8*)(s_adpcmInfoLoader.buffer)) + (0x30*sourceBlockID); nw4r::db::Exception_Printf_("Using ADPCM data for channel %d from block %d, data at %p\n", i, sourceBlockID, sourceData); if (!voice) continue; Voice_SetADPCMLoop(voice, i, sourceData+0x28); // loop through all axVoices for (int j = 0; j < 4; j++) { int axVoiceID = (i*4) + j; u8 **axVoicePointer = (u8**)(voice + 0xC + (axVoiceID*4)); u8 *axVoice = *axVoicePointer; nw4r::db::Exception_Printf_("Setting AxVoice ID %d, with pointer at %p, located at %p\n", axVoiceID, axVoicePointer, axVoice); if (axVoice) AxVoice_SetADPCM(axVoice, sourceData); } } OSReport("All done\n"); s_song = s_nextSong; s_nextSong = -1; } } else if (s_countdownToFadeIn >= 0) { s_countdownToFadeIn--; if (s_countdownToFadeIn == 0) { OSReport("Going to fade in the second track now!\n"); if (s_handle.Exists()) s_handle.SetTrackVolume(1<<1, FADE_IN_LEN, 1.0f); } } }
/*! ****************************************************************************** * \brief * Open video file. * * This functions opens a video file and parses some basic file * information. * * \param fileName * Name of file to open * * \return * TRUE if file could be opened and is in valid format! * ****************************************************************************** */ BOOL AUDSimpleOpen( char* fileName ) { // u32 fileOffset = 0; // u32 headSize; // u32 audioInfoSize; if( audio_player.open ) { # ifdef _DEBUG OSReport( "*** Cannot open '%s' because audio_player already open.\n", fileName ); # endif return FALSE; } // Initialise the callback status. audio_player.asyncOpenCallbackStatus = 0; s32 entry_num = DVDConvertPathToEntrynum( fileName ); if( entry_num == -1 ) { # ifdef _DEBUG OSReport( "*** Cannot find '%s'\n", filename ); # endif return FALSE; } if( DVDFastOpen( entry_num, &audio_player.fileHandle ) == FALSE ) { # ifdef _DEBUG OSReport( "*** Cannot open: '%s'\n", fileName ); # endif return FALSE; } // Set callback status to indicate file is now open. audio_player.asyncOpenCallbackStatus = 1; // Read 'VID1' chunk from file and check for correct version. // if( DVDRead( &audio_player.fileHandle, &workChunk, 32, 0 ) < 0 ) if( DVDReadAsync( &audio_player.fileHandle, &workChunk, 32, 0, AUDSimpleOpenDVDCallback ) < 0 ) { # ifdef _DEBUG OSReport( "*** Failed to read the header for %s.\n", fileName ); # endif DVDClose( &audio_player.fileHandle ); return FALSE; } strncpy( audio_player.fileName, fileName, 64 ); audio_player.fileName[63] = 0; // Nothing more to do here. return TRUE; // fileOffset += 32; // Check file id // if( workChunk.id != VID_FCC('V','I','D','1' )) // { //# ifdef _DEBUG // OSReport("*** No VID1 file: '%s'\n", fileName); //# endif // DVDClose( &audio_player.fileHandle ); // return FALSE; // } // Check for correct version of vid chunk. // If we find this version we assume a 'special' alignment and chunk ordering which may be invalid // in another version of the file format. // if( workChunk.vid.versionMajor != 1 || workChunk.vid.versionMinor != 0 ) // { //# ifdef _DEBUG // OSReport("*** Unsupported file version: major: %d, minor: %d\n", workChunk.vid.versionMajor, workChunk.vid.versionMajor); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } //# ifdef _DEBUG // Sometimes, it's required to check for a special build of the VidConv converter. // { // u32 version = VID_VERSION(workChunk.vid.vidConvMajor, workChunk.vid.vidConvMinor, workChunk.vid.vidConvBuild); // if(version < VID_VERSION(1,0,1)) // OSReport("*** WARNING: Vid file created using an unsupported converter version: %d.%d.%d\n", (u32)workChunk.vid.vidConvMajor, (u32)workChunk.vid.vidConvMinor, (u32)workChunk.vid.vidConvBuild); // } //# endif // Check types of chunks we have in this file. // !!! Note that we assume start of 'HEAD' chunk at byte offset 32 from file start !!! // if( DVDRead( &audio_player.fileHandle, &workChunk, 32, (s32)fileOffset ) < 0 ) // { //# ifdef _DEBUG // OSReport("*** Failed to read 'HEAD' chunk.\n"); //# endif // DVDClose( &audio_player.fileHandle ); // return FALSE; // } // if( workChunk.id != VID_FCC('H','E','A','D' )) // { //# ifdef _DEBUG // OSReport("*** No HEAD chunk found at expected offset\n"); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // Calculate the start of the first frame chunk // (we know the header chunk starts at offset 32) // audio_player.nextFrameOffset = workChunk.len + 32; // Skip 'HEAD' chunk id, len and version fields // fileOffset += VID_CHUNK_HEADER_SIZE; // The header chunk contains one or more header chunks for the different data types contained // in the stream. Parse them all... // headSize = workChunk.len - VID_CHUNK_HEADER_SIZE; // while( headSize >= 32 ) // { // if( DVDRead( &audio_player.fileHandle, &workChunk, 32, (s32)fileOffset ) < 0 ) // { //# ifdef _DEBUG // OSReport("*** Error reading file at offset %d\n", fileOffset); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // fileOffset += 32; // headSize -= 32; // We analyze the 1st 32 bytes of the chunk for a known header format // if(workChunk.id == VID_FCC('A','U','D','H')) // { // Allocate memory for audio header chunk // audio_player.audioHeaderChunk = (u8*)((*audio_player.cbAlloc)(workChunk.len)); // audioInfoSize = workChunk.len - VID_CHUNK_HEADER_SIZE; // Copy the already loaded part // memcpy(audio_player.audioHeaderChunk, &workChunk, 32); // workChunk.len -= 32; // Read additional audio header bytes if the audio header is greater that 32 bytes // if(workChunk.len >= 32) // { // ASSERT((workChunk.len&31)==0); // if( DVDRead( &audio_player.fileHandle, audio_player.audioHeaderChunk + 32, workChunk.len, (s32)fileOffset ) < 0 ) // { //# ifdef _DEBUG // OSReport("*** Error reading file at offset %d\n", fileOffset); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // fileOffset += workChunk.len; // headSize -= workChunk.len; // } // Setup and calc the number of bytes which we are allowed to copy into the audioInfo struct // memcpy(&audio_player.audioInfo, audio_player.audioHeaderChunk+VID_CHUNK_HEADER_SIZE, MIN(audioInfoSize, sizeof(audio_player.audioInfo))); // } // else // { // // Skip unknown chunks. We already read 32 bytes for the header which we must subtract here. // fileOffset += workChunk.len - 32; /// headSize -= workChunk.len - 32; // } // } // check if we have the correct vaud file version (>0) // if(audio_player.audioInfo.vaudex.version == 0) // { //# ifdef _DEBUG // OSReport("*** Invalid version in vaud file."); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // we can only play audio files which have the following fiels set. // Note that in case of VIDEO files this fields are allowed to be 0. // ASSERT(audio_player.audioInfo.vaudex.maxBufferSize > 0); // ASSERT(audio_player.audioInfo.vaudex.frameCount > 0); // ASSERT(audio_player.audioInfo.vaudex.frameTimeMs > 0); // read beginning of 1st frame chunk to get required size information // if( DVDRead( &audio_player.fileHandle, &workChunk, 32 , (s32)audio_player.nextFrameOffset ) < 0 ) // { //# ifdef _DEBUG // OSReport("*** Failed to read 'FRAM' chunk.\n"); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // if( workChunk.id != VID_FCC('F','R','A','M') ) // { //# ifdef _DEBUG // OSReport("*** No FRAM chunk found."); //# endif // DVDClose(&audio_player.fileHandle); // return FALSE; // } // audio_player.nextFrameSize = workChunk.len; // 32 bytes of this chunk are already consumed, but we want to 'preload' the NEXT chunk's FRAM header // audio_player.nextFrameOffset += 32; // audio_player.firstFrameOffset = audio_player.nextFrameOffset; // audio_player.firstFrameSize = audio_player.nextFrameSize; // strncpy(audio_player.fileName, fileName, 64); // audio_player.fileName[63] = 0; // audio_player.open = TRUE; // audio_player.readIndex = 0; // audio_player.decodeIndex = 0; // audio_player.lastDecodedFrame = 0; // audio_player.error = FALSE; // audio_player.preFetchState = FALSE; // audio_player.loopMode = FALSE; // audio_player.asyncDvdRunning = FALSE; // audio_player.currentFrameCount = 0; // audio_player.readBufferBaseMem = 0; // return TRUE; }