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> /// 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> /// 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> /// 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> /// 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); }
/// <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> /// 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(); } }