/// <summary> /// Write a file header. /// </summary> /// <param name="bw">The writer.</param> public void Write(ref BinaryDataWriter bw) { //Make big endian for now. bw.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; bw.Write(magic); bw.Write(byteOrder); //Get real byte order. Syroot.BinaryData.ByteOrder bo = Syroot.BinaryData.ByteOrder.BigEndian; if (byteOrder == ByteOrder.LittleEndian) { bo = Syroot.BinaryData.ByteOrder.LittleEndian; } bw.ByteOrder = bo; bw.Write(headerSize); UpdateVersion(); bw.Write(version); bw.Write(size); bw.Write(nBlocks); bw.Write(padding); foreach (SizedReference sr in blockOffsets) { sr.Write(ref bw); } bw.Write(reserved); }
/// <summary> /// Update sequence data. /// </summary> public void UpdateSeqData(WriteMode writeMode) { //Write sequence data. Syroot.BinaryData.ByteOrder bo = Syroot.BinaryData.ByteOrder.BigEndian; if (writeMode == WriteMode.NX || writeMode == WriteMode.C_BE) { bo = Syroot.BinaryData.ByteOrder.LittleEndian; } goodData = SequenceData.ToBytes(bo); }
public void Write(WriteMode writeMode, BinaryDataWriter bw) { switch (writeMode) { case WriteMode.Cafe: case WriteMode.C_BE: ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; break; case WriteMode.NX: case WriteMode.CTR: ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; break; } }
/// <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 { } }
public void Write(BinaryDataWriter bw) { ByteOrder = bw.ByteOrder; bw.Write(ToBytes()); }
/// <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 bars from bytes. /// </summary> /// <param name="src"></param> public void Load(byte[] b) { MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); fileHeader = new Header(ref br); numTracks = br.ReadUInt32(); trackInfo = new List <UInt32>(); for (int i = 0; i < numTracks; i++) { trackInfo.Add(br.ReadUInt32()); } fileReferences = new FileReference[numTracks]; for (int i = 0; i < numTracks; i++) { fileReferences[i] = new FileReference() { AMTAOffset = br.ReadUInt32(), WAVOffset = br.ReadUInt32() }; } amtas = new List <AMTA>(); wavs = new List <b_wav>(); for (int i = 0; i < numTracks; i++) { long basePos = br.Position; Syroot.BinaryData.ByteOrder b2 = br.ByteOrder; br.Position = fileReferences[i].AMTAOffset; AMTA a = new AMTA(); a.magic = new string(br.ReadChars(4)); a.byteOrder = br.ReadUInt16(); if (a.byteOrder == ByteOrder.BigEndian) { br.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; } else { br.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; } a.byteOrder = ByteOrder.BigEndian; a.version = br.ReadUInt16(); a.chunkSize = br.ReadUInt32(); a.dataOffset = br.ReadUInt32(); a.markOffset = br.ReadUInt32(); a.extOffset = br.ReadUInt32(); a.strgOffset = br.ReadUInt32(); a.data = new AMTA.Data(); a.mark = new AMTA.Mark(); a.ext = new AMTA.Ext(); a.strg = new AMTA.Strg(); br.Position = basePos + a.dataOffset; a.data.magic = new string(br.ReadChars(4)); a.data.restOfSize = br.ReadUInt32(); a.data.unknown = br.ReadBytes((int)a.data.restOfSize); br.Position = basePos + a.markOffset; a.mark.magic = new string(br.ReadChars(4)); a.mark.restOfSize = br.ReadUInt32(); a.mark.unknown = br.ReadBytes((int)a.mark.restOfSize); br.Position = basePos + a.extOffset; a.ext.magic = new string(br.ReadChars(4)); a.ext.restOfSize = br.ReadUInt32(); a.ext.unknown = br.ReadBytes((int)a.ext.restOfSize); br.Position = basePos + a.strgOffset; a.strg.magic = new string(br.ReadChars(4)); a.strg.restOfSize = br.ReadUInt32(); a.strg.trackName = new string(br.ReadChars((int)a.strg.restOfSize - 1)); br.ByteOrder = b2; } for (int i = 0; i < numTracks; i++) { br.Position = fileReferences[i].WAVOffset; br.ReadUInt32s(3); b_wav w = new b_wav(); int length = (int)br.ReadUInt32(); br.Position -= 12; w.Load(br.ReadBytes(length)); wavs.Add(w); } }
/// <summary> /// Read the sequence data. /// </summary> /// <param name="br">The reader.</param> public void Read(BinaryDataReader br) { //Open file. FileReader FileReader = new FileReader(); FileReader.OpenFile(br, out writeMode, out Version); //Data block. FileReader.OpenBlock(br, 0); //Get size. br.Position -= 4; uint size = br.ReadUInt32(); //Read the sequence data. BE for WiiU and 3ds, LE for NX. Must therefore write a parser. List <byte> tempSeqData = br.ReadBytes((int)size - 8).ToList(); //Trim data. bool foundEnd = false; while (!foundEnd) { //Remove padding stuff. if (tempSeqData[tempSeqData.Count - 1] == 0) { tempSeqData.RemoveAt(tempSeqData.Count - 1); } //Found end. else { foundEnd = true; } } //Close data block. FileReader.CloseBlock(br); //Label block. FileReader.OpenBlock(br, 1); //Open the reference table. FileReader.OpenReferenceTable(br, "Labels"); //Go through all the references. Labels = new List <SequenceLabel>(); for (int i = 0; i < FileReader.ReferenceTableCount("Labels"); i++) { //Reference is null. if (FileReader.ReferenceTableReferenceIsNull(i, "Labels")) { Labels.Add(null); } //Label exist. else { //Jump to label. FileReader.ReferenceTableJumpToReference(br, i, "Labels"); //Start label info structure. FileReader.StartStructure(br); //Get reference to data. FileReader.OpenReference(br, "ToSeqData"); //String size. uint stringSize = br.ReadUInt32(); //String data. string labelNow = new string(br.ReadChars((int)stringSize)); //Get label info. Labels.Add(new SequenceLabel() { Offset = FileReader.ReferenceGetOffset("ToSeqData"), Label = labelNow }); //Close reference. FileReader.CloseReference("ToSeqData"); //End label info structure. FileReader.EndStructure(); } } //Close the reference table. FileReader.CloseReferenceTable("Labels"); //Close label block. FileReader.CloseBlock(br); //Convert labels to dictionary. Dictionary <string, int> publicLabels = new Dictionary <string, int>(); foreach (var e in Labels) { if (e != null) { publicLabels.Add(e.Label, e.Offset); } } //Set sequence data. SequenceData = new SequenceData(); SequenceData.PublicLabelOffsets = publicLabels; Syroot.BinaryData.ByteOrder bo = Syroot.BinaryData.ByteOrder.BigEndian; if (writeMode == WriteMode.NX || writeMode == WriteMode.C_BE) { bo = Syroot.BinaryData.ByteOrder.LittleEndian; } SequenceData.Read(tempSeqData.ToArray(), bo); goodData = tempSeqData.ToArray(); //Close file. FileReader.CloseFile(br); }
/// <summary> /// Write the sequence file. /// </summary> /// <param name="writeMode">Write mode.</param> /// <param name="bw">The writer.</param> public void Write(WriteMode writeMode, BinaryDataWriter bw) { //Update sequence data if write mode changed. if (this.writeMode != writeMode) { UpdateSeqData(writeMode); } //Set write mode. this.writeMode = writeMode; //Init file. FileWriter FileWriter = new FileWriter(); FileWriter.InitFile(bw, writeMode, "SEQ", 2, Version); //Data block. FileWriter.InitBlock(bw, ReferenceTypes.SEQ_Block_Data, "DATA"); //Write sequence data. Syroot.BinaryData.ByteOrder bo = Syroot.BinaryData.ByteOrder.BigEndian; if (writeMode == WriteMode.NX || writeMode == WriteMode.C_BE) { bo = Syroot.BinaryData.ByteOrder.LittleEndian; } //bw.Write(SequenceData.ToBytes(bo)); bw.Write(goodData); //Align. FileWriter.Align(bw, 0x20); //Close data block. FileWriter.CloseBlock(bw); //Label block. FileWriter.InitBlock(bw, ReferenceTypes.SEQ_Block_Label, "LABL"); //Label table. FileWriter.InitReferenceTable(bw, Labels.Count, "Labels"); //Write each label. foreach (SequenceLabel l in Labels) { //Label is null. if (l == null) { FileWriter.AddReferenceTableNullReference("Labels"); } //Not null. else { //Add reference. FileWriter.AddReferenceTableReference(bw, ReferenceTypes.SEQ_LabelInfo, "Labels"); //Write data. bw.Write(ReferenceTypes.General); bw.Write((UInt16)0); bw.Write(l.Offset); bw.Write((UInt32)l.Label.Length); bw.Write(l.Label.ToCharArray()); //Add null terminator. bw.Write('\0'); //Align to 4 bytes. FileWriter.Align(bw, 4); } } //Close labels. FileWriter.CloseReferenceTable(bw, "Labels"); //Align. FileWriter.Align(bw, 0x20); //Close label block. FileWriter.CloseBlock(bw); //Close file. FileWriter.CloseFile(bw); }