/// <summary> /// New binary wave. /// </summary> /// <param name="wave">Wave to create this from.</param> public BinaryWave(b_wav wave) { //Set data. ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; Major = 0; Minor = 1; SampleRate = wave.info.sampleRate; NumSamples = wave.info.loopEnd; switch (wave.info.encoding) { case 0: wave.data.dspAdpcm = EncoderFactory.Pcm16ToDspApdcmWAV(EncoderFactory.SignedPcm8ToPcm16(wave.data.pcm8), ref wave); break; case 1: wave.data.dspAdpcm = EncoderFactory.Pcm16ToDspApdcmWAV(wave.data.pcm16, ref wave); break; } DspAdpcmInfo = new DspAdpcmInfo[wave.info.channelInfo.Count]; for (int i = 0; i < DspAdpcmInfo.Length; i++) { DspAdpcmInfo[i] = wave.info.channelInfo[i].dspAdpcmInfo; } Loops = wave.info.isLoop; LoopStartSample = wave.info.loopStart; LoopEndSample = wave.info.loopEnd; Data = wave.data; //Do channel pans. ChannelPans = new ChannelPan[wave.info.channelInfo.Count()]; for (int i = 0; i < wave.info.channelInfo.Count(); i++) { if (i == wave.info.channelInfo.Count() - 1) { ChannelPans[i] = ChannelPan.Middle; } else if (i % 2 == 0) { ChannelPans[i] = ChannelPan.Left; ChannelPans[i] = ChannelPan.Right; } } }
/// <summary> /// Load a wave file. /// </summary> /// <param name="b">The byte array.</param> public void Load(byte[] b) { //Read file. MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); //Get byte order. br.ByteOrder = ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; br.Position = 4; if (br.ReadUInt16() == CitraFileLoader.ByteOrder.LittleEndian) { br.ByteOrder = ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; } //Get version. ushort version = br.ReadUInt16(); Major = (byte)((version & 0xFF00) >> 8); Minor = (byte)(version & 0xFF); //Get num channels. br.Position = 0x0E; ushort numChannels = br.ReadUInt16(); ChannelPans = new ChannelPan[numChannels]; //Get codic. Reference:vgmstream/src/meta/bwav.c . br.Position = 0x10; Codic = br.ReadUInt16(); //Get info from first channel. br.Position = 0x12; ChannelPans[0] = (ChannelPan)br.ReadUInt16(); SampleRate = br.ReadUInt32(); NumSamples = br.ReadUInt32(); br.ReadUInt32(); DspAdpcmInfo = new DspAdpcmInfo[numChannels]; DspAdpcmInfo[0] = new DspAdpcmInfo(); DspAdpcmInfo[0].coefs = new short[8][]; DspAdpcmInfo[0].coefs[0] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[1] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[2] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[3] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[4] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[5] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[6] = br.ReadInt16s(2); DspAdpcmInfo[0].coefs[7] = br.ReadInt16s(2); //Start offsets. uint[] startOffsets = new uint[numChannels]; startOffsets[0] = br.ReadUInt32(); br.Position += 4; //Loop info. Loops = br.ReadUInt32() > 0; LoopEndSample = br.ReadUInt32(); LoopStartSample = br.ReadUInt32(); //More DSP info. DspAdpcmInfo[0].pred_scale = DspAdpcmInfo[0].loop_pred_scale = br.ReadUInt16(); DspAdpcmInfo[0].yn1 = DspAdpcmInfo[0].loop_yn1 = br.ReadInt16(); DspAdpcmInfo[0].yn2 = DspAdpcmInfo[0].loop_yn2 = br.ReadInt16(); //Read each channel start offset. for (int i = 1; i < numChannels; i++) { //Get channel pan. br.Position = i * 0x4C + 0x10 + 0x2; ChannelPans[i] = (ChannelPan)br.ReadUInt16(); //Start offset. br.Position = i * 0x4C + 0x10 + 0x30; startOffsets[i] = br.ReadUInt32(); //Get DSP info. br.Position = i * 0x4C + 0x10 + 0x10; DspAdpcmInfo[i] = new DspAdpcmInfo(); DspAdpcmInfo[i].coefs = new short[8][]; DspAdpcmInfo[i].coefs[0] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[1] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[2] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[3] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[4] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[5] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[6] = br.ReadInt16s(2); DspAdpcmInfo[i].coefs[7] = br.ReadInt16s(2); br.Position += 20; DspAdpcmInfo[i].pred_scale = DspAdpcmInfo[i].loop_pred_scale = br.ReadUInt16(); DspAdpcmInfo[i].yn1 = DspAdpcmInfo[i].loop_yn1 = br.ReadInt16(); DspAdpcmInfo[i].yn2 = DspAdpcmInfo[i].loop_yn2 = br.ReadInt16(); } //Read the wave data. Data = new SoundNStreamDataBlock(br, startOffsets); try { br.Dispose(); } catch { } try { src.Dispose(); } catch { } }
/// <summary> /// New binary wave. /// </summary> /// <param name="s">The stream.</param> public BinaryWave(b_stm s) { //Set data. ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; Major = 0; Minor = 1; SampleRate = s.info.streamSoundInfo.sampleRate; NumSamples = s.info.streamSoundInfo.sampleCount; switch (s.info.streamSoundInfo.encoding) { case 0: s.data.dspAdpcm = EncoderFactory.Pcm16ToDspAdpcmSTM(EncoderFactory.SignedPcm8ToPcm16(s.data.pcm8), s); break; case 1: s.data.dspAdpcm = EncoderFactory.Pcm16ToDspAdpcmSTM(s.data.pcm16, s); break; } DspAdpcmInfo = new DspAdpcmInfo[s.info.channels.Count]; for (int i = 0; i < DspAdpcmInfo.Length; i++) { DspAdpcmInfo[i] = s.info.channels[i].dspAdpcmInfo; } Loops = s.info.streamSoundInfo.isLoop; LoopStartSample = s.info.streamSoundInfo.loopStart; LoopEndSample = s.info.streamSoundInfo.sampleCount; Data = s.data; //Do channel pans. ChannelPans = new ChannelPan[s.info.channels.Count]; for (int i = 0; i < s.info.channels.Count; i++) { if (i == s.info.channels.Count - 1) { ChannelPans[i] = ChannelPan.Middle; } else if (i % 2 == 0) { ChannelPans[i] = ChannelPan.Left; ChannelPans[i + 1] = ChannelPan.Right; i++; } } if (s.info.tracks != null) { foreach (var t in s.info.tracks) { if (t.globalChannelIndexTable.count > 0) { if (t.globalChannelIndexTable.count > 1) { ChannelPans[t.globalChannelIndexTable.entries[0]] = ChannelPan.Left; ChannelPans[t.globalChannelIndexTable.entries[1]] = ChannelPan.Right; } else { ChannelPans[t.globalChannelIndexTable.entries[0]] = ChannelPan.Middle; } } } } }
/// <summary> /// Load a file. /// </summary> /// <param name="b">The file.</param> public void Load(byte[] b) { //Set up the reader. MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); //Read the header. fileHeader = new FileHeader(ref br); //Read blocks. foreach (SizedReference s in fileHeader.blockOffsets) { if (s.offset != Reference.NULL_PTR) { br.Position = s.offset; switch (s.typeId) { //Info block. case ReferenceTypes.STRM_Block_Info: long basePos = br.Position + 8; info = new InfoBlock() { magic = br.ReadChars(4), blockSize = br.ReadUInt32(), streamSoundInfoRef = new Reference(ref br), trackInfoTableRef = new Reference(ref br), channelInfoTableRef = new Reference(ref br), streamSoundInfo = null, trackInfoRefTable = null, channelInfoRefTable = null, tracks = null, channels = null }; //Stream sound info. if (info.streamSoundInfoRef.typeId == ReferenceTypes.STRM_Info_StreamSound && info.streamSoundInfoRef.offset != Reference.NULL_PTR) { br.Position = basePos + info.streamSoundInfoRef.offset; info.streamSoundInfo = new StreamSoundInfo() { encoding = br.ReadByte(), isLoop = br.ReadBoolean(), channelCount = br.ReadByte(), regionCount = br.ReadByte(), sampleRate = br.ReadUInt32(), loopStart = br.ReadUInt32(), sampleCount = br.ReadUInt32(), blockCount = br.ReadUInt32(), oneBlockBytesize = br.ReadUInt32(), oneBlockSamples = br.ReadUInt32(), lastBlockBytesize = br.ReadUInt32(), lastBlockSamples = br.ReadUInt32(), lastBlockPaddedBytesize = br.ReadUInt32(), sizeOfSeekInfo = br.ReadUInt32(), seekInfoIntervalSamples = br.ReadUInt32(), sampleDataOffset = new Reference(ref br), regionInfoBytesize = 0x100, padding = 0, regionDataOffset = new Reference(0, 0x18), originalLoopStart = 0, originalLoopEnd = 0, secretInfo = 0 }; if (fileHeader.vMajor >= regionInfo) { info.streamSoundInfo.regionInfoBytesize = br.ReadUInt16(); info.streamSoundInfo.padding = br.ReadUInt16(); info.streamSoundInfo.regionDataOffset = new Reference(ref br); } if (fileHeader.vMajor >= originalLoopInfo) { info.streamSoundInfo.originalLoopStart = br.ReadUInt32(); info.streamSoundInfo.originalLoopEnd = br.ReadUInt32(); } if (fileHeader.vMajor >= secretInfo) { info.streamSoundInfo.secretInfo = br.ReadUInt32(); } } //Track info. if (info.trackInfoTableRef.typeId == ReferenceTypes.Tables + 1 && info.trackInfoTableRef.offset != Reference.NULL_PTR) { br.Position = basePos + info.trackInfoTableRef.offset; long newPos = br.Position; info.trackInfoRefTable = new ReferenceTable(ref br); //Get tracks. info.tracks = new List <TrackInfo>(); foreach (Reference r in info.trackInfoRefTable.references) { TrackInfo t = null; if (r.typeId == ReferenceTypes.STRM_Info_Track && r.offset != Reference.NULL_PTR) { br.Position = newPos + r.offset; t = new TrackInfo() { volume = br.ReadByte(), pan = br.ReadByte(), span = br.ReadByte(), surroundMode = br.ReadByte(), globalChannelIndexTableRef = new Reference(ref br), globalChannelIndexTable = null }; if (t.globalChannelIndexTableRef.offset != Reference.NULL_PTR) { br.Position = newPos + r.offset + t.globalChannelIndexTableRef.offset; t.globalChannelIndexTable = new Table <byte>(); t.globalChannelIndexTable.count = br.ReadUInt32(); t.globalChannelIndexTable.entries = new List <byte>(); for (int i = 0; i < t.globalChannelIndexTable.count; i++) { t.globalChannelIndexTable.entries.Add(br.ReadByte()); } } } info.tracks.Add(t); } } //Channel info. if (info.channelInfoTableRef.typeId == ReferenceTypes.Tables + 1 && info.channelInfoTableRef.offset != Reference.NULL_PTR) { br.Position = basePos + info.channelInfoTableRef.offset; long newPos = br.Position; info.channelInfoRefTable = new ReferenceTable(ref br); //Get channels. info.channels = new List <ChannelInfo>(); foreach (Reference r in info.channelInfoRefTable.references) { ChannelInfo c = null; if (r.offset != Reference.NULL_PTR) { br.Position = newPos + r.offset; c = new ChannelInfo() { dspAdpcmInfoRef = new Reference(ref br), dspAdpcmInfo = null }; if (c.dspAdpcmInfoRef.offset != Reference.NULL_PTR) { br.Position = newPos + r.offset + c.dspAdpcmInfoRef.offset; c.dspAdpcmInfo = new DspAdpcmInfo(); c.dspAdpcmInfo = new DspAdpcmInfo() { coefs = new short[8][] }; c.dspAdpcmInfo.coefs[0] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[1] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[2] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[3] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[4] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[5] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[6] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[7] = br.ReadInt16s(2); c.dspAdpcmInfo.pred_scale = br.ReadUInt16(); c.dspAdpcmInfo.yn1 = br.ReadInt16(); c.dspAdpcmInfo.yn2 = br.ReadInt16(); c.dspAdpcmInfo.loop_pred_scale = br.ReadUInt16(); c.dspAdpcmInfo.loop_yn1 = br.ReadInt16(); c.dspAdpcmInfo.loop_yn2 = br.ReadInt16(); } } info.channels.Add(c); } } break; //Seek block. case ReferenceTypes.STRM_Block_Seek: seek = new SoundNStreamSeekBlock(ref br, info.streamSoundInfo, fileHeader); break; //Region block. case ReferenceTypes.STRM_Block_Region: region = new SoundNStreamRegionBlock(ref br, info.streamSoundInfo); break; //Data block. case ReferenceTypes.STRM_Block_Data: data = new SoundNStreamDataBlock(ref br, info); break; } } } }
/// <summary> /// Load a file. /// </summary> /// <param name="b">The file.</param> public void Load(byte[] b) { //Set up the reader. MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); //Read file header. fileHeader = new FileHeader(ref br); //Read info block. info = null; if (fileHeader.blockOffsets[0].offset != Reference.NULL_PTR && fileHeader.blockOffsets[0].typeId == ReferenceTypes.WAV_Block_Info) { br.Position = fileHeader.blockOffsets[0].offset; info = new InfoBlock { magic = br.ReadChars(4), blockSize = br.ReadUInt32(), encoding = br.ReadByte(), isLoop = br.ReadBoolean(), padding = br.ReadUInt16(), sampleRate = br.ReadUInt32(), loopStart = br.ReadUInt32(), loopEnd = br.ReadUInt32(), originalLoopStart = br.ReadUInt32(), channelInfoRefTable = new ReferenceTable(ref br), channelInfo = new List <InfoBlock.ChannelInfo>() }; //Read channel info. foreach (Reference r in info.channelInfoRefTable.references) { //Set position. br.Position = 0x5C + r.offset; //New channel info. InfoBlock.ChannelInfo c = new InfoBlock.ChannelInfo() { samplesRef = new Reference(ref br), dspAdpcmInfoRef = new Reference(ref br), reserved = br.ReadUInt32(), dspAdpcmInfo = null }; //Read Dsp-Apdcm info. if (c.dspAdpcmInfoRef.offset != Reference.NULL_PTR) { br.Position = 0x5C + r.offset + c.dspAdpcmInfoRef.offset; c.dspAdpcmInfo = new DspAdpcmInfo(); c.dspAdpcmInfo.coefs = new Int16[8][]; c.dspAdpcmInfo.coefs[0] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[1] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[2] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[3] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[4] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[5] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[6] = br.ReadInt16s(2); c.dspAdpcmInfo.coefs[7] = br.ReadInt16s(2); c.dspAdpcmInfo.pred_scale = br.ReadUInt16(); c.dspAdpcmInfo.yn1 = br.ReadInt16(); c.dspAdpcmInfo.yn2 = br.ReadInt16(); c.dspAdpcmInfo.loop_pred_scale = br.ReadUInt16(); c.dspAdpcmInfo.loop_yn1 = br.ReadInt16(); c.dspAdpcmInfo.loop_yn2 = br.ReadInt16(); } info.channelInfo.Add(c); } } //Read data block. if (fileHeader.blockOffsets[1].offset != Reference.NULL_PTR && fileHeader.blockOffsets[1].typeId == ReferenceTypes.WAV_Block_Data) { br.Position = fileHeader.blockOffsets[1].offset; data = new SoundNStreamDataBlock(ref br, info); } }