/// <summary> /// Start PCM. /// </summary> /// <param name="wave">The wave.</param> /// <param name="noteDuration">Note duration.</param> /// <param name="clockSpeed">System clock speed.</param> public void StartPCM(RiffWave wave, int noteDuration, uint clockSpeed) { Type = InstrumentType.PCM; _waveSample = 0; _wave = wave; BaseTimer = (ushort)(clockSpeed / _wave.SampleRate); Start(noteDuration); }
/// <summary> /// Get the waves. /// </summary> /// <returns>The wave files.</returns> public RiffWave[] GetWaves() { RiffWave[] w = new RiffWave[Waves.Count]; for (int i = 0; i < Waves.Count; i++) { w[i] = new RiffWave(); w[i].FromOtherStreamFile(Waves[i]); } return(w); }
static void Main(string[] args) { //Start. Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Argument mode. if (args.Length > 0) { //Switch type. switch (Path.GetExtension(args[0])) { //Sound archive. case ".sdat": Application.Run(new MainWindow(args[0])); break; //Sound sequence. case ".sseq": Application.Run(new SequenceEditor(args[0])); break; //Sound archive. case ".ssar": Application.Run(new SequenceArchiveEditor(args[0])); break; //Sound bank. case ".sbnk": Application.Run(new BankEditor(args[0])); break; //Sound wave archive. case ".swar": Application.Run(new WaveArchiveEditor(args[0])); break; //Stream. case ".strm": RiffWave r = new RiffWave(); NitroFileLoader.Stream s = new NitroFileLoader.Stream(); s.Read(args[0]); r.FromOtherStreamFile(s); r.Write(MainWindow.NitroPath + "/" + "tmpStream" + 0 + ".wav"); Application.Run(new StreamPlayer(null, MainWindow.NitroPath + "/" + "tmpStream" + 0 + ".wav", Path.GetFileNameWithoutExtension(args[0]))); break; } } else { //Start the editor. Application.Run(new MainWindow()); } }
/// <summary> /// Get the associated waves from the wave archives. /// </summary> /// <returns>The waves from the wave archives.</returns> public RiffWave[][] GetAssociatedWaves() { //Get waves. RiffWave[][] waves = new RiffWave[4][]; for (int i = 0; i < 4; i++) { if (WaveArchives[i] != null) { waves[i] = WaveArchives[i].File.GetWaves(); } } return(waves); }
/// <summary> /// Load a stream. /// </summary> /// <param name="s">The sound file.</param> public void LoadStream(SoundFile s) { Riff = new RiffWave(); Riff.FromOtherStreamFile(s); MemoryStream = new MemoryStream(Riff.Write()); WaveFileReader = new WaveFileReader(MemoryStream); SoundOut.Dispose(); SoundOut = new WaveOut(); LoopStream = new LoopStream(this, WaveFileReader, Riff.Loops && Loop, s.LoopStart, (Riff.Loops && Loop) ? s.LoopEnd : (uint)s.Audio.NumSamples); try { SoundOut.Init(LoopStream); } catch (NAudio.MmException e) { SoundOut = new NullWavePlayer(); } }
/// <summary> /// Get the wave data from a file path. /// </summary> /// <returns>Wave data.</returns> public Wave GetWave() { string wavePath = GetWavePath(); if (wavePath == "") { return(null); } //Extension. string ext = Path.GetExtension(wavePath).ToLower(); //RIFF. if (ext.StartsWith(".w")) { RiffWave r = new RiffWave(); r.Load(System.IO.File.ReadAllBytes(wavePath)); return(new Wave() { Wav = WaveFactory.CreateWave(r, true, forceWavMaj, forceWavMin, forceWavRev) }); } //Wave. else if (ext.EndsWith("wav")) { b_wav b = new b_wav(); b.Load(System.IO.File.ReadAllBytes(wavePath)); return(new Wave() { Wav = b }); } //Stream. else if (ext.EndsWith("stm")) { b_stm s = new b_stm(); s.Load(System.IO.File.ReadAllBytes(wavePath)); return(new Wave() { Wav = WaveFactory.CreateWave(s, forceWavMaj, forceWavMin, forceWavRev) }); } //Null. return(null); }
/// <summary> /// Write a wave file. /// </summary> /// <param name="r">The riff wave.</param> public void WriteWave(RiffWave r) { //Make it so the sample block is not written. r.Loops = false; //Write the file and fix chunks. long bak = BaseStream.Position; Write(r.Write()); long bak2 = BaseStream.Position; BaseStream.Position = bak; Write("LIST".ToCharArray()); BaseStream.Position += 4; Write("wave".ToCharArray()); BaseStream.Position = bak2; }
/// <summary> /// Write the text format, and dump files. /// </summary> /// <param name="path">The path.</param> /// <param name="name">The name.</param> public void WriteTextFormat(string path, string name) { //SWLS. List <string> swls = new List <string>(); int ind = 0; Directory.CreateDirectory(path + "/" + name); foreach (var w in File.Waves) { swls.Add(name + "/" + ind.ToString("D4") + ".adpcm.swav"); w.Write(path + "/" + name + "/" + ind.ToString("D4") + ".adpcm.swav"); RiffWave r = new RiffWave(); r.FromOtherStreamFile(w); r.Write(path + "/" + name + "/" + ind.ToString("D4") + ".wav"); ind++; } System.IO.File.WriteAllLines(path + "/" + name + ".swls", swls); }
/// <summary> /// From a RIFF wave. WIP. /// </summary> /// <param name="r"></param> public FISP(RiffWave r) { regions = new List <RegionInfo>(); tracks = new List <TrackInfo>(); data = new DataInfo(); stream = new StreamInfo(); //Data. if (r.fmt.bitsPerSample == 16) { short[][] pcm16 = new short[r.data.channels.Count][]; for (int i = 0; i < r.data.channels.Count; i++) { pcm16[i] = r.data.channels[i].pcm16.ToArray(); } data.data = pcm16.ToList(); } else { byte[][] pcm8 = new byte[r.data.channels.Count][]; for (int i = 0; i < r.data.channels.Count; i++) { pcm8[i] = r.data.channels[i].pcm8.ToArray(); } data.data = EncoderFactory.Pcm8ToPcm16(pcm8).ToList(); } //Stream info. stream.sampleRate = r.fmt.sampleRate; stream.encoding = 2; if (data.data.Count > 0) { stream.loopEnd = (uint)data.data[0].Length; } if (r.smpl != null) { if (r.smpl.loops.Count > 0) { stream.isLoop = true; stream.loopStart = stream.originalLoopStart = r.smpl.loops[0].startSample; stream.loopEnd = stream.originalLoopEnd = r.smpl.loops[0].endSample; } } }
/// <summary> /// Replace the wave. /// </summary> public override void NodeReplace() { //Get the file. OpenFileDialog o = new OpenFileDialog(); o.Filter = "Supported Audio Files|*.wav;*.swav;*.strm"; o.RestoreDirectory = true; o.ShowDialog(); //If valid. if (o.FileName != "") { //Swav file. Wave w = new Wave(); switch (Path.GetExtension(o.FileName)) { case ".wav": RiffWave r = new RiffWave(o.FileName); w.FromOtherStreamFile(r); break; case ".swav": w.Read(o.FileName); break; case ".strm": NitroFileLoader.Stream s = new NitroFileLoader.Stream(); s.Read(o.FileName); w.FromOtherStreamFile(s); break; default: MessageBox.Show("Unsupported file format!"); return; } //Add the wave. WA.Waves[tree.SelectedNode.Index] = w; UpdateNodes(); DoInfoStuff(); } }
/// <summary> /// Export the wave. /// </summary> public override void NodeExport() { //Get the file. SaveFileDialog s = new SaveFileDialog(); s.Filter = "Supported Audio Files|*.wav;*.swav;*.strm|Wave|*.wav|Sound Wave|*.swav|Sound Stream|*.strm"; s.RestoreDirectory = true; s.FileName = "Wave " + tree.SelectedNode.Index + ".swav"; s.ShowDialog(); //If valid. if (s.FileName != "") { //Wave. Wave w = WA.Waves[tree.SelectedNode.Index]; //Switch type. switch (Path.GetExtension(s.FileName)) { case ".wav": RiffWave r = new RiffWave(); r.FromOtherStreamFile(w); r.Write(s.FileName); break; case ".swav": w.Write(s.FileName); break; case ".strm": NitroFileLoader.Stream stm = new NitroFileLoader.Stream(); stm.FromOtherStreamFile(w); stm.Write(s.FileName); break; default: MessageBox.Show("Unsupported file format!"); return; } } }
/// <summary> /// Read the sample item. Set current offset to start of wave table in advance! /// </summary> /// <param name="r">The reader.</param> public void Read(FileReader r) { Name = r.ReadFixedString(20); uint startSample = r.ReadUInt32(); uint endSample = r.ReadUInt32(); long bak = r.Position; r.Position = r.CurrentOffset; r.Position += startSample * 2; Wave = new RiffWave() { Audio = new AudioData() { Channels = new List <List <GotaSoundIO.Sound.Encoding.IAudioEncoding> >() { new List <GotaSoundIO.Sound.Encoding.IAudioEncoding>() { new PCM16() } } } }; Wave.Audio.Channels[0][0].ReadRaw(r, (uint)((endSample * 2 + r.CurrentOffset - r.Position) / 2), (uint)(endSample * 2 + r.CurrentOffset - r.Position)); r.Position = bak; Wave.LoopStart = r.ReadUInt32(); Wave.LoopEnd = r.ReadUInt32(); if (Wave.LoopEnd != 0) { Wave.LoopStart -= startSample; Wave.LoopEnd -= startSample; } Wave.Loops = Wave.LoopEnd > 0; Wave.SampleRate = r.ReadUInt32(); OriginalPitch = r.ReadByte(); PitchCorrection = r.ReadSByte(); Link = r.ReadUInt16(); ushort type = r.ReadUInt16(); LinkType = (SF2LinkTypes)(type & 0b1111); IsRomType = (type & 0b1000000000000000) > 0; }
/// <summary> /// Import files. /// </summary> public override void WarBatchImport() { //File open check. if (!FileTest(null, null, false, true)) { return; } //Safety. string path = GetFolderPath(); if (path == "") { return; } //Sort files. List <string> files = Directory.EnumerateFiles(path).ToList(); for (int i = files.Count - 1; i >= 0; i--) { if (!files[i].Contains("wav")) { files.RemoveAt(i); } } //Read each file. foreach (string d in files) { if (Path.GetExtension(d).ToLower().Contains(".wav")) { byte[] b = System.IO.File.ReadAllBytes(d); if (b.Length > 0) { RiffWave r = new RiffWave(); r.Load(b); (File as SoundWaveArchive).Add(new Wave() { Wav = WaveFactory.CreateWave(r, true, forceWavMaj, forceWavMin, forceWavRev) }); } else { (File as SoundWaveArchive).Add(null); } } else { byte[] b = System.IO.File.ReadAllBytes(d); if (b.Length > 0) { Wave a = new Wave(); a.Wav = new b_wav(); a.Wav.Load(b); (File as SoundWaveArchive).Add(a); } else { (File as SoundWaveArchive).Add(null); } } } //Update. UpdateNodes(); DoInfoStuff(); }
/// <summary> /// Read the file. /// </summary> /// <param name="r2">The file reader.</param> public override void Read(FileReader r2) { //Use a RIFF reader. using (RiffReader r = new RiffReader(r2.BaseStream)) { //Get the number of instruments. r.OpenChunk(r.GetChunk("colh")); uint numInsts = r.ReadUInt32(); //Pointer table is skipped since it's just offsets to wave data relative to the first wave identifier. //Read wave data. Waves = new List <RiffWave>(); foreach (var c in (r.GetChunk("wvpl") as ListChunk).Chunks) { //Open block. r.OpenChunk(c); //Set position for proper RIFF reading. r.BaseStream.Position -= 8; int len = r.ReadInt32() + 8; r.BaseStream.Position -= 8; RiffWave wav = new RiffWave(); wav.Read(r.ReadBytes(len)); Waves.Add(wav); } //Read each instrument. foreach (ListChunk c in (r.GetChunk("lins") as ListChunk).Chunks) { //Open block. r.OpenChunk(c); //New instrument. Instrument inst = new Instrument(); //Read header. r.OpenChunk(c.GetChunk("insh")); r.ReadUInt32(); inst.BankId = r.ReadUInt32(); inst.InstrumentId = r.ReadUInt32(); //Read regions. foreach (ListChunk g in (c.GetChunk("lrgn") as ListChunk).Chunks) { //New region. Region reg = new Region(); //Region header. r.OpenChunk(g.GetChunk("rgnh")); reg.NoteLow = r.ReadUInt16(); reg.NoteHigh = r.ReadUInt16(); reg.VelocityLow = r.ReadUInt16(); reg.VelocityHigh = r.ReadUInt16(); reg.DoublePlayback = r.ReadUInt16() > 0; reg.KeyGroup = (byte)r.ReadUInt16(); reg.Layer = r.ReadUInt16(); //Note information. r.OpenChunk(g.GetChunk("wsmp")); r.ReadUInt32(); reg.RootNote = (byte)r.ReadUInt16(); reg.Tuning = r.ReadInt16(); reg.Gain = r.ReadInt32(); uint flags = r.ReadUInt32(); reg.NoTruncation = (flags & 0b1) > 0; reg.NoCompression = (flags & 0b10) > 0; reg.Loops = r.ReadUInt32() > 0; if (reg.Loops) { r.ReadUInt32(); reg.LoopAndRelease = r.ReadUInt32() > 0; reg.LoopStart = r.ReadUInt32(); reg.LoopLength = r.ReadUInt32(); } //Wave link. r.OpenChunk(g.GetChunk("wlnk")); uint flg = r.ReadUInt16(); reg.PhaseMaster = (flg & 0b1) > 0; reg.MultiChannel = (flg & 0b10) > 0; reg.PhaseGroup = r.ReadUInt16(); reg.ChannelFlags = r.ReadUInt32(); reg.WaveId = r.ReadUInt32(); //Loop. Waves[(int)reg.WaveId].Loops = reg.Loops; if (reg.Loops) { Waves[(int)reg.WaveId].LoopStart = reg.LoopStart; Waves[(int)reg.WaveId].LoopEnd = reg.LoopLength == 0 ? (uint)Waves[(int)reg.WaveId].Audio.NumSamples : reg.LoopStart + reg.LoopLength; } //Articulators. var lar = g.GetChunk("lar2"); if (lar == null) { lar = g.GetChunk("lar1"); } foreach (Chunk art in (g.GetChunk("lar2") as ListChunk).Chunks) { //Read articulator. Articulator a = new Articulator(); r.OpenChunk(art); r.ReadUInt32(); uint numCons = r.ReadUInt32(); for (uint i = 0; i < numCons; i++) { Connection con = new Connection(); con.SourceConnection = (SourceConnection)r.ReadUInt16(); con.ControlConnection = r.ReadUInt16(); con.DestinationConnection = (DestinationConnection)r.ReadUInt16(); con.TransformConnection = (TransformConnection)r.ReadUInt16(); con.Scale = r.ReadInt32(); a.Connections.Add(con); } reg.Articulators.Add(a); } //Add region. inst.Regions.Add(reg); } //Read name. var info = c.GetChunk("INFO"); if (info != null) { var inam = (info as ListChunk).GetChunk("INAM"); if (inam != null) { r.OpenChunk(inam); r.BaseStream.Position -= 4; uint siz = r.ReadUInt32(); inst.Name = new string(r.ReadChars((int)siz).Where(x => x != 0).ToArray()); } } //Add instrument. Instruments.Add(inst); } } }
/// <summary> /// Create a DLS from a sound font. /// </summary> /// <param name="sf2">The SF2 file.</param> public DownloadableSounds(SoundFont sf2) { //Get waves. List <string> waveMd5s = new List <string>(); Dictionary <int, string> newWaveIds = new Dictionary <int, string>(); Dictionary <int, sbyte> tunings = new Dictionary <int, sbyte>(); Dictionary <int, byte> origPitches = new Dictionary <int, byte>(); Dictionary <int, uint> channelFlags = new Dictionary <int, uint>(); Waves = new List <RiffWave>(); foreach (var i in sf2.Instruments) { foreach (var z in i.GetAllZones()) { foreach (var g in z.Generators.Where(x => x.Gen == SF2Generators.SampleID)) { var s = sf2.Samples[g.Amount.UAmount]; RiffWave wav = new RiffWave(); wav.Loops = s.Wave.Loops; wav.LoopStart = s.Wave.LoopStart; wav.LoopEnd = s.Wave.LoopEnd; wav.SampleRate = s.Wave.SampleRate; wav.Audio.Channels = new List <List <GotaSoundIO.Sound.Encoding.IAudioEncoding> >(); switch (s.LinkType) { case SF2LinkTypes.Left: wav.Audio.Channels.Add(s.Wave.Audio.Channels[0]); try { wav.Audio.Channels.Add(sf2.Samples.Where(x => x.Link == s.Link && x.LinkType == SF2LinkTypes.Right).FirstOrDefault().Wave.Audio.Channels[0]); } catch { } if (!channelFlags.ContainsKey(g.Amount.UAmount)) { channelFlags.Add(g.Amount.UAmount, 0b11); } break; case SF2LinkTypes.Right: try { wav.Audio.Channels.Add(sf2.Samples.Where(x => x.Link == s.Link && x.LinkType == SF2LinkTypes.Left).FirstOrDefault().Wave.Audio.Channels[0]); } catch { } wav.Audio.Channels.Add(s.Wave.Audio.Channels[0]); if (!channelFlags.ContainsKey(g.Amount.UAmount)) { channelFlags.Add(g.Amount.UAmount, 0b11); } break; case SF2LinkTypes.Mono: wav.Audio.Channels.Add(s.Wave.Audio.Channels[0]); if (!channelFlags.ContainsKey(g.Amount.UAmount)) { channelFlags.Add(g.Amount.UAmount, 0b1); } break; case SF2LinkTypes.Linked: foreach (var w in sf2.Samples) { if (w.LinkType == SF2LinkTypes.Linked && w.Link == s.Link) { wav.Audio.Channels.Add(w.Wave.Audio.Channels[0]); if (!channelFlags.ContainsKey(g.Amount.UAmount)) { channelFlags.Add(g.Amount.UAmount, 0); } channelFlags[g.Amount.UAmount] <<= 1; channelFlags[g.Amount.UAmount] |= 0b1; } } break; } string md5 = wav.Md5Sum; if (!newWaveIds.ContainsKey(g.Amount.UAmount)) { newWaveIds.Add(g.Amount.UAmount, md5); tunings.Add(g.Amount.UAmount, sf2.Samples[g.Amount.UAmount].PitchCorrection); origPitches.Add(g.Amount.UAmount, sf2.Samples[g.Amount.UAmount].OriginalPitch); } if (!waveMd5s.Contains(md5)) { waveMd5s.Add(md5); Waves.Add(wav); } } } } //Get instruments. Instruments = new List <Instrument>(); int instId = 0; foreach (var inst in sf2.Instruments) { //Instrument. Instrument i = new Instrument(); i.Name = inst.Name; i.Regions = new List <Region>(); i.BankId = 0; foreach (var p in sf2.Presets) { foreach (var z in p.GetAllZones()) { foreach (var g in z.Generators) { if (g.Gen == SF2Generators.Instrument && g.Amount.Amount == instId) { i.BankId = p.Bank; i.InstrumentId = p.PresetNumber; } } } } instId++; //Get regions. foreach (var z in inst.Zones) { var reg = GetInstrumentRegion(z, inst.GlobalZone); if (reg != null) { i.Regions.Add(reg); } } if (i.Regions.Count < 1) { var reg = GetInstrumentRegion(inst.GlobalZone, null); if (reg != null) { i.Regions.Add(reg); } } //Add instrument. Instruments.Add(i); } //Get an instrument region from an SF2 zone. Region GetInstrumentRegion(Zone z, Zone g) { //Null region. if (z == null) { return(null); } //New region. Region r = new Region(); //Get sample. int sampleNumRaw = SF2Value(SF2Generators.SampleID).UAmount; int sampleNum = waveMd5s.IndexOf(newWaveIds[sampleNumRaw]); r.WaveId = (uint)sampleNum; r.Tuning = (short)(tunings[sampleNumRaw] % 12 * 65536); r.RootNote = (byte)(origPitches[sampleNumRaw] + tunings[sampleNumRaw] / 12); r.ChannelFlags = channelFlags[sampleNumRaw]; r.Loops = Waves[sampleNum].Loops; r.LoopStart = Waves[sampleNum].LoopStart; r.LoopLength = Waves[sampleNum].LoopEnd - Waves[sampleNum].LoopStart; Articulator art = new Articulator(); art.Connections = new List <Connection>(); var c = art.Connections; //Get generators. foreach (var gen in z.Generators) { DestinationConnection d = DestinationConnection.Center; switch (gen.Gen) { case SF2Generators.OverridingRootKey: r.RootNote = (byte)(gen.Amount.Amount + tunings[sampleNumRaw] / 12); continue; case SF2Generators.KeyRange: r.NoteLow = gen.Amount.LowByte; r.NoteHigh = gen.Amount.HighByte; continue; case SF2Generators.VelRange: r.VelocityLow = gen.Amount.LowByte; r.VelocityHigh = gen.Amount.HighByte; continue; case SF2Generators.ChorusEffectsSend: d = DestinationConnection.Chorus; break; case SF2Generators.AttackVolEnv: d = DestinationConnection.EG1AttackTime; break; case SF2Generators.DecayVolEnv: d = DestinationConnection.EG1DecayTime; break; case SF2Generators.DelayVolEnv: d = DestinationConnection.EG1DelayTime; break; case SF2Generators.HoldVolEnv: d = DestinationConnection.EG1HoldTime; break; case SF2Generators.ReleaseVolEnv: d = DestinationConnection.EG1ReleaseTime; break; case SF2Generators.SustainVolEnv: d = DestinationConnection.EG1SustainLevel; c.Add(new Connection() { DestinationConnection = d, Scale = (int)((1 - (gen.Amount.Amount / 1000d)) * 1000 * 65536) }); continue; case SF2Generators.Keynum: d = DestinationConnection.KeyNumber; break; case SF2Generators.Pan: d = DestinationConnection.Pan; break; case SF2Generators.FreqModLFO: d = DestinationConnection.LFOFrequency; break; case SF2Generators.DelayModLFO: d = DestinationConnection.LFOStartDelayTime; break; default: continue; } c.Add(new Connection() { DestinationConnection = d, Scale = gen.Amount.Amount * 65536 }); } //Get the SF2 value. SF2GeneratorAmount SF2Value(SF2Generators gen) { var ret = new SF2GeneratorAmount(); if (g != null) { var a = g.Generators.Where(x => x.Gen == gen).FirstOrDefault(); if (a != null) { ret.Amount += a.Amount.Amount; } } var b = z.Generators.Where(x => x.Gen == gen).FirstOrDefault(); if (b != null) { ret.Amount = b.Amount.Amount; } return(ret); } //Add articulators. r.Articulators = new List <Articulator>() { art }; //Return the region. return(r); } }
public void ConvertFile(string filename, string OutputFormat) { FISP file; string outputfilepath; switch (filename.Substring(filename.Length - 4)) { case ".wav": RiffWave w = new RiffWave(); w.Load(File.ReadAllBytes(filename)); file = new FISP(w); outputfilepath = entry_output_file_path.Text; if (checkbutton_output_copy_input_name.Active) { int lastDotLocate = entry_input_file_path.Text.LastIndexOf('.'); if (lastDotLocate > 0) { if (OutputFormat == "BWAV") { outputfilepath = entry_input_file_path.Text.Substring(0, lastDotLocate) + ".bwav"; } if (OutputFormat == "WAV") { outputfilepath = entry_input_file_path.Text.Substring(0, lastDotLocate) + ".wav"; } } else { if (OutputFormat == "BWAV") { outputfilepath = entry_input_file_path.Text + ".bwav"; } if (OutputFormat == "WAV") { outputfilepath = entry_input_file_path.Text + ".wav"; } } } //MsgBox("in?:" + filename +"\nout:"+outputfilepath); file.stream.isLoop = checkbutton_looping.Active; file.stream.loopStart = (uint)spinbutton_loop_start.Value; file.stream.loopEnd = (uint)spinbutton_loop_end.Value; //File.WriteAllBytes(outputfilepath, BinaryWave.FromRiff(w).ToBytes()); if (OutputFormat == "BWAV") { File.WriteAllBytes(outputfilepath, BinaryWave.FromFISP(file).ToBytes()); } if (OutputFormat == "WAV") { File.WriteAllBytes(outputfilepath, RiffWaveFactory.CreateRiffWave(file).ToBytes()); } break; case "bwav": BinaryWave r = new BinaryWave(); r.Load(File.ReadAllBytes(filename)); file = new FISP(r); outputfilepath = entry_output_file_path.Text; if (checkbutton_output_copy_input_name.Active) { int lastDotLocate = entry_input_file_path.Text.LastIndexOf('.'); if (lastDotLocate > 0) { if (OutputFormat == "BWAV") { outputfilepath = entry_input_file_path.Text.Substring(0, lastDotLocate) + ".bwav"; } if (OutputFormat == "WAV") { outputfilepath = entry_input_file_path.Text.Substring(0, lastDotLocate) + ".wav"; } } else { if (OutputFormat == "BWAV") { outputfilepath = entry_input_file_path.Text + ".bwav"; } if (OutputFormat == "WAV") { outputfilepath = entry_input_file_path.Text + ".wav"; } } } //riffWave file.stream.encoding = (byte)1; if (OutputFormat == "BWAV") { File.WriteAllBytes(outputfilepath, file.ToBytes()); } if (OutputFormat == "WAV") { File.WriteAllBytes(outputfilepath, RiffWaveFactory.CreateRiffWave(file).ToBytes()); } break; default: MsgBox("Unknown type - Only WAV and BWAV are supported.\nIf file isn't WAV or BWAV but like Ogg, convert before. (Oddly, some WAVs crash. Exporting with Audacity may work.)\nThis check depends on the file name (mainly the extension), not the actual file contents.\nIf it is WAV or BWAV, please change the file name.\nBut BWAV input support is too bad. In that case, try using VGMStream.", "Error", MessageType.Error, ButtonsType.Ok); return; } //file.stream /*MsgBox("file.stream.isLoop: \"" + (file.stream.isLoop.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.loopStart: \"" + (file.stream.loopStart.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.loopEnd: \"" + (file.stream.loopEnd.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.originalLoopStart: \"" + (file.stream.originalLoopStart.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.originalLoopEnd: \"" + (file.stream.originalLoopEnd.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.encoding: \"" + (file.stream.encoding.ToString() ?? "NULL!!!") + "\"\n" + //+ "file.stream.magic: \"" + (file.stream.magic.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.sampleRate: \"" + (file.stream.sampleRate.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.secretInfo: \"" + (file.stream.secretInfo.ToString() ?? "NULL!!!") + "\"\n");*/ }
/// <summary> /// Create a sample table from some waves and get a wave's new index. /// </summary> /// <param name="waves"></param> /// <param name="newIndices"></param> public void CreateSampleTable(List <RiffWave> waves, out Dictionary <int, int> newIndices) { //New indices. newIndices = new Dictionary <int, int>(); int currInd = 0; ushort link = 1; //Fix loops. foreach (var w in waves) { if (w.LoopEnd != 0) { w.Loops = true; } } //For each wave. Samples = new List <SampleItem>(); for (int i = 0; i < waves.Count; i++) { //Switch the number of channels. switch (waves[i].Audio.Channels.Count()) { //Mono. case 1: Samples.Add(new SampleItem() { LinkType = SF2LinkTypes.Mono, Name = "Sample " + i, Wave = waves[i] }); break; //Stereo. case 2: RiffWave left = new RiffWave(); RiffWave right = new RiffWave(); left.FromOtherStreamFile(waves[i]); right.FromOtherStreamFile(waves[i]); left.Audio.Channels.RemoveAt(1); right.Audio.Channels.RemoveAt(0); Samples.Add(new SampleItem() { LinkType = SF2LinkTypes.Left, Name = "Sample " + i + " L", Link = link, Wave = left }); Samples.Add(new SampleItem() { LinkType = SF2LinkTypes.Right, Name = "Sample " + i + " R", Link = link++, Wave = right }); break; //Link. default: int chanNum = 0; foreach (var w in waves) { RiffWave lnk = new RiffWave(); lnk.FromOtherStreamFile(w); lnk.Audio.Channels = new List <List <GotaSoundIO.Sound.Encoding.IAudioEncoding> >() { lnk.Audio.Channels[chanNum++] }; Samples.Add(new SampleItem() { LinkType = SF2LinkTypes.Left, Name = "Sample " + i + " Link " + chanNum, Link = link, Wave = lnk }); } link++; break; } //Increase index. newIndices.Add(i, currInd); currInd += (ushort)waves[i].Audio.Channels.Count(); } }
private void exportButton_Click(object sender, EventArgs e) { //Test. if (impFileBox.Text.Equals("")) { MessageBox.Show("No Input File Selected!"); return; } if (outFileBox.Text.Equals("")) { MessageBox.Show("No Output File Selected!"); return; } //Sound file. SoundFile s; if (SwavMode) { s = new Wave(); } else { s = new NitroFileLoader.Stream(); } //Switch input file. SoundFile i; switch (Path.GetExtension(impFileBox.Text)) { case ".swav": i = new Wave(); break; case ".strm": i = new NitroFileLoader.Stream(); break; default: i = new RiffWave(); break; } i.Read(impFileBox.Text); //Get conversion type. Type convType; switch (outputFormat.SelectedIndex) { case 0: convType = typeof(PCM8Signed); break; case 1: convType = typeof(PCM16); break; default: convType = typeof(ImaAdpcm); break; } //Convert the file. s.FromOtherStreamFile(i, convType); //Save the file. s.Write(outFileBox.Text); }
/// <summary> /// Write an instrument. /// </summary> /// <param name="bnk">The bank.</param> /// <param name="instrumentId">The instrument Id.</param> /// <param name="a">Sound archive.</param> /// <param name="war0">Wave archive 0.</param> /// <param name="war1">Wave archive 1.</param> /// <param name="war2">Wave archive 2.</param> /// <param name="war3">Wave archive 3.</param> public void WriteInstrument(Bank bnk, int instrumentId, SoundArchive a, ushort war0, ushort war1, ushort war2, ushort war3) { //Set the instrument. var repl = bnk.Instruments.Where(x => x.Index == instrumentId).FirstOrDefault(); Inst.Index = instrumentId; //Sound archive check. if (a == null) { return; } //Get wave archives. WaveArchiveInfo[] wars = new WaveArchiveInfo[4]; if (war0 != 0xFFFF) { wars[0] = a.WaveArchives.Where(x => x.Index == (int)war0).FirstOrDefault(); } if (war1 != 0xFFFF) { wars[1] = a.WaveArchives.Where(x => x.Index == (int)war1).FirstOrDefault(); } if (war2 != 0xFFFF) { wars[2] = a.WaveArchives.Where(x => x.Index == (int)war2).FirstOrDefault(); } if (war3 != 0xFFFF) { wars[3] = a.WaveArchives.Where(x => x.Index == (int)war3).FirstOrDefault(); } //Make sure there are linked wave archives. if (wars.Where(x => x != null).Count() < 1) { return; } //For each region in the instrument. foreach (var r in Inst.NoteInfo) { //PCM type. if (r.InstrumentType != InstrumentType.PCM) { continue; } //Waves are not null. if (Waves == null) { continue; } //Get entry. var e = Waves.Where(x => x.WarId == r.WarId && x.WaveId == r.WaveId).FirstOrDefault(); if (e == null) { continue; } //Wave is not null. if (e.Wave == null) { continue; } //Get MD5SUM of wave. string md5 = e.Wave.Md5Sum; //Try and find matching wave. bool found = false; for (int i = 0; i < wars.Length; i++) { if (wars[i] != null) { for (int j = 0; j < wars[i].File.Waves.Count; j++) { if (!found && wars[i].File.Waves[j].Md5Sum == md5) { r.WaveId = (ushort)j; r.WarId = (ushort)i; found = true; } } } } //Not found. if (!found) { RiffWave riff = new RiffWave(); riff.FromOtherStreamFile(e.Wave); WaveMapper mapper = new WaveMapper(new List <RiffWave>() { riff }, wars.Where(x => x != null).ToList(), true); mapper.MinimizeBox = false; mapper.ShowDialog(); if (mapper.WarMap == null) { return; } a.WaveArchives.Where(x => x.Index == mapper.WarMap[0]).FirstOrDefault().File.Waves.Add(e.Wave); r.WaveId = (ushort)(a.WaveArchives.Where(x => x.Index == mapper.WarMap[0]).FirstOrDefault().File.Waves.Count() - 1); r.WarId = (ushort)wars.ToList().IndexOf(a.WaveArchives.Where(x => x.Index == mapper.WarMap[0]).FirstOrDefault()); } } //Set instrument. bnk.Instruments[bnk.Instruments.IndexOf(repl)] = Inst; }
/// <summary> /// Convert the bank to downloadable sounds. /// </summary> /// <param name="a">The sound archive.</param> /// <param name="b">The bank info.</param> /// <returns>The bank as DLS.</returns> public DownloadableSounds ToDLS(SoundArchive a, BankInfo b) { //New DLS. DownloadableSounds d = new DownloadableSounds(); //Wave map. Dictionary <uint, RiffWave> waveMap = new Dictionary <uint, RiffWave>(); Dictionary <ushort, RiffWave> psgMap = new Dictionary <ushort, RiffWave>(); Dictionary <ushort, RiffWave> noiseMap = new Dictionary <ushort, RiffWave>(); d.Waves.Add(new RiffWave("Hardware/Null.wav")); //Add each instrument. foreach (var inst in Instruments) { //New instrument. GotaSoundBank.DLS.Instrument im = new GotaSoundBank.DLS.Instrument(); im.BankId = (uint)(inst.Index / 128); im.InstrumentId = (uint)(inst.Index % 128); im.Name = "Instrument " + im.InstrumentId; //Add regions. byte lastNote = inst as DrumSetInstrument != null ? (inst as DrumSetInstrument).Min : (byte)0; foreach (var n in inst.NoteInfo) { //New region. Region r = new Region(); //Set note info. r.VelocityLow = 0; r.VelocityHigh = 127; r.NoteLow = lastNote; r.NoteHigh = (inst as DirectInstrument != null) ? (byte)127 : (byte)n.Key; lastNote = (byte)(n.Key + 1); r.ChannelFlags = 1; r.DoublePlayback = true; r.Layer = 1; r.NoTruncation = true; r.RootNote = (byte)n.BaseNote; //Wave data. int wavInd = 0; switch (n.InstrumentType) { case InstrumentType.PCM: uint key = 0xFFFFFFFF; try { var p = b.WaveArchives[n.WarId].File.Waves[n.WaveId]; key = (uint)(b.WaveArchives[n.WarId].Index << 16) | n.WaveId; } catch { } if (key != 0xFFFFFFFF) { if (!waveMap.ContainsKey(key)) { RiffWave pcm = new RiffWave(); pcm.FromOtherStreamFile(b.WaveArchives[n.WarId].File.Waves[n.WaveId]); waveMap.Add(key, pcm); d.Waves.Add(pcm); } wavInd = d.Waves.IndexOf(waveMap[key]); } break; case InstrumentType.PSG: if (!psgMap.ContainsKey(n.WaveId)) { RiffWave psg = new RiffWave("Hardware/DutyCycle" + (n.WaveId + 1) + ".wav"); psgMap.Add(n.WaveId, psg); d.Waves.Add(psg); } wavInd = d.Waves.IndexOf(psgMap[n.WaveId]); break; case InstrumentType.Noise: if (!noiseMap.ContainsKey(0)) { RiffWave noise = new RiffWave("Hardware/WhiteNoise.wav"); noiseMap.Add(0, noise); d.Waves.Add(noise); wavInd = d.Waves.IndexOf(noise); } else { wavInd = d.Waves.IndexOf(noiseMap[0]); } break; } //Set wave data. r.WaveId = (uint)wavInd; r.Loops = d.Waves[wavInd].Loops; if (r.Loops) { r.LoopStart = d.Waves[wavInd].LoopStart; r.LoopLength = d.Waves[wavInd].LoopEnd - d.Waves[wavInd].LoopStart; if (r.LoopLength < 0) { r.LoopLength = 0; } } //Articulator. Articulator ar = new Articulator(); ar.Connections.Add(new Connection() { DestinationConnection = DestinationConnection.EG1AttackTime, Scale = n.Attack >= 127 ? int.MinValue : MillisecondsToTimecents(AttackTable[n.Attack]) * 65536 }); ar.Connections.Add(new Connection() { DestinationConnection = DestinationConnection.EG1DecayTime, Scale = n.Decay >= 127 ? int.MinValue : MillisecondsToTimecents(MaxReleaseTimes[n.Decay]) * 65536 }); ar.Connections.Add(new Connection() { DestinationConnection = DestinationConnection.EG1SustainLevel, Scale = (int)Math.Round(Sustain2Fraction(n.Sustain) * 1000, MidpointRounding.AwayFromZero) * 65536 }); ar.Connections.Add(new Connection() { DestinationConnection = DestinationConnection.EG1ReleaseTime, Scale = n.Release >= 127 ? int.MinValue : MillisecondsToTimecents(MaxReleaseTimes[n.Release]) * 65536 }); ar.Connections.Add(new Connection() { DestinationConnection = DestinationConnection.Pan, Scale = GetPan(n.Pan) * 65536 }); r.Articulators.Add(ar); //Add region. im.Regions.Add(r); } //Add the instrument. d.Instruments.Add(im); } //Return the DLS. return(d); }
protected void OnButtonLoadClicked(object sender, EventArgs e) { var filepath = entry_input_file_path.Text; System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(filepath); try { stringBuilder.Replace("~", Environment.GetEnvironmentVariable("HOME"), 0, 1); } catch (Exception ex) { } filepath = stringBuilder.ToString(); if (!IsReadable(filepath, true)) { return; } entry_loaded_file_path.Text = filepath; FISP file; switch (filepath.Substring(filepath.Length - 4)) { case ".wav": entry_loaded_file_format.Text = "WAV"; RiffWave w = new RiffWave(); w.Load(File.ReadAllBytes(filepath)); file = new FISP(w); break; case "bwav": entry_loaded_file_format.Text = "BWAV"; BinaryWave r = new BinaryWave(); if (r.Codic == 0) { entry_loaded_file_format.Text = "BWAV(PCM16)"; } if (r.Codic == 1) { entry_loaded_file_format.Text = "BWAV(DSPADPCM)"; } //RiffWave riffWave = new RiffWave(); r.Load(File.ReadAllBytes(filepath)); file = new FISP(r); break; default: entry_loaded_file_format.Text = "Unknown"; MsgBox("Unknown type - Only WAV and BWAV are supported.\nIf file isn't WAV or BWAV but like Ogg, convert before. (Oddly, some WAVs crash. Exporting with Audacity may work.)\nThis check depends on the file name (mainly the extension), not the actual file contents.\nIf it is WAV or BWAV, please change the file name.\nBut BWAV input support is too bad. In that case, try using VGMStream.", "Error", MessageType.Error, ButtonsType.Ok); return; } checkbutton_looping.Sensitive = spinbutton_loop_start.Sensitive = spinbutton_loop_end.Sensitive = hbox_convert_buttons.Sensitive = true; checkbutton_looping.Inconsistent = false; spinbutton_loop_start.Adjustment.Upper = spinbutton_loop_end.Adjustment.Upper = double.MaxValue; checkbutton_looping.Active = file.stream.isLoop; spinbutton_loop_start.Value = file.stream.loopStart; spinbutton_loop_end.Value = file.stream.loopEnd; //MsgBox(spinbutton_loop_start.Adjustment.Upper.ToString()+"\n" +spinbutton_loop_end.Adjustment.Upper.ToString()); MsgBox("file.stream.isLoop: \"" + (file.stream.isLoop.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.loopStart: \"" + (file.stream.loopStart.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.loopEnd: \"" + (file.stream.loopEnd.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.originalLoopStart: \"" + (file.stream.originalLoopStart.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.originalLoopEnd: \"" + (file.stream.originalLoopEnd.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.encoding: \"" + (file.stream.encoding.ToString() ?? "NULL!!!") + "\"\n" //+ "file.stream.magic: \"" + (file.stream.magic.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.sampleRate: \"" + (file.stream.sampleRate.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.secretInfo: \"" + (file.stream.secretInfo.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.vMajor: \"" + (file.stream.vMajor.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.vMinor: \"" + (file.stream.vMinor.ToString() ?? "NULL!!!") + "\"\n" + "file.stream.vRevision: \"" + (file.stream.vRevision.ToString() ?? "NULL!!!") + "\""); }