public void SwitchBank(int index) { if (index < BankManager.Count) { this.bank = BankManager.getBank(index); } }
private SfzRegion[] regions; //the complete list of regions #endregion Fields #region Constructors //--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; ReadFromStream(PlatformHelper.StreamLoad(Instrumentfile), Path.GetDirectoryName(Instrumentfile) + "/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
//--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; ReadFromStream(PlatformHelper.StreamLoad(Instrumentfile), Path.GetDirectoryName(Instrumentfile) + "/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
private void banksList_SelectedIndexChanged(object sender, EventArgs e) { try { progList.Items.Clear(); var progidx = 0; var IBNK = Root.g_AAF.IBNK; if (banksList.SelectedIndex > IBNK.Length || banksList.SelectedIndex > bankMap.Length) { return; } var thisBank = bankMap[banksList.SelectedIndex]; var CurrentIBNK = IBNK[thisBank]; currentIBNK = CurrentIBNK; Dictionary <int, string> mapOut = null; if (INAMap != null) { INAMap.TryGetValue(thisBank, out mapOut); } for (int i = 0; i < CurrentIBNK.Instruments.Length; i++) { if (CurrentIBNK.Instruments[i] != null) { string repName = null; if (mapOut != null) { mapOut.TryGetValue(i, out repName); } if (repName != null) { progList.Items.Add((i) + " " + repName); } else if (CurrentIBNK.Instruments[i].IsPercussion) { progList.Items.Add("(PRC)Program " + (i)); } else { progList.Items.Add("Program " + (i)); } progMap[progidx] = i; progidx++; } } Root.currentBank = currentIBNK; } catch { } // F**k this too. }
private SfzRegion[] regions; //the complete list of regions #endregion Fields #region Constructors //--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; String fileName = Instrumentfile.Substring(Instrumentfile.LastIndexOf("/"), Instrumentfile.Length - Instrumentfile.LastIndexOf("/") ); ReadFromStream(Application.GetResourceStream(new Uri(Instrumentfile, UriKind.Relative)).Stream, Instrumentfile.Replace(fileName, "")+"/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
//--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; String fileName = Instrumentfile.Substring(Instrumentfile.LastIndexOf("/"), Instrumentfile.Length - Instrumentfile.LastIndexOf("/")); ReadFromStream(Application.GetResourceStream(new Uri(Instrumentfile, UriKind.Relative)).Stream, Instrumentfile.Replace(fileName, "") + "/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
public void SwitchBank(int index) { if (index < BankManager.Count) {//banks are reloaded if at different sample rate this.bank = BankManager.getBank(index); if (this.bank.SampleRate != this.sampleRate) { bank.reload(this.sampleRate); } } }
public bool UnloadBank(int index) { if (index < BankManager.Count) { if (BankManager.Banks[index] == bank) { bank = null; } BankManager.removeBank(index); return(true); } return(false); }
//--Private Methods private void ReadFromStream(Stream InstrumentStream, string path, InstrumentBank bank) { StreamReader reader = new StreamReader(InstrumentStream); List <string> text = new List <string>(); while (reader.Peek() > -1) { text.Add(reader.ReadLine()); } reader.Dispose(); InstrumentStream.Dispose(); ParseInstrumentData(text.ToArray(), path, bank); }
//--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; //UnitySynth //ReadFromStream(File.Open(Instrumentfile, FileMode.Open), Path.GetDirectoryName(Instrumentfile) + "\\", bank); TextAsset instrumentFile = Resources.Load(Instrumentfile) as TextAsset; Stream instrumentStream = new MemoryStream(instrumentFile.bytes); this.ReadFromStream(instrumentStream, Path.GetDirectoryName(Instrumentfile) + "/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
private SfzRegion[] regions; //the complete list of regions #endregion Fields #region Constructors //--Public Methods public SfzInstrument(string Instrumentfile, int sampleRate, InstrumentBank bank) : base() { this.SampleRate = sampleRate; //UnitySynth //ReadFromStream(File.Open(Instrumentfile, FileMode.Open), Path.GetDirectoryName(Instrumentfile) + "\\", bank); TextAsset instrumentFile = Resources.Load(Instrumentfile) as TextAsset; Stream instrumentStream = new MemoryStream(instrumentFile.bytes); Debug.Log(Instrumentfile); this.ReadFromStream(instrumentStream, Path.GetDirectoryName(Instrumentfile) + "/", bank); CreateKeyMap(); base.Name = System.IO.Path.GetFileNameWithoutExtension(Instrumentfile); }
internal override void Load(DataSegment segment) { index = segment.ReadInt32(Offset, Size); bank = (InstrumentBank)segment.ReadInt32(SchemaField.BankOffset, 1); }
public void LoadAAFile(string filename, JAIVersion version) { WSYS = new WaveSystem[0xFF]; // None over 256 please :). IBNK = new InstrumentBank[0xFF]; // These either. var aafdata = File.ReadAllBytes(filename); // We're just going to load a whole copy into memory because we're lame -- having this buffer in memory makes it easy to pass as a ref to stream readers later. var aafRead = new BeBinaryReader(new MemoryStream(aafdata)); bool done = false; while (!done) { var ChunkID = aafRead.ReadUInt32(); long anchor; var name = convertChunkName(ChunkID); Console.WriteLine("[AAF] Found chunk: {0}", name); switch (ChunkID) { case 0: done = true; // either we're misalligned or done, so just stopo here. break; case 1: // Don't know case 5: case 4: case 6: case 7: aafRead.ReadUInt32(); aafRead.ReadUInt32(); aafRead.ReadUInt32(); break; case 2: // INST case 3: // WSYS { while (true) { var offset = aafRead.ReadUInt32(); if (offset == 0) { break; // 0 means we reached the end. } var size = aafRead.ReadUInt32(); var type = aafRead.ReadUInt32(); anchor = aafRead.BaseStream.Position; // Store our return position. aafRead.BaseStream.Position = offset; // Seek to the offset pos. if (ChunkID == 3) { var b = new WaveSystem(); // Load the wavesystem b.LoadWSYS(aafRead); WSYS[b.id] = b; // store it Console.WriteLine("\t WSYS at 0x{0:X}", offset); } else if (ChunkID == 2) { var x = new InstrumentBank(); x.LoadInstrumentBank(aafRead, version); Console.WriteLine("\t IBNK at 0x{0:X}", offset); IBNK[x.id] = x; // Store it } aafRead.BaseStream.Position = anchor; // Return back to our original pos after loading. } break; } } } }
private void ParseInstrumentData(string[] text, string InstrumentPath, InstrumentBank bank) { allSamplesHaveDualChannels = true; SfzRegion Group = new SfzRegion(); bool[] groupValues = new bool[21]; List<Sample> Samples = new List<Sample>(); List<string> SampleNames = new List<string>(); List<SfzRegion> Regions = new List<SfzRegion>(); for (int x = 0; x < text.Length; x++) { string line = text[x].Trim(); if (line != "") { switch (line.Substring(0, 1).ToLower()) { case "<": if (line == "<group>") { while (text[x] != "") { x++; if (x >= text.Length) break; string[] Rvalue = text[x].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); if (Rvalue.Length == 2) { switch (Rvalue[0]) { case "sample": Rvalue[1] = System.IO.Path.GetFileNameWithoutExtension(Rvalue[1]); groupValues[0] = true; if (SampleNames.Contains(Rvalue[1]))//its in the local list so no need to check the master list { Group.SampleIndex = SampleNames.IndexOf(Rvalue[1]); } else { SampleNames.Add(Rvalue[1]); //check if the sample is in the master list. int sampNum = bank.SampleNameList.IndexOf(Rvalue[1]); Sample s; if (sampNum > -1)//its in the list { s = bank.SampleList[sampNum]; } else//its not in the list { s = new Sample(InstrumentPath + "SAMPLES/" + Rvalue[1] + ".wav"); bank.SampleList.Add(s); bank.SampleNameList.Add(Rvalue[1]); } if (s.isDualChannel == false) allSamplesHaveDualChannels = false; Samples.Add(s); Group.SampleIndex = SampleNames.Count - 1; } break; case "hikey": Group.HiNote = (byte)int.Parse(Rvalue[1]); groupValues[1] = true; break; case "lokey": Group.LoNote = (byte)int.Parse(Rvalue[1]); groupValues[2] = true; break; case "loop_start": Group.LoopStart = int.Parse(Rvalue[1]); groupValues[3] = true; break; case "loop_end": Group.LoopEnd = int.Parse(Rvalue[1]); groupValues[4] = true; break; case "tune": Group.Tune = int.Parse(Rvalue[1]) / 100.0f; groupValues[5] = true; break; case "pitch_keycenter": Group.Root = int.Parse(Rvalue[1]); groupValues[6] = true; break; case "volume": Group.Volume = float.Parse(Rvalue[1]); groupValues[7] = true; break; case "loop_mode": groupValues[8] = true; switch (Rvalue[1]) { case "loop_continuous": Group.LoopMode = 1; break; case "loop_sustain": Group.LoopMode = 2; break; default: Group.LoopMode = 0; break; } break; case "ampeg_release": groupValues[9] = true; Group.Release = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_attack": groupValues[10] = true; Group.Attack = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_decay": groupValues[11] = true; Group.Decay = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_hold": groupValues[12] = true; Group.Hold = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "lovel": groupValues[13] = true; Group.LoVelocity = (byte)int.Parse(Rvalue[1]); break; case "hivel": groupValues[14] = true; Group.HiVelocity = (byte)int.Parse(Rvalue[1]); break; case "lochan": groupValues[15] = true; Group.LoChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "hichan": groupValues[16] = true; Group.HiChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "key": Group.Root = int.Parse(Rvalue[1]); groupValues[6] = true; Group.HiNote = (byte)Group.Root; groupValues[1] = true; Group.LoNote = (byte)Group.Root; groupValues[2] = true; break; case "offset": groupValues[17] = true; Group.Offset = int.Parse(Rvalue[1]); break; case "pan": groupValues[18] = true; Group.Pan = float.Parse(Rvalue[1]); break; case "effect1": groupValues[19] = true; Group.Effect1 = float.Parse(Rvalue[1]); break; case "effect2": groupValues[20] = true; Group.Effect2 = float.Parse(Rvalue[1]); break; default: break; } } } } else if (line == "<region>") { SfzRegion r = new SfzRegion(); while (text[x] != "") { x++; if (x >= text.Length) break; string[] Rvalue = text[x].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); if (Rvalue.Length == 2) { switch (Rvalue[0]) { case "sample": Rvalue[1] = System.IO.Path.GetFileNameWithoutExtension(Rvalue[1]);//remove ending .wav if (SampleNames.Contains(Rvalue[1]))//its in the local list so no need to check the master list { r.SampleIndex = SampleNames.IndexOf(Rvalue[1]); } else { SampleNames.Add(Rvalue[1]); //check if the sample is in the master list. int sampNum = bank.SampleNameList.IndexOf(Rvalue[1]); Sample s; if (sampNum > -1)//its in the list { s = bank.SampleList[sampNum]; } else//its not in the list { s = new Sample(InstrumentPath + "SAMPLES/" + Rvalue[1] + ".wav"); bank.SampleList.Add(s); bank.SampleNameList.Add(Rvalue[1]); } if (s.isDualChannel == false) allSamplesHaveDualChannels = false; Samples.Add(s); r.SampleIndex = SampleNames.Count - 1; } break; case "hikey": r.HiNote = (byte)int.Parse(Rvalue[1]); break; case "lokey": r.LoNote = (byte)int.Parse(Rvalue[1]); break; case "loop_start": r.LoopStart = int.Parse(Rvalue[1]); break; case "loop_end": r.LoopEnd = int.Parse(Rvalue[1]); break; case "tune": r.Tune = int.Parse(Rvalue[1]) / 100.0f; break; case "pitch_keycenter": r.Root = int.Parse(Rvalue[1]); break; case "volume": r.Volume = float.Parse(Rvalue[1]); break; case "loop_mode": switch (Rvalue[1]) { case "loop_continuous": r.LoopMode = 1; break; case "loop_sustain": r.LoopMode = 2; break; default: r.LoopMode = 0; break; } break; case "ampeg_release": r.Release = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_attack": r.Attack = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_decay": r.Decay = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_hold": r.Hold = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "lovel": r.LoVelocity = (byte)int.Parse(Rvalue[1]); break; case "hivel": r.HiVelocity = (byte)int.Parse(Rvalue[1]); break; case "lochan": r.LoChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "hichan": r.HiChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "key": r.Root = int.Parse(Rvalue[1]); r.HiNote = (byte)r.Root; r.LoNote = (byte)r.Root; break; case "offset": r.Offset = int.Parse(Rvalue[1]); break; case "pan": r.Pan = float.Parse(Rvalue[1]); break; case "effect1": r.Effect1 = float.Parse(Rvalue[1]); break; case "effect2": r.Effect2 = float.Parse(Rvalue[1]); break; default: break; } } } if (Regions.Contains(r) == false) Regions.Add(r); } break; default: break; } } } //Apply group values here for (int x = 0; x < Regions.Count; x++) { if (groupValues[0] == true) Regions[x].SampleIndex = Group.SampleIndex; if (groupValues[1] == true) Regions[x].HiNote = Group.HiNote; if (groupValues[2] == true) Regions[x].LoNote = Group.LoNote; if (groupValues[3] == true) Regions[x].LoopStart = Group.LoopStart; if (groupValues[4] == true) Regions[x].LoopEnd = Group.LoopEnd; if (groupValues[5] == true) Regions[x].Tune = Group.Tune; if (groupValues[6] == true) Regions[x].Root = Group.Root; if (groupValues[7] == true) Regions[x].Volume = Group.Volume; if (groupValues[8] == true) Regions[x].LoopMode = Group.LoopMode; if (groupValues[9] == true) Regions[x].Release = Group.Release; if (groupValues[10] == true) Regions[x].Attack = Group.Attack; if (groupValues[11] == true) Regions[x].Decay = Group.Decay; if (groupValues[12] == true) Regions[x].Hold = Group.Hold; if (groupValues[13] == true) Regions[x].LoVelocity = Group.LoVelocity; if (groupValues[14] == true) Regions[x].HiVelocity = Group.HiVelocity; if (groupValues[15] == true) Regions[x].LoChannel = Group.LoChannel; if (groupValues[16] == true) Regions[x].HiChannel = Group.HiChannel; if (groupValues[17] == true) Regions[x].Offset = Group.Offset; if (groupValues[18] == true) Regions[x].Pan = Group.Pan; if (groupValues[19] == true) Regions[x].Effect1 = Group.Effect1; if (groupValues[20] == true) Regions[x].Effect2 = Group.Effect2; } base.SampleList = Samples.ToArray(); regions = Regions.ToArray(); //Fix parameters so enforce isn't needed for (int x = 0; x < regions.Length; x++) { Sample s = base.SampleList[regions[x].SampleIndex]; float factor = (this.SampleRate / (float)s.OriginalSampleRate); regions[x].LoopEnd = (int)(regions[x].LoopEnd * factor); regions[x].LoopStart = (int)(regions[x].LoopStart * factor); regions[x].Offset = (int)(regions[x].Offset * factor); //Set loopend to end of sample if none is provided if (regions[x].LoopEnd <= 0) { if (this.SampleRate != s.SampleRate) regions[x].LoopEnd = (int)(base.SampleList[regions[x].SampleIndex].SamplesPerChannel * factor) - 1; else regions[x].LoopEnd = (int)(base.SampleList[regions[x].SampleIndex].SamplesPerChannel) - 1; } } //Resample as well for (int x = 0; x < base.SampleList.Length; x++) { Sample s = base.SampleList[x]; float factor = this.SampleRate / (float)s.SampleRate; if (factor != 1.0f) { s.setAllSampleData(WaveHelper.ReSample(this.SampleRate, s.SampleRate, s.getAllSampleData())); s.SampleRate = this.SampleRate; } } }
static void Main(string[] args) { string arkpath = args[0]; string songname = args[1]; FileStream arkfile = new FileStream(arkpath, FileMode.Open, FileAccess.Read); Ark ark = new Ark(new EndianReader(arkfile, Endianness.LittleEndian)); DirectoryNode songdir = ark.Root.Find("songs") as DirectoryNode; songdir = songdir.Find(songname) as DirectoryNode; Midi midi = Midi.Create(Mid.Create((songdir.Find(songname + "_g.mid") as FileNode).Data)); Dictionary <InstrumentBank, Stream> banks = new Dictionary <InstrumentBank, Stream>(); foreach (FileNode node in songdir.Files) { if (node.Name.EndsWith(".bnk")) { InstrumentBank bank = InstrumentBank.Create(new EndianReader(node.Data, Endianness.LittleEndian)); FileNode nse = songdir.Find(Path.GetFileNameWithoutExtension(node.Name) + ".nse") as FileNode; banks.Add(bank, nse.Data); } } int tracknum = 0; FileStream outfile = new FileStream(@"Z:\" + songname + "_" + midi.Tracks.Count.ToString() + ".raw", FileMode.Create, FileAccess.ReadWrite); //EndianReader writer = new EndianReader(outfile, Endianness.BigEndian); EndianReader writer = new EndianReader(new TemporaryStream(), Endianness.BigEndian); foreach (Midi.Track track in midi.Tracks) { List <Midi.Event> events = new List <Midi.Event>(); events.AddRange(track.Banks.Cast <Midi.Event>()); events.AddRange(track.Instruments.Cast <Midi.Event>()); events.AddRange(track.Notes.Cast <Midi.Event>()); InstrumentBank[] bankids = new InstrumentBank[0x10]; InstrumentBank.Bank[] subbankids = new InstrumentBank.Bank[0x10]; InstrumentBank.Instrument[] instrumentids = new InstrumentBank.Instrument[0x10]; InstrumentBank.Sound[][] soundids = new InstrumentBank.Sound[0x10][]; events.Sort(new SpecialEventComparer()); foreach (Midi.ChannelEvent e in events.Cast <Midi.ChannelEvent>()) { Midi.BankEvent banke = e as Midi.BankEvent; Midi.InstrumentEvent instrumente = e as Midi.InstrumentEvent; Midi.NoteEvent notee = e as Midi.NoteEvent; if (banke != null) { bankids[banke.Channel] = banks.Select(b => b.Key).SingleOrDefault(b => b.Banks.SingleOrDefault(b2 => b2.ID == banke.Bank) != null); subbankids[banke.Channel] = bankids[banke.Channel].Banks.SingleOrDefault(b => b.ID == banke.Bank); } else if (instrumente != null) { instrumentids[instrumente.Channel] = bankids[instrumente.Channel].Instruments.SingleOrDefault(i => i.ID == instrumente.Instrument); int soundoffset = 0; foreach (var instrument in bankids[instrumente.Channel].Instruments) { if (instrument == instrumentids[instrumente.Channel]) { break; } soundoffset += instrument.Sounds; } soundids[instrumente.Channel] = bankids[instrumente.Channel].Sounds.Skip(soundoffset).Take(instrumentids[instrumente.Channel].Sounds).ToArray(); } else { var bank = bankids[notee.Channel]; if (bank == null) { continue; } var instrument = instrumentids[notee.Channel]; if (instrument == null) { continue; // Chart note, not audio-playable } var sound = soundids[notee.Channel].FirstOrDefault(s => s.ID0 == notee.Note); // Should be SingleOrDefault, but some duplicates use Sound.Unknown if (sound == null) { continue; } ulong notetime = midi.GetTime(notee.Time); long sample = (long)(notetime / 1000 * (uint)bank.Samples[sound.Sample].SampleRate / 1000); long duration = (long)((midi.GetTime(notee.Time + notee.Duration) - notetime) / 1000 * (uint)bank.Samples[sound.Sample].SampleRate / 1000); short[] samples = bank.Decode(banks[bank], bank.Samples[sound.Sample]); int volume = sound.Volume * notee.Velocity * instrument.Volume * subbankids[notee.Channel].Volume / 0x7F / 0x7F / 0x7F; //int balance = ((int)sound.Balance - 0x40) * ((int)instrument.Balance - 0x40) / 0x40; int balance = (int)sound.Balance - 0x40; int lvolume = balance <= 0x00 ? 0x7F : 0x7F - balance * 2; int rvolume = balance >= 0x00 ? 0x7F : 0x7F + balance * 2; lvolume = lvolume * volume / 0x7F; rvolume = rvolume * volume / 0x7F; writer.Position = (sample * 2) * midi.Tracks.Count * 2 + tracknum * 2 * 2; //writer.Position = (sample * 2) * midi.Tracks.Count + tracknum * 2; duration = Math.Min(duration, samples.Length); for (int i = 0; i < duration; i++) { //writer.Write(samples[i]); if (lvolume > 1) { writer.Write((short)((int)samples[i] * lvolume / 0x7F)); } else { writer.Position += 2; } if (rvolume > 1) { writer.Write((short)((int)samples[i] * rvolume / 0x7F)); } else { writer.Position += 2; } writer.Position += 2 * (midi.Tracks.Count - 1) * 2; //writer.Position += 2 * (midi.Tracks.Count - 1); } } } tracknum++; Console.WriteLine("Track: " + tracknum.ToString()); } writer.Position = 0; Util.StreamCopy(outfile, writer.Base); outfile.Close(); writer.Base.Close(); arkfile.Close(); }
public void LoadBAAFile(string filename, JAIVersion version) { WSYS = new WaveSystem[0xFF]; // None over 256 please :). IBNK = new InstrumentBank[0xFF]; // These either. var aafdata = File.ReadAllBytes(filename); // We're just going to load a whole copy into memory because we're lame -- having this buffer in memory makes it easy to pass as a ref to stream readers later. var aafRead = new BeBinaryReader(new MemoryStream(aafdata)); bool done = false; while (!done) { var ChunkID = aafRead.ReadUInt32(); long anchor; var name = convertChunkName(ChunkID); Console.WriteLine("[BAA] Found chunk: {0}", name); switch (ChunkID) { case 1046430017: // >_AA done = true; // either we're misalligned or done, so just stopo here. break; case 1094803260: // AA_< break; case 1651733536: // BST { var offset_sta = aafRead.ReadUInt32(); var offset_end = aafRead.ReadUInt32(); break; } case 1651733614: // BSTN { var offset_sta = aafRead.ReadUInt32(); var offset_end = aafRead.ReadUInt32(); break; } case 1651729184: // BSC { var offset_sta = aafRead.ReadUInt32(); var offset_end = aafRead.ReadUInt32(); break; } case 1651403552: // BNK { var id = aafRead.ReadUInt32(); var offset = aafRead.ReadUInt32(); anchor = aafRead.BaseStream.Position; // Store our return position. aafRead.BaseStream.Position = offset; // Seek to the offset pos. var b = new InstrumentBank(); b.LoadInstrumentBank(aafRead, version); // Load it up IBNK[id] = b; aafRead.BaseStream.Position = anchor; // Return back to our original pos after loading. break; } case 2004033568: // WSYS { var id = aafRead.ReadUInt32(); var offset = aafRead.ReadUInt32(); var flags = aafRead.ReadUInt32(); anchor = aafRead.BaseStream.Position; // Store our return position. aafRead.BaseStream.Position = offset; // Seek to the offset pos. var b = new WaveSystem(); b.LoadWSYS(aafRead); WSYS[id] = b; aafRead.BaseStream.Position = anchor; // Return back to our original pos after loading. break; } } } }
private void ParseInstrumentData(string[] text, string InstrumentPath, InstrumentBank bank) { allSamplesHaveDualChannels = true; SfzRegion Group = new SfzRegion(); bool[] groupValues = new bool[21]; List <Sample> Samples = new List <Sample>(); List <string> SampleNames = new List <string>(); List <SfzRegion> Regions = new List <SfzRegion>(); for (int x = 0; x < text.Length; x++) { string line = text[x].Trim(); if (line != "") { switch (line.Substring(0, 1).ToLower()) { case "<": if (line == "<group>") { while (text[x] != "") { x++; if (x >= text.Length) { break; } string[] Rvalue = text[x].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); if (Rvalue.Length == 2) { switch (Rvalue[0]) { case "sample": Rvalue[1] = System.IO.Path.GetFileNameWithoutExtension(Rvalue[1]); groupValues[0] = true; if (SampleNames.Contains(Rvalue[1])) //its in the local list so no need to check the master list { Group.SampleIndex = SampleNames.IndexOf(Rvalue[1]); } else { SampleNames.Add(Rvalue[1]); //check if the sample is in the master list. int sampNum = bank.SampleNameList.IndexOf(Rvalue[1]); Sample s; if (sampNum > -1) //its in the list { s = bank.SampleList[sampNum]; } else //its not in the list { s = new Sample(InstrumentPath + "SAMPLES/" + Rvalue[1] + ".wav"); bank.SampleList.Add(s); bank.SampleNameList.Add(Rvalue[1]); } if (s.isDualChannel == false) { allSamplesHaveDualChannels = false; } Samples.Add(s); Group.SampleIndex = SampleNames.Count - 1; } break; case "hikey": Group.HiNote = (byte)int.Parse(Rvalue[1]); groupValues[1] = true; break; case "lokey": Group.LoNote = (byte)int.Parse(Rvalue[1]); groupValues[2] = true; break; case "loop_start": Group.LoopStart = int.Parse(Rvalue[1]); groupValues[3] = true; break; case "loop_end": Group.LoopEnd = int.Parse(Rvalue[1]); groupValues[4] = true; break; case "tune": Group.Tune = int.Parse(Rvalue[1]) / 100.0f; groupValues[5] = true; break; case "pitch_keycenter": Group.Root = int.Parse(Rvalue[1]); groupValues[6] = true; break; case "volume": Group.Volume = float.Parse(Rvalue[1]); groupValues[7] = true; break; case "loop_mode": groupValues[8] = true; switch (Rvalue[1]) { case "loop_continuous": Group.LoopMode = 1; break; case "loop_sustain": Group.LoopMode = 2; break; default: Group.LoopMode = 0; break; } break; case "ampeg_release": groupValues[9] = true; Group.Release = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_attack": groupValues[10] = true; Group.Attack = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_decay": groupValues[11] = true; Group.Decay = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_hold": groupValues[12] = true; Group.Hold = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "lovel": groupValues[13] = true; Group.LoVelocity = (byte)int.Parse(Rvalue[1]); break; case "hivel": groupValues[14] = true; Group.HiVelocity = (byte)int.Parse(Rvalue[1]); break; case "lochan": groupValues[15] = true; Group.LoChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "hichan": groupValues[16] = true; Group.HiChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "key": Group.Root = int.Parse(Rvalue[1]); groupValues[6] = true; Group.HiNote = (byte)Group.Root; groupValues[1] = true; Group.LoNote = (byte)Group.Root; groupValues[2] = true; break; case "offset": groupValues[17] = true; Group.Offset = int.Parse(Rvalue[1]); break; case "pan": groupValues[18] = true; Group.Pan = float.Parse(Rvalue[1]); break; case "effect1": groupValues[19] = true; Group.Effect1 = float.Parse(Rvalue[1]); break; case "effect2": groupValues[20] = true; Group.Effect2 = float.Parse(Rvalue[1]); break; default: break; } } } } else if (line == "<region>") { SfzRegion r = new SfzRegion(); while (text[x] != "") { x++; if (x >= text.Length) { break; } string[] Rvalue = text[x].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); if (Rvalue.Length == 2) { switch (Rvalue[0]) { case "sample": Rvalue[1] = System.IO.Path.GetFileNameWithoutExtension(Rvalue[1]); //remove ending .wav if (SampleNames.Contains(Rvalue[1])) //its in the local list so no need to check the master list { r.SampleIndex = SampleNames.IndexOf(Rvalue[1]); } else { SampleNames.Add(Rvalue[1]); //check if the sample is in the master list. int sampNum = bank.SampleNameList.IndexOf(Rvalue[1]); Sample s; if (sampNum > -1) //its in the list { s = bank.SampleList[sampNum]; } else //its not in the list { s = new Sample(InstrumentPath + "SAMPLES/" + Rvalue[1] + ".wav"); bank.SampleList.Add(s); bank.SampleNameList.Add(Rvalue[1]); } if (s.isDualChannel == false) { allSamplesHaveDualChannels = false; } Samples.Add(s); r.SampleIndex = SampleNames.Count - 1; } break; case "hikey": r.HiNote = (byte)int.Parse(Rvalue[1]); break; case "lokey": r.LoNote = (byte)int.Parse(Rvalue[1]); break; case "loop_start": r.LoopStart = int.Parse(Rvalue[1]); break; case "loop_end": r.LoopEnd = int.Parse(Rvalue[1]); break; case "tune": r.Tune = int.Parse(Rvalue[1]) / 100.0f; break; case "pitch_keycenter": r.Root = int.Parse(Rvalue[1]); break; case "volume": r.Volume = float.Parse(Rvalue[1]); break; case "loop_mode": switch (Rvalue[1]) { case "loop_continuous": r.LoopMode = 1; break; case "loop_sustain": r.LoopMode = 2; break; default: r.LoopMode = 0; break; } break; case "ampeg_release": r.Release = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_attack": r.Attack = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_decay": r.Decay = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "ampeg_hold": r.Hold = SynthHelper.getSampleFromTime(this.SampleRate, float.Parse(Rvalue[1])); break; case "lovel": r.LoVelocity = (byte)int.Parse(Rvalue[1]); break; case "hivel": r.HiVelocity = (byte)int.Parse(Rvalue[1]); break; case "lochan": r.LoChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "hichan": r.HiChannel = (byte)(int.Parse(Rvalue[1]) - 1); break; case "key": r.Root = int.Parse(Rvalue[1]); r.HiNote = (byte)r.Root; r.LoNote = (byte)r.Root; break; case "offset": r.Offset = int.Parse(Rvalue[1]); break; case "pan": r.Pan = float.Parse(Rvalue[1]); break; case "effect1": r.Effect1 = float.Parse(Rvalue[1]); break; case "effect2": r.Effect2 = float.Parse(Rvalue[1]); break; default: break; } } } if (Regions.Contains(r) == false) { Regions.Add(r); } } break; default: break; } } } //Apply group values here for (int x = 0; x < Regions.Count; x++) { if (groupValues[0] == true) { Regions[x].SampleIndex = Group.SampleIndex; } if (groupValues[1] == true) { Regions[x].HiNote = Group.HiNote; } if (groupValues[2] == true) { Regions[x].LoNote = Group.LoNote; } if (groupValues[3] == true) { Regions[x].LoopStart = Group.LoopStart; } if (groupValues[4] == true) { Regions[x].LoopEnd = Group.LoopEnd; } if (groupValues[5] == true) { Regions[x].Tune = Group.Tune; } if (groupValues[6] == true) { Regions[x].Root = Group.Root; } if (groupValues[7] == true) { Regions[x].Volume = Group.Volume; } if (groupValues[8] == true) { Regions[x].LoopMode = Group.LoopMode; } if (groupValues[9] == true) { Regions[x].Release = Group.Release; } if (groupValues[10] == true) { Regions[x].Attack = Group.Attack; } if (groupValues[11] == true) { Regions[x].Decay = Group.Decay; } if (groupValues[12] == true) { Regions[x].Hold = Group.Hold; } if (groupValues[13] == true) { Regions[x].LoVelocity = Group.LoVelocity; } if (groupValues[14] == true) { Regions[x].HiVelocity = Group.HiVelocity; } if (groupValues[15] == true) { Regions[x].LoChannel = Group.LoChannel; } if (groupValues[16] == true) { Regions[x].HiChannel = Group.HiChannel; } if (groupValues[17] == true) { Regions[x].Offset = Group.Offset; } if (groupValues[18] == true) { Regions[x].Pan = Group.Pan; } if (groupValues[19] == true) { Regions[x].Effect1 = Group.Effect1; } if (groupValues[20] == true) { Regions[x].Effect2 = Group.Effect2; } } base.SampleList = Samples.ToArray(); regions = Regions.ToArray(); //Fix parameters so enforce isn't needed for (int x = 0; x < regions.Length; x++) { Sample s = base.SampleList[regions[x].SampleIndex]; float factor = (this.SampleRate / (float)s.OriginalSampleRate); regions[x].LoopEnd = (int)(regions[x].LoopEnd * factor); regions[x].LoopStart = (int)(regions[x].LoopStart * factor); regions[x].Offset = (int)(regions[x].Offset * factor); //Set loopend to end of sample if none is provided if (regions[x].LoopEnd <= 0) { if (this.SampleRate != s.SampleRate) { regions[x].LoopEnd = (int)(base.SampleList[regions[x].SampleIndex].SamplesPerChannel * factor) - 1; } else { regions[x].LoopEnd = (int)(base.SampleList[regions[x].SampleIndex].SamplesPerChannel) - 1; } } } //Resample as well for (int x = 0; x < base.SampleList.Length; x++) { Sample s = base.SampleList[x]; float factor = this.SampleRate / (float)s.SampleRate; if (factor != 1.0f) { s.setAllSampleData(WaveHelper.ReSample(this.SampleRate, s.SampleRate, s.getAllSampleData())); s.SampleRate = this.SampleRate; } } }
//--Private Methods private void ReadFromStream(Stream InstrumentStream, string path, InstrumentBank bank) { StreamReader reader = new StreamReader(InstrumentStream); List<string> text = new List<string>(); while (reader.Peek() > -1) text.Add(reader.ReadLine()); reader.Close(); InstrumentStream.Close(); ParseInstrumentData(text.ToArray(), path, bank); }