private void LoadFilter(Sf2Region region) { fltr = new FilterDescriptor(); fltr.FilterMethod = FilterTypeEnum.BiquadLowpass; fltr.CutOff = (float)SynthHelper.KeyToFrequency(region.Generators[(int)GeneratorEnum.InitialFilterCutoffFrequency] / 100.0, 69); fltr.Resonance = (float)SynthHelper.DBtoLinear(region.Generators[(int)GeneratorEnum.InitialFilterQ] / 10.0); }
private void LoadEnvelopes(Sf2Region region) { //mod env mod_env = new EnvelopeDescriptor(); mod_env.AttackTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.AttackModulationEnvelope] / 1200.0); mod_env.AttackGraph = 3; mod_env.DecayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DecayModulationEnvelope] / 1200.0); mod_env.DelayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DelayModulationEnvelope] / 1200.0); mod_env.HoldTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.HoldModulationEnvelope] / 1200.0); mod_env.PeakLevel = 1; mod_env.ReleaseTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.ReleaseModulationEnvelope] / 1200.0); mod_env.StartLevel = 0; mod_env.SustainLevel = 1f - SynthHelper.Clamp(region.Generators[(int)GeneratorEnum.SustainModulationEnvelope], (short)0, (short)1000) / 1000f; //checks if (mod_env.AttackTime < 0.001f) mod_env.AttackTime = 0.001f; else if (mod_env.AttackTime > 100f) mod_env.AttackTime = 100f; if (mod_env.DecayTime < 0.001f) mod_env.DecayTime = 0; else if (mod_env.DecayTime > 100f) mod_env.DecayTime = 100f; if (mod_env.DelayTime < 0.001f) mod_env.DelayTime = 0; else if (mod_env.DelayTime > 20f) mod_env.DelayTime = 20f; if (mod_env.HoldTime < 0.001f) mod_env.HoldTime = 0; else if (mod_env.HoldTime > 20f) mod_env.HoldTime = 20f; if (mod_env.ReleaseTime < 0.001f) mod_env.ReleaseTime = 0.001f; else if (mod_env.ReleaseTime > 100f) mod_env.ReleaseTime = 100f; //volume env vel_env = new EnvelopeDescriptor(); vel_env.AttackTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.AttackVolumeEnvelope] / 1200.0); vel_env.AttackGraph = 3; vel_env.DecayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DecayVolumeEnvelope] / 1200.0); vel_env.DelayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DelayVolumeEnvelope] / 1200.0); vel_env.HoldTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.HoldVolumeEnvelope] / 1200.0); vel_env.PeakLevel = 0; vel_env.ReleaseTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.ReleaseVolumeEnvelope] / 1200.0); vel_env.StartLevel = -100; vel_env.SustainLevel = SynthHelper.Clamp(region.Generators[(int)GeneratorEnum.SustainVolumeEnvelope], (short)0, (short)1000) / -10f; //checks if (vel_env.AttackTime < 0.001f) vel_env.AttackTime = 0.001f; else if (vel_env.AttackTime > 100f) vel_env.AttackTime = 100f; if (vel_env.DecayTime < 0.001f) vel_env.DecayTime = 0; else if (vel_env.DecayTime > 100f) vel_env.DecayTime = 100f; if (vel_env.DelayTime < 0.001f) vel_env.DelayTime = 0; else if (vel_env.DelayTime > 20f) vel_env.DelayTime = 20f; if (vel_env.HoldTime < 0.001f) vel_env.HoldTime = 0; else if (vel_env.HoldTime > 20f) vel_env.HoldTime = 20f; if (vel_env.ReleaseTime < 0.001f) vel_env.ReleaseTime = 0.001f; else if (vel_env.ReleaseTime > 100f) vel_env.ReleaseTime = 100f; }
private void LoadLfos(Sf2Region region) { mod_lfo = new LfoDescriptor(); mod_lfo.DelayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DelayModulationLFO] / 1200.0); mod_lfo.Frequency = (float)(Math.Pow(2, region.Generators[(int)GeneratorEnum.FrequencyModulationLFO] / 1200.0) * 8.176); mod_lfo.Generator = AudioSynthesis.Bank.Components.Generators.Generator.DefaultSine; vib_lfo = new LfoDescriptor(); vib_lfo.DelayTime = (float)Math.Pow(2, region.Generators[(int)GeneratorEnum.DelayVibratoLFO] / 1200.0); vib_lfo.Frequency = (float)(Math.Pow(2, region.Generators[(int)GeneratorEnum.FrequencyVibratoLFO] / 1200.0) * 8.176); vib_lfo.Generator = AudioSynthesis.Bank.Components.Generators.Generator.DefaultSine; }
private void LoadGen(Sf2Region region, AssetManager assets) { SampleDataAsset sda = assets.SampleAssetList[region.Generators[(int)GeneratorEnum.SampleID]]; gen = new SampleGenerator(); gen.EndPhase = sda.End + region.Generators[(int)GeneratorEnum.EndAddressOffset] + 32768 * region.Generators[(int)GeneratorEnum.EndAddressCoarseOffset]; gen.Frequency = sda.SampleRate; gen.KeyTrack = region.Generators[(int)GeneratorEnum.ScaleTuning]; gen.LoopEndPhase = sda.LoopEnd + region.Generators[(int)GeneratorEnum.EndLoopAddressOffset] + 32768 * region.Generators[(int)GeneratorEnum.EndLoopAddressCoarseOffset]; switch (region.Generators[(int)GeneratorEnum.SampleModes] & 0x3) { case 0x0: case 0x2: gen.LoopMode = LoopModeEnum.NoLoop; break; case 0x1: gen.LoopMode = LoopModeEnum.Continuous; break; case 0x3: gen.LoopMode = LoopModeEnum.LoopUntilNoteOff; break; } gen.LoopStartPhase = sda.LoopStart + region.Generators[(int)GeneratorEnum.StartLoopAddressOffset] + 32768 * region.Generators[(int)GeneratorEnum.StartLoopAddressCoarseOffset]; gen.Offset = 0; gen.Period = 1.0; if (region.Generators[(int)GeneratorEnum.OverridingRootKey] > -1) gen.RootKey = region.Generators[(int)GeneratorEnum.OverridingRootKey]; else gen.RootKey = sda.RootKey; gen.StartPhase = sda.Start + region.Generators[(int)GeneratorEnum.StartAddressOffset] + 32768 * region.Generators[(int)GeneratorEnum.StartAddressCoarseOffset]; gen.Tune = (short)(sda.Tune + region.Generators[(int)GeneratorEnum.FineTune] + 100 * region.Generators[(int)GeneratorEnum.CoarseTune]); gen.VelocityTrack = 0; ((SampleGenerator)gen).Samples = sda.SampleData; }
public void Load(Sf2Region region, AssetManager assets) { this.exGroup = region.Generators[(int)GeneratorEnum.ExclusiveClass]; this.exTarget = exGroup; iniFilterFc = region.Generators[(int)GeneratorEnum.InitialFilterCutoffFrequency]; filterQ = SynthHelper.DBtoLinear(region.Generators[(int)GeneratorEnum.InitialFilterQ] / 10.0); initialAttn = -region.Generators[(int)GeneratorEnum.InitialAttenuation] / 10f; keyOverride = region.Generators[(int)GeneratorEnum.KeyNumber]; velOverride = region.Generators[(int)GeneratorEnum.Velocity]; keynumToModEnvHold = region.Generators[(int)GeneratorEnum.KeyNumberToModulationEnvelopeHold]; keynumToModEnvDecay = region.Generators[(int)GeneratorEnum.KeyNumberToModulationEnvelopeDecay]; keynumToVolEnvHold = region.Generators[(int)GeneratorEnum.KeyNumberToVolumeEnvelopeHold]; keynumToVolEnvDecay = region.Generators[(int)GeneratorEnum.KeyNumberToVolumeEnvelopeDecay]; pan = new PanComponent(region.Generators[(int)GeneratorEnum.Pan] / 500f, PanFormulaEnum.Neg3dBCenter); modLfoToPitch = region.Generators[(int)GeneratorEnum.ModulationLFOToPitch]; vibLfoToPitch = region.Generators[(int)GeneratorEnum.VibratoLFOToPitch]; modEnvToPitch = region.Generators[(int)GeneratorEnum.ModulationEnvelopeToPitch]; modLfoToFilterFc = region.Generators[(int)GeneratorEnum.ModulationLFOToFilterCutoffFrequency]; modEnvToFilterFc = region.Generators[(int)GeneratorEnum.ModulationEnvelopeToFilterCutoffFrequency]; modLfoToVolume = region.Generators[(int)GeneratorEnum.ModulationLFOToVolume] / 10f; LoadGen(region, assets); LoadEnvelopes(region); LoadLfos(region); LoadFilter(region); }
private void ReadSf2Region(Sf2Region region, Generator[] globals, Generator[] gens, bool isRelative) { if (isRelative == false) { if (globals != null) { for (int x = 0; x < globals.Length; x++) region.Generators[(int)globals[x].GeneratorType] = globals[x].AmountInt16; } for (int x = 0; x < gens.Length; x++) region.Generators[(int)gens[x].GeneratorType] = gens[x].AmountInt16; } else { List<Generator> genList = new List<Generator>(gens); if (globals != null) { for (int x = 0; x < globals.Length; x++) { bool found = false; for (int i = 0; i < genList.Count; i++) { if (genList[i].GeneratorType == globals[x].GeneratorType) { found = true; break; } } if (!found) genList.Add(globals[x]); } } for (int x = 0; x < genList.Count; x++) { int value = (int)genList[x].GeneratorType; if (value < 5 || value == 12 || value == 45 || value == 46 || value == 47 || value == 50 || value == 54 || value == 57 || value == 58) continue; else if (value == 43 || value == 44) {//calculate intersect byte lo_a; byte hi_a; byte lo_b; byte hi_b; if (BitConverter.IsLittleEndian) { lo_a = (byte)(region.Generators[value] & 0xFF); hi_a = (byte)((region.Generators[value] >> 8) & 0xFF); lo_b = (byte)(genList[x].AmountInt16 & 0xFF); hi_b = (byte)((genList[x].AmountInt16 >> 8) & 0xFF); } else { hi_a = (byte)(region.Generators[value] & 0xFF); lo_a = (byte)((region.Generators[value] >> 8) & 0xFF); hi_b = (byte)(genList[x].AmountInt16 & 0xFF); lo_b = (byte)((genList[x].AmountInt16 >> 8) & 0xFF); } lo_a = Math.Max(lo_a, lo_b); hi_a = Math.Min(hi_a, hi_b); if (lo_a > hi_a) throw new Exception("Invalid sf2 region. The range generators do not intersect."); if (BitConverter.IsLittleEndian) region.Generators[value] = (short)(lo_a | (hi_a << 8)); else region.Generators[value] = (short)((lo_a << 8) | hi_a); } else region.Generators[value] += genList[x].AmountInt16; } } }
private Sf2Region[][] ReadSf2Instruments(Instrument[] instruments) { Sf2Region[][] regions = new Sf2Region[instruments.Length][]; for (int x = 0; x < regions.Length; x++) { Generator[] globalGens = null; int i; if (instruments[x].Zones[0].Generators.Length == 0 || instruments[x].Zones[0].Generators[instruments[x].Zones[0].Generators.Length - 1].GeneratorType != GeneratorEnum.SampleID) { globalGens = instruments[x].Zones[0].Generators; i = 1; } else i = 0; regions[x] = new Sf2Region[instruments[x].Zones.Length - i]; for (int j = 0; j < regions[x].Length; j++) { Sf2Region r = new Sf2Region(); r.ApplyDefaultValues(); ReadSf2Region(r, globalGens, instruments[x].Zones[j + i].Generators, false); regions[x][j] = r; } } return regions; }
private void LoadSf2(Stream stream) { SoundFont sf = new SoundFont(stream); bankName = sf.Info.BankName; comment = sf.Info.Comments; //load samples for (int x = 0; x < sf.Presets.SampleHeaders.Length; x++) assets.SampleAssetList.Add(new SampleDataAsset(sf.Presets.SampleHeaders[x], sf.SampleData)); //create instrument regions first Sf2Region[][] inst = ReadSf2Instruments(sf.Presets.Instruments); //load each patch foreach (PresetHeader p in sf.Presets.PresetHeaders) { Generator[] globalGens = null; int i; if (p.Zones[0].Generators.Length == 0 || p.Zones[0].Generators[p.Zones[0].Generators.Length - 1].GeneratorType != GeneratorEnum.Instrument) { globalGens = p.Zones[0].Generators; i = 1; } else i = 0; List<Sf2Region> regionList = new List<Sf2Region>(); while (i < p.Zones.Length) { byte presetLoKey = 0; byte presetHiKey = 127; byte presetLoVel = 0; byte presetHiVel = 127; if (p.Zones[i].Generators[0].GeneratorType == GeneratorEnum.KeyRange) { if (BitConverter.IsLittleEndian) { presetLoKey = (byte)(p.Zones[i].Generators[0].AmountInt16 & 0xFF); presetHiKey = (byte)((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF); } else { presetHiKey = (byte)(p.Zones[i].Generators[0].AmountInt16 & 0xFF); presetLoKey = (byte)((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF); } if (p.Zones[i].Generators.Length > 1 && p.Zones[i].Generators[1].GeneratorType == GeneratorEnum.VelocityRange) { if (BitConverter.IsLittleEndian) { presetLoVel = (byte)(p.Zones[i].Generators[1].AmountInt16 & 0xFF); presetHiVel = (byte)((p.Zones[i].Generators[1].AmountInt16 >> 8) & 0xFF); } else { presetHiVel = (byte)(p.Zones[i].Generators[1].AmountInt16 & 0xFF); presetLoVel = (byte)((p.Zones[i].Generators[1].AmountInt16 >> 8) & 0xFF); } } } else if (p.Zones[i].Generators[0].GeneratorType == GeneratorEnum.VelocityRange) { if (BitConverter.IsLittleEndian) { presetLoVel = (byte)(p.Zones[i].Generators[0].AmountInt16 & 0xFF); presetHiVel = (byte)((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF); } else { presetHiVel = (byte)(p.Zones[i].Generators[0].AmountInt16 & 0xFF); presetLoVel = (byte)((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF); } } if(p.Zones[i].Generators[p.Zones[i].Generators.Length - 1].GeneratorType == GeneratorEnum.Instrument) { Sf2Region[] insts = inst[p.Zones[i].Generators[p.Zones[i].Generators.Length - 1].AmountInt16]; for (int x = 0; x < insts.Length; x++) { byte instLoKey; byte instHiKey; byte instLoVel; byte instHiVel; if (BitConverter.IsLittleEndian) { instLoKey = (byte)(insts[x].Generators[(int)GeneratorEnum.KeyRange] & 0xFF); instHiKey = (byte)((insts[x].Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF); instLoVel = (byte)(insts[x].Generators[(int)GeneratorEnum.VelocityRange] & 0xFF); instHiVel = (byte)((insts[x].Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF); } else { instHiKey = (byte)(insts[x].Generators[(int)GeneratorEnum.KeyRange] & 0xFF); instLoKey = (byte)((insts[x].Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF); instHiVel = (byte)(insts[x].Generators[(int)GeneratorEnum.VelocityRange] & 0xFF); instLoVel = (byte)((insts[x].Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF); } if ((instLoKey <= presetHiKey && presetLoKey <= instHiKey) && (instLoVel <= presetHiVel && presetLoVel <= instHiVel)) { Sf2Region r = new Sf2Region(); Array.Copy(insts[x].Generators, r.Generators, r.Generators.Length); ReadSf2Region(r, globalGens, p.Zones[i].Generators, true); regionList.Add(r); } } } i++; } MultiPatch mp = new MultiPatch(p.Name); mp.LoadSf2(regionList.ToArray(), assets); assets.PatchAssetList.Add(new PatchAsset(mp.Name, mp)); AssignPatchToBank(mp, p.BankNumber, p.PatchNumber, p.PatchNumber); } }