コード例 #1
0
ファイル: Sf2Patch.cs プロジェクト: CoderLine/alphaSynth
        public void Load(Sf2Region region, AssetManager assets)
        {
            ExclusiveGroup = region.Generators[(int)GeneratorEnum.ExclusiveClass];
            ExclusiveGroupTarget = ExclusiveGroup;

            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();
            pan.SetValue(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);
        }
コード例 #2
0
ファイル: PatchBank.cs プロジェクト: eriser/alphaSynth
        public void LoadSf2(IReadable input)
        {
            Reset();

            Logger.Debug("Reading SF2");
            var sf = new SoundFont();
            sf.Load(input);

            Logger.Debug("Building patchbank");
            Name = sf.Info.BankName;
            Comments = sf.Info.Comments;

            //load samples
            foreach (var sampleHeader in sf.Presets.SampleHeaders)
            {
                _assets.SampleAssets.Add(new SampleDataAsset(sampleHeader, sf.SampleData));
            }

            //create instrument regions first
            var sfinsts = ReadSf2Instruments(sf.Presets.Instruments);
            //load each patch
            foreach (var 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;
                }

                var regionList = new FastList<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 (TypeUtils.IsLittleEndian)
                        {
                            presetLoKey = TypeUtils.ToUInt8(p.Zones[i].Generators[0].AmountInt16 & 0xFF);
                            presetHiKey = TypeUtils.ToUInt8((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF);
                        }
                        else
                        {
                            presetHiKey = TypeUtils.ToUInt8(p.Zones[i].Generators[0].AmountInt16 & 0xFF);
                            presetLoKey = TypeUtils.ToUInt8((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF);
                        }
                        if (p.Zones[i].Generators.Length > 1 && p.Zones[i].Generators[1].GeneratorType == GeneratorEnum.VelocityRange)
                        {
                            if (TypeUtils.IsLittleEndian)
                            {
                                presetLoVel = TypeUtils.ToUInt8(p.Zones[i].Generators[1].AmountInt16 & 0xFF);
                                presetHiVel = TypeUtils.ToUInt8((p.Zones[i].Generators[1].AmountInt16 >> 8) & 0xFF);
                            }
                            else
                            {
                                presetHiVel = TypeUtils.ToUInt8(p.Zones[i].Generators[1].AmountInt16 & 0xFF);
                                presetLoVel = TypeUtils.ToUInt8((p.Zones[i].Generators[1].AmountInt16 >> 8) & 0xFF);
                            }
                        }
                    }
                    else if (p.Zones[i].Generators[0].GeneratorType == GeneratorEnum.VelocityRange)
                    {
                        if (TypeUtils.IsLittleEndian)
                        {
                            presetLoVel = TypeUtils.ToUInt8(p.Zones[i].Generators[0].AmountInt16 & 0xFF);
                            presetHiVel = TypeUtils.ToUInt8((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF);
                        }
                        else
                        {
                            presetHiVel = TypeUtils.ToUInt8(p.Zones[i].Generators[0].AmountInt16 & 0xFF);
                            presetLoVel = TypeUtils.ToUInt8((p.Zones[i].Generators[0].AmountInt16 >> 8) & 0xFF);
                        }
                    }
                    if (p.Zones[i].Generators[p.Zones[i].Generators.Length - 1].GeneratorType == GeneratorEnum.Instrument)
                    {
                        var insts = sfinsts[p.Zones[i].Generators[p.Zones[i].Generators.Length - 1].AmountInt16];
                        foreach (var inst in insts)
                        {
                            byte instLoKey;
                            byte instHiKey;
                            byte instLoVel;
                            byte instHiVel;
                            if (TypeUtils.IsLittleEndian)
                            {
                                instLoKey = TypeUtils.ToUInt8(inst.Generators[(int)GeneratorEnum.KeyRange] & 0xFF);
                                instHiKey = TypeUtils.ToUInt8((inst.Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF);
                                instLoVel = TypeUtils.ToUInt8(inst.Generators[(int)GeneratorEnum.VelocityRange] & 0xFF);
                                instHiVel = TypeUtils.ToUInt8((inst.Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF);
                            }
                            else
                            {
                                instHiKey = TypeUtils.ToUInt8(inst.Generators[(int)GeneratorEnum.KeyRange] & 0xFF);
                                instLoKey = TypeUtils.ToUInt8((inst.Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF);
                                instHiVel = TypeUtils.ToUInt8(inst.Generators[(int)GeneratorEnum.VelocityRange] & 0xFF);
                                instLoVel = TypeUtils.ToUInt8((inst.Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF);
                            }
                            if ((instLoKey <= presetHiKey && presetLoKey <= instHiKey) && (instLoVel <= presetHiVel && presetLoVel <= instHiVel))
                            {
                                var r = new Sf2Region();
                                Std.ArrayCopy(inst.Generators, 0, r.Generators, 0, r.Generators.Length);
                                ReadSf2Region(r, globalGens, p.Zones[i].Generators, true);
                                regionList.Add(r);
                            }
                        }
                    }
                    i++;
                }
                var mp = new MultiPatch(p.Name);
                mp.LoadSf2(regionList.ToArray(), _assets);
                _assets.PatchAssets.Add(new PatchAsset(mp.Name, mp));
                AssignPatchToBank(mp, p.BankNumber, p.PatchNumber, p.PatchNumber);
            }
        }
コード例 #3
0
ファイル: PatchBank.cs プロジェクト: eriser/alphaSynth
        private void ReadSf2Region(Sf2Region region, Generator[] globals, Generator[] gens, bool isRelative)
        {
            if (!isRelative)
            {
                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
            {
                var genList = new FastList<Generator>();
                foreach (var generator in gens)
                {
                    genList.Add(generator);
                }
                if (globals != null)
                {
                    for (int x = 0; x < globals.Length; x++)
                    {
                        var 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++)
                {
                    var 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)
                    {
                        byte lo_a;
                        byte hi_a;
                        byte lo_b;
                        byte hi_b;
                        if (TypeUtils.IsLittleEndian)
                        {
                            lo_a = TypeUtils.ToUInt8(region.Generators[value] & 0xFF);
                            hi_a = TypeUtils.ToUInt8((region.Generators[value] >> 8) & 0xFF);
                            lo_b = TypeUtils.ToUInt8(genList[x].AmountInt16 & 0xFF);
                            hi_b = TypeUtils.ToUInt8((genList[x].AmountInt16 >> 8) & 0xFF);
                        }
                        else
                        {
                            hi_a = TypeUtils.ToUInt8(region.Generators[value] & 0xFF);
                            lo_a = TypeUtils.ToUInt8((region.Generators[value] >> 8) & 0xFF);
                            hi_b = TypeUtils.ToUInt8(genList[x].AmountInt16 & 0xFF);
                            lo_b = TypeUtils.ToUInt8((genList[x].AmountInt16 >> 8) & 0xFF);
                        }
                        lo_a = (byte) 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 (TypeUtils.IsLittleEndian)
                        {
                            region.Generators[value] = TypeUtils.ToInt16((lo_a | (hi_a << 8)));
                        }
                        else
                        {
                            region.Generators[value] = TypeUtils.ToInt16((lo_a << 8) | hi_a);
                        }
                    }
                    else
                    {
                        region.Generators[value] = TypeUtils.ToInt16(region.Generators[value] + genList[x].AmountInt16);
                    }
                }
            }
        }
コード例 #4
0
ファイル: PatchBank.cs プロジェクト: eriser/alphaSynth
        private Sf2Region[][] ReadSf2Instruments(Instrument[] instruments)
        {
            var regions = new Sf2Region[instruments.Length][];
            for (int x = 0; x < instruments.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++)
                {
                    var r = new Sf2Region();
                    r.ApplyDefaultValues();
                    ReadSf2Region(r, globalGens, instruments[x].Zones[j + i].Generators, false);
                    regions[x][j] = r;
                }
            }
            return regions;
        }
コード例 #5
0
ファイル: Sf2Patch.cs プロジェクト: CoderLine/alphaSynth
 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 = DefaultGenerators.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 = DefaultGenerators.DefaultSine;
 }
コード例 #6
0
ファイル: Sf2Patch.cs プロジェクト: CoderLine/alphaSynth
 private void LoadGen(Sf2Region region, AssetManager assets)
 {
     SampleDataAsset sda = assets.SampleAssets[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 = LoopMode.NoLoop;
             break;
         case 0x1:
             gen.LoopMode = LoopMode.Continuous;
             break;
         case 0x3:
             gen.LoopMode = LoopMode.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;
 }
コード例 #7
0
ファイル: Sf2Patch.cs プロジェクト: CoderLine/alphaSynth
 private void LoadFilter(Sf2Region region)
 {
     fltr = new FilterDescriptor();
     fltr.FilterMethod = FilterType.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);
 }
コード例 #8
0
ファイル: Sf2Patch.cs プロジェクト: CoderLine/alphaSynth
        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.ClampS(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.ClampS(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;
        }
コード例 #9
0
ファイル: MultiPatch.cs プロジェクト: eriser/alphaSynth
 public void LoadSf2(Sf2Region[] regions, AssetManager assets)
 {
     _intervalList = new PatchInterval[regions.Length];
     for (int x = 0; x < regions.Length; x++)
     {
         byte loKey;
         byte hiKey;
         byte loVel;
         byte hiVel;
         if (TypeUtils.IsLittleEndian)
         {
             loKey = TypeUtils.ToUInt8(regions[x].Generators[(int)GeneratorEnum.KeyRange] & 0xFF);
             hiKey = TypeUtils.ToUInt8((regions[x].Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF);
             loVel = TypeUtils.ToUInt8(regions[x].Generators[(int)GeneratorEnum.VelocityRange] & 0xFF);
             hiVel = TypeUtils.ToUInt8((regions[x].Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF);
         }
         else
         {
             hiKey = TypeUtils.ToUInt8(regions[x].Generators[(int)GeneratorEnum.KeyRange] & 0xFF);
             loKey = TypeUtils.ToUInt8((regions[x].Generators[(int)GeneratorEnum.KeyRange] >> 8) & 0xFF);
             hiVel = TypeUtils.ToUInt8(regions[x].Generators[(int)GeneratorEnum.VelocityRange] & 0xFF);
             loVel = TypeUtils.ToUInt8((regions[x].Generators[(int)GeneratorEnum.VelocityRange] >> 8) & 0xFF);
         }
         var sf2 = new Sf2Patch(Name + "_" + x);
         sf2.Load(regions[x], assets);
         _intervalList[x] = new PatchInterval(sf2, 0, 15, loKey, hiKey, loVel, hiVel);
     }
     DetermineIntervalType();
 }