示例#1
0
        private InstrumentRegion(Instrument instrument, Generator[] global, Generator[] local, SampleHeader[] samples)
        {
            gs = new short[61];
            gs[(int)GeneratorType.InitialFilterCutoffFrequency] = 13500;
            gs[(int)GeneratorType.DelayModulationLfo]           = -12000;
            gs[(int)GeneratorType.DelayVibratoLfo]           = -12000;
            gs[(int)GeneratorType.DelayModulationEnvelope]   = -12000;
            gs[(int)GeneratorType.AttackModulationEnvelope]  = -12000;
            gs[(int)GeneratorType.HoldModulationEnvelope]    = -12000;
            gs[(int)GeneratorType.DecayModulationEnvelope]   = -12000;
            gs[(int)GeneratorType.ReleaseModulationEnvelope] = -12000;
            gs[(int)GeneratorType.DelayVolumeEnvelope]       = -12000;
            gs[(int)GeneratorType.AttackVolumeEnvelope]      = -12000;
            gs[(int)GeneratorType.HoldVolumeEnvelope]        = -12000;
            gs[(int)GeneratorType.DecayVolumeEnvelope]       = -12000;
            gs[(int)GeneratorType.ReleaseVolumeEnvelope]     = -12000;
            gs[(int)GeneratorType.KeyRange]          = 0x7F00;
            gs[(int)GeneratorType.VelocityRange]     = 0x7F00;
            gs[(int)GeneratorType.KeyNumber]         = -1;
            gs[(int)GeneratorType.Velocity]          = -1;
            gs[(int)GeneratorType.ScaleTuning]       = 100;
            gs[(int)GeneratorType.OverridingRootKey] = -1;

            if (global != null)
            {
                foreach (var parameter in global)
                {
                    SetParameter(parameter);
                }
            }

            if (local != null)
            {
                foreach (var parameter in local)
                {
                    SetParameter(parameter);
                }
            }

            if (samples != null)
            {
                var id = gs[(int)GeneratorType.SampleID];
                if (!(0 <= id && id < samples.Length))
                {
                    throw new InvalidDataException($"The instrument '{instrument.Name}' contains an invalid sample ID '{id}'.");
                }
                sample = samples[id];
            }
            else
            {
                sample = SampleHeader.Default;
            }
        }
        internal static SampleHeader[] ReadFromChunk(BinaryReader reader, int size)
        {
            if (size % 46 != 0)
            {
                throw new InvalidDataException("The sample header list is invalid.");
            }

            var headers = new SampleHeader[size / 46 - 1];

            for (var i = 0; i < headers.Length; i++)
            {
                headers[i] = new SampleHeader(reader);
            }

            // The last one is the terminator.
            new SampleHeader(reader);

            return(headers);
        }
        internal SoundFontParameters(BinaryReader reader)
        {
            var chunkId = reader.ReadFourCC();

            if (chunkId != "LIST")
            {
                throw new InvalidDataException("The LIST chunk was not found.");
            }

            var end = reader.BaseStream.Position + reader.ReadInt32();

            var listType = reader.ReadFourCC();

            if (listType != "pdta")
            {
                throw new InvalidDataException($"The type of the LIST chunk must be 'pdta', but was '{listType}'.");
            }

            PresetInfo[]     presetInfos          = null;
            ZoneInfo[]       presetBag            = null;
            Generator[]      presetGenerators     = null;
            InstrumentInfo[] instrumentInfos      = null;
            ZoneInfo[]       instrumentBag        = null;
            Generator[]      instrumentGenerators = null;

            while (reader.BaseStream.Position < end)
            {
                var id   = reader.ReadFourCC();
                var size = reader.ReadInt32();

                switch (id)
                {
                case "phdr":
                    presetInfos = PresetInfo.ReadFromChunk(reader, size);
                    break;

                case "pbag":
                    presetBag = ZoneInfo.ReadFromChunk(reader, size);
                    break;

                case "pmod":
                    Modulator.DiscardData(reader, size);
                    break;

                case "pgen":
                    presetGenerators = Generator.ReadFromChunk(reader, size);
                    break;

                case "inst":
                    instrumentInfos = InstrumentInfo.ReadFromChunk(reader, size);
                    break;

                case "ibag":
                    instrumentBag = ZoneInfo.ReadFromChunk(reader, size);
                    break;

                case "imod":
                    Modulator.DiscardData(reader, size);
                    break;

                case "igen":
                    instrumentGenerators = Generator.ReadFromChunk(reader, size);
                    break;

                case "shdr":
                    sampleHeaders = SampleHeader.ReadFromChunk(reader, size);
                    break;

                default:
                    throw new InvalidDataException($"The INFO list contains an unknown ID '{id}'.");
                }
            }

            if (presetInfos == null)
            {
                throw new InvalidDataException("The PHDR sub-chunk was not found.");
            }
            if (presetBag == null)
            {
                throw new InvalidDataException("The PBAG sub-chunk was not found.");
            }
            if (presetGenerators == null)
            {
                throw new InvalidDataException("The PGEN sub-chunk was not found.");
            }
            if (instrumentInfos == null)
            {
                throw new InvalidDataException("The INST sub-chunk was not found.");
            }
            if (instrumentBag == null)
            {
                throw new InvalidDataException("The IBAG sub-chunk was not found.");
            }
            if (instrumentGenerators == null)
            {
                throw new InvalidDataException("The IGEN sub-chunk was not found.");
            }
            if (sampleHeaders == null)
            {
                throw new InvalidDataException("The SHDR sub-chunk was not found.");
            }

            var instrumentZones = Zone.Create(instrumentBag, instrumentGenerators);

            instruments = Instrument.Create(instrumentInfos, instrumentZones, sampleHeaders);

            var presetZones = Zone.Create(presetBag, presetGenerators);

            presets = Preset.Create(presetInfos, presetZones, instruments);
        }