/// <summary> /// Create a standard b_wav. /// </summary> /// <param name="sampleRate">The sample rate.</param> /// <param name="numSamples">Number of samples.</param> /// <param name="samples">Pcm8[][] or Pcm16[][] audio samples.</param> /// <param name="encoding">If samples is Pcm8[][] always 0. Must be 1 or 2 for if samples is Pcm16[][].</param> /// <param name="version">The version of the file.</param> /// <returns></returns> public static b_wav CreateWave(UInt32 sampleRate, UInt32 numSamples, object samples, byte encoding, byte vMajor, byte vMinor, byte vRevision) { //Create wav. b_wav b = new b_wav(); b.fileHeader = new FileHeader("FWAV", ByteOrder.BigEndian, vMajor, vMinor, vRevision, 0, new List <SizedReference>()); b.info = new b_wav.InfoBlock(); b.info.magic = "INFO".ToCharArray(); b.info.encoding = encoding; b.info.isLoop = false; b.info.loopStart = b_wav.InfoBlock.NULL_LOOP; b.info.loopEnd = numSamples; b.info.originalLoopStart = b_wav.InfoBlock.NULL_LOOP; b.info.padding = 0; b.info.sampleRate = sampleRate; b.info.channelInfo = new List <b_wav.InfoBlock.ChannelInfo>(); //Encoding. switch (encoding) { case EncodingTypes.PCM8: b.data = new SoundNStreamDataBlock(EncoderFactory.Pcm8ToSignedPcm8(samples as byte[][]), encoding); for (int i = 0; i < (samples as byte[][]).Length; i++) { b.info.channelInfo.Add(new b_wav.InfoBlock.ChannelInfo() { reserved = 0, dspAdpcmInfo = null }); } break; case EncodingTypes.PCM16: b.data = new SoundNStreamDataBlock(samples, encoding); for (int i = 0; i < (samples as Int16[][]).Length; i++) { b.info.channelInfo.Add(new b_wav.InfoBlock.ChannelInfo() { reserved = 0, dspAdpcmInfo = null }); } break; case EncodingTypes.DSP_ADPCM: b.data = new SoundNStreamDataBlock(EncoderFactory.Pcm16ToDspApdcmWAV(samples as Int16[][], ref b), encoding); break; } b.Update(ByteOrder.BigEndian); //Return wav. return(b); }
/// <summary> /// Create a RIFF wave from a vibration. /// </summary> /// <param name="v">Vibration file.</param> /// <returns>The RIFF wave as a vibration.</returns> public static RiffWave CreateRiffWave(Vibration v) { //New wave. RiffWave r = new RiffWave(); //Not looped. if (!v.Loops) { r = RiffWaveFactory.CreateRiffWave(200, 1, EncoderFactory.SignedPcm8ToPcm8(new sbyte[][] { v.pcm8 })); } //Looped. else { r = RiffWaveFactory.CreateRiffWave(200, 1, EncoderFactory.SignedPcm8ToPcm8(new sbyte[][] { v.pcm8 }), v.LoopStart, v.LoopEnd); } return(r); }
/// <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> /// Create a wave from a FISP. /// </summary> /// <param name="f"></param> /// <returns></returns> public static b_wav CreateWave(FISP f, byte vMajor, byte vMinor, byte vRevision) { //New wave. b_wav b = new b_wav(); //Trim the fat from each loop. object channels = new short[f.data.data.Count()][]; for (int i = 0; i < (channels as short[][]).Length; i++) { List <short> l = new List <short>(); for (int j = 0; j < f.stream.loopEnd; j++) { l.Add(f.data.data[i][j]); } (channels as short[][])[i] = l.ToArray(); } //PCM8 conversion. if (f.stream.encoding == EncodingTypes.PCM8) { channels = EncoderFactory.Pcm16ToPcm8(channels as short[][]); } //If looped. if (f.stream.isLoop) { b = WaveFactory.CreateWave(f.stream.sampleRate, f.stream.loopEnd, channels, f.stream.encoding, vMajor, vMinor, vRevision, f.stream.loopStart); } //Not looped. else { b = WaveFactory.CreateWave(f.stream.sampleRate, f.stream.loopEnd, channels, f.stream.encoding, vMajor, vMinor, vRevision); } //Info. b.info.originalLoopStart = f.stream.originalLoopStart; return(b); }
/// <summary> /// Get data from a b_stm. /// </summary> /// <param name="wavInfo"></param> /// <returns></returns> public object GetDataSTM(b_stm.StreamSoundInfo wavInfo, b_stm.InfoBlock info) { object returnValue = null; //See encoding. switch (wavInfo.encoding) { case EncodingTypes.PCM8: return(EncoderFactory.SignedPcm8ToPcm8(pcm8)); case EncodingTypes.PCM16: return(pcm16); case EncodingTypes.DSP_ADPCM: List <DspAdpcmInfo> context = new List <DspAdpcmInfo>(); foreach (b_stm.ChannelInfo c in info.channels) { context.Add(c.dspAdpcmInfo); } return(EncoderFactory.DspApcmToPcm16(dspAdpcm, wavInfo.sampleCount, context.ToArray())); } return(returnValue); }
/// <summary> /// Get data from a b_wav. /// </summary> /// <param name="wavInfo"></param> /// <returns></returns> public object GetDataWAV(b_wav.InfoBlock wavInfo) { object returnValue = null; //See encoding. switch (wavInfo.encoding) { case EncodingTypes.PCM8: return(EncoderFactory.SignedPcm8ToPcm8(pcm8)); case EncodingTypes.PCM16: return(pcm16); case EncodingTypes.DSP_ADPCM: List <DspAdpcmInfo> context = new List <DspAdpcmInfo>(); foreach (b_wav.InfoBlock.ChannelInfo c in wavInfo.channelInfo) { context.Add(c.dspAdpcmInfo); } return(EncoderFactory.DspApcmToPcm16(dspAdpcm, wavInfo.loopEnd, context.ToArray())); } return(returnValue); }
/// <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> /// Create a seek block from a bunch of samples. /// </summary> /// <param name="pcm16">Pcm16.</param> public SoundNStreamSeekBlock(byte[][] dspAdpcm, uint numSamples, DspAdpcmInfo[] context) { short[][] pcm16 = EncoderFactory.DspApcmToPcm16(dspAdpcm, numSamples, context); InitializeSamples(pcm16, 0x3800); }
/// <summary> /// Get data from a binary wave. /// </summary> /// <param name="info">Dsp-ADPCM info.</param> /// <returns></returns> public object GetDataWAV(DspAdpcmInfo[] info, uint loopEnd) { //Get the data. return(EncoderFactory.DspApcmToPcm16(dspAdpcm, loopEnd, info)); }
/// <summary> /// Create a standard b_stm. /// </summary> /// <param name="sampleRate">The sample rate.</param> /// <param name="numSamples">Number of samples.</param> /// <param name="samples">Pcm8[][] or Pcm16[][] audio samples.</param> /// <param name="encoding">If samples is Pcm8[][] always 0. Must be 1 or 2 for if samples is Pcm16[][].</param> /// <param name="version">The version of the file.</param> /// <returns></returns> public static b_stm CreateStream(UInt32 sampleRate, UInt32 numSamples, object samples, byte encoding, byte vMajor, byte vMinor, byte vRevision) { b_stm s = new b_stm(); s.fileHeader = new FileHeader("FSTM", ByteOrder.BigEndian, vMajor, vMinor, vRevision, 0, new List <SizedReference>()); s.info = new b_stm.InfoBlock(); s.info.streamSoundInfo = new b_stm.StreamSoundInfo(); s.info.tracks = new List <b_stm.TrackInfo>(); s.info.channels = new List <b_stm.ChannelInfo>(); //Stream info. s.info.streamSoundInfo = new b_stm.StreamSoundInfo(); s.info.streamSoundInfo.encoding = encoding; s.info.streamSoundInfo.sampleCount = numSamples; s.info.streamSoundInfo.sampleRate = sampleRate; //Channels. switch (encoding) { case EncodingTypes.PCM8: s.data = new SoundNStreamDataBlock(EncoderFactory.Pcm8ToSignedPcm8(samples as byte[][]), encoding); for (int i = 0; i < (samples as byte[][]).Length; i++) { s.info.channels.Add(new b_stm.ChannelInfo()); } break; case EncodingTypes.PCM16: s.data = new SoundNStreamDataBlock(samples, encoding); for (int i = 0; i < (samples as Int16[][]).Length; i++) { s.info.channels.Add(new b_stm.ChannelInfo()); } break; case EncodingTypes.DSP_ADPCM: s.data = new SoundNStreamDataBlock(EncoderFactory.Pcm16ToDspAdpcmSTM(samples as Int16[][], s), encoding); s.Update(ByteOrder.BigEndian); //Get DSP-ADPCM info. DspAdpcmInfo[] context = new DspAdpcmInfo[s.data.dspAdpcm.Length]; int cCount = 0; foreach (var channel in s.info.channels) { context[cCount] = channel.dspAdpcmInfo; cCount++; } //Create SEEK block. s.seek = new SoundNStreamSeekBlock(s.data.dspAdpcm, s.info.streamSoundInfo.sampleCount, context); break; } //Tracks. for (int i = 0; i < s.info.channels.Count; i += 2) { s.info.tracks.Add(new b_stm.TrackInfo() { volume = 0x64, pan = 0x40, span = 0x0, surroundMode = 0, globalChannelIndexTable = new Table <byte>() { entries = new List <byte>() { (byte)i } } }); if (i + 1 != s.info.channels.Count) { s.info.tracks[s.info.tracks.Count - 1].globalChannelIndexTable.entries.Add((byte)(i + 1)); } } s.Update(ByteOrder.BigEndian); return(s); }
/// <summary> /// Create a wave from a FISP. /// </summary> /// <param name="f"></param> /// <returns></returns> public static b_stm CreateStream(FISP f, byte vMajor, byte vMinor, byte vRevision) { //New stream. b_stm s = new b_stm(); //Trim the fat from each loop. object channels = new short[f.data.data.Count()][]; for (int i = 0; i < (channels as short[][]).Length; i++) { List <short> l = new List <short>(); for (int j = 0; j < f.stream.loopEnd; j++) { l.Add(f.data.data[i][j]); } (channels as short[][])[i] = l.ToArray(); } //PCM8 conversion. if (f.stream.encoding == EncodingTypes.PCM8) { channels = EncoderFactory.Pcm16ToPcm8(channels as short[][]); } //If looped. if (f.stream.isLoop) { s = StreamFactory.CreateStream(f.stream.sampleRate, f.stream.loopEnd, channels, f.stream.encoding, vMajor, vMinor, vRevision, f.stream.loopStart); } //Not looped. else { s = StreamFactory.CreateStream(f.stream.sampleRate, f.stream.loopEnd, channels, f.stream.encoding, vMajor, vMinor, vRevision); } //Make tracks. s.info.tracks = new List <b_stm.TrackInfo>(); foreach (FISP.TrackInfo i in f.tracks) { b_stm.TrackInfo t = new b_stm.TrackInfo(); t.globalChannelIndexTable = new Table <byte>(); t.globalChannelIndexTable.count = (uint)i.channels.Count(); t.globalChannelIndexTable.entries = i.channels; t.pan = i.pan; t.span = i.span; t.surroundMode = i.surroundMode; t.volume = i.volume; s.info.tracks.Add(t); } //Nullify. if (f.tracks.Count() <= 0) { s.info.tracks = null; } //Make regions. EXPERIMENTAL! Yell at me if this doesn't work. s.region = null; if (f.regions.Count > 0) { s.region = new SoundNStreamRegionBlock(); s.region.regions = new SoundNStreamRegionBlock.RegionInfo[f.regions.Count]; int index = 0; foreach (FISP.RegionInfo i in f.regions) { SoundNStreamRegionBlock.RegionInfo r = new SoundNStreamRegionBlock.RegionInfo(); r.start = i.start; r.end = i.end; r.loopInfo = new SoundNStreamRegionBlock.RegionInfo.DspAdpcmLoopInfo[s.info.channels.Count]; if (f.stream.encoding >= EncodingTypes.DSP_ADPCM) { for (int j = 0; j < s.info.channels.Count; j++) { short h1 = 0; short h2 = 0; if (r.start >= 1) { h1 = f.data.data[j][r.start - 1]; } if (r.start >= 2) { h2 = f.data.data[j][r.start - 2]; } r.loopInfo[j] = new SoundNStreamRegionBlock.RegionInfo.DspAdpcmLoopInfo() { loopPredScale = s.info.channels[j].dspAdpcmInfo.loop_pred_scale, loopYn1 = h1, loopYn2 = h2 }; } } s.region.regions[index] = r; index++; } } //Set info. s.info.streamSoundInfo.originalLoopStart = f.stream.originalLoopStart; s.info.streamSoundInfo.originalLoopEnd = f.stream.originalLoopEnd; s.info.streamSoundInfo.secretInfo = f.stream.secretInfo; return(s); }