internal static unsafe byte[] ToRSTM(FSTMHeader *fstm) { FSTMDataInfo fstmDataInfo = fstm->INFOData->_dataInfo; int channels = fstmDataInfo._format._channels; // Get section sizes from the BRSTM - BFSTM is such a similar format that we can assume the sizes will match. int rstmSize = 0x40; int infoSize = fstm->_infoBlockSize; int seekSize = fstm->_seekBlockSize; int dataSize = fstm->_dataBlockSize; //Create byte array byte[] array = new byte[rstmSize + infoSize + seekSize + dataSize]; fixed(byte *address = array) { //Get section pointers RSTMHeader * rstm = (RSTMHeader *)address; HEADHeader * info = (HEADHeader *)((byte *)rstm + rstmSize); ADPCHeader * seek = (ADPCHeader *)((byte *)info + infoSize); RSTMDATAHeader *data = (RSTMDATAHeader *)((byte *)seek + seekSize); //Initialize sections rstm->Set(infoSize, seekSize, dataSize); info->Set(infoSize, channels, (WaveEncoding)fstm->INFOData->_dataInfo._format._encoding); seek->Set(seekSize); data->Set(dataSize); //Set HEAD data *info->Part1 = new StrmDataInfo(fstmDataInfo, rstmSize + infoSize + seekSize + 0x20); //Create one ADPCMInfo for each channel IntPtr * adpcData = stackalloc IntPtr[channels]; ADPCMInfo **pAdpcm = (ADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = info->GetChannelInfo(i)) = new ADPCMInfo(*fstm->INFOData->GetChannelInfo(i)); } bshort *seekFrom = (bshort *)fstm->SEEKData->Data; bshort *seekTo = (bshort *)seek->Data; for (int i = 0; i < seek->_length / 2 - 8; i++) { *(seekTo++) = *(seekFrom++); } VoidPtr dataFrom = fstm->DATAData->Data; VoidPtr dataTo = data->Data; Memory.Move(dataTo, dataFrom, (uint)data->_length - 8); } return(array); }
public FSTMDataInfo(StrmDataInfo o, int dataOffset = 0x18) { _format = o._format; _sampleRate = (ushort)o._sampleRate; _loopStartSample = o._loopStartSample; _numSamples = o._numSamples; _numBlocks = o._numBlocks; _blockSize = o._blockSize; _samplesPerBlock = o._samplesPerBlock; _lastBlockSize = o._lastBlockSize; _lastBlockSamples = o._lastBlockSamples; _lastBlockTotal = o._lastBlockTotal; _bitsPerSample = o._bitsPerSample; _dataInterval = o._dataInterval; _sampleDataRef._type = (short)FSTMReference.RefType.SampleData; _sampleDataRef._padding = 0; _sampleDataRef._dataOffset = dataOffset; }
internal static unsafe byte[] ToRSTM(CSTMHeader *cstm) { CSTMDataInfo cstmDataInfo = cstm->INFOData->_dataInfo; int channels = cstmDataInfo._format._channels; if (cstm->_seekBlockRef._type != CSTMReference.RefType.SeekBlock) { throw new Exception("BrawlLib does not recognize this type of CSTM file (the SEEK block is missing or in an unexpected location.)"); } // Get section sizes from the BRSTM - BCSTM is such a similar format that we can assume the sizes will match. int rstmSize = 0x40; int infoSize = cstm->_infoBlockSize; int seekSize = cstm->_seekBlockSize; int dataSize = cstm->_dataBlockSize; //Create byte array byte[] array = new byte[rstmSize + infoSize + seekSize + dataSize]; fixed(byte *address = array) { //Get section pointers RSTMHeader * rstm = (RSTMHeader *)address; HEADHeader * info = (HEADHeader *)((byte *)rstm + rstmSize); ADPCHeader * seek = (ADPCHeader *)((byte *)info + infoSize); RSTMDATAHeader *data = (RSTMDATAHeader *)((byte *)seek + seekSize); //Initialize sections rstm->Set(infoSize, seekSize, dataSize); info->Set(infoSize, channels, (WaveEncoding)cstm->INFOData->_dataInfo._format._encoding); seek->Set(seekSize); data->Set(dataSize); //Set HEAD data *info->Part1 = new StrmDataInfo(cstmDataInfo, rstmSize + infoSize + seekSize + 0x20); //Create one ADPCMInfo for each channel IntPtr * adpcData = stackalloc IntPtr[channels]; ADPCMInfo **pAdpcm = (ADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = info->GetChannelInfo(i)) = new ADPCMInfo(*cstm->INFOData->GetChannelInfo(i)); } bshort *seekFrom = (bshort *)cstm->SEEKData->Data; short * seekTo = (short *)seek->Data; for (int i = 0; i < seek->_length / 2 - 8; i++) { *(seekTo++) = *(seekFrom++); } VoidPtr dataFrom = cstm->DATAData->Data; VoidPtr dataTo = data->Data; Memory.Move(dataTo, dataFrom, (uint)data->_length - 8); } return(array); }
internal static unsafe byte[] FromRSTM(RSTMHeader *rstm) { StrmDataInfo strmDataInfo = *rstm->HEADData->Part1; int channels = strmDataInfo._format._channels; if (strmDataInfo._format._encoding != (byte)WaveEncoding.ADPCM) { throw new NotImplementedException("CSTM export only supports ADPCM encoding."); } // Get section sizes from the BRSTM - BCSTM is such a similar format that we can assume the sizes will match. int rstmSize = 0x40; int infoSize = rstm->_headLength; int seekSize = rstm->_adpcLength; int dataSize = rstm->_dataLength; //Create byte array byte[] array = new byte[rstmSize + infoSize + seekSize + dataSize]; fixed(byte *address = array) { //Get section pointers CSTMHeader * cstm = (CSTMHeader *)address; CSTMINFOHeader *info = (CSTMINFOHeader *)((byte *)cstm + rstmSize); CSTMSEEKHeader *seek = (CSTMSEEKHeader *)((byte *)info + infoSize); CSTMDATAHeader *data = (CSTMDATAHeader *)((byte *)seek + seekSize); //Initialize sections cstm->Set(infoSize, seekSize, dataSize); info->Set(infoSize, channels); seek->Set(seekSize); data->Set(dataSize); //Set HEAD data info->_dataInfo = new CSTMDataInfo(strmDataInfo); //Create one ADPCMInfo for each channel IntPtr * adpcData = stackalloc IntPtr[channels]; CSTMADPCMInfo **pAdpcm = (CSTMADPCMInfo **)adpcData; for (int i = 0; i < channels; i++) { *(pAdpcm[i] = info->GetChannelInfo(i)) = new CSTMADPCMInfo(*rstm->HEADData->GetChannelInfo(i)); } bshort *seekFrom = (bshort *)rstm->ADPCData->Data; short * seekTo = (short *)seek->Data; for (int i = 0; i < seek->_length / 2 - 8; i++) { *(seekTo++) = *(seekFrom++); } VoidPtr dataFrom = rstm->DATAData->Data; VoidPtr dataTo = data->Data; Memory.Move(dataTo, dataFrom, (uint)data->_length - 8); } return(array); }