예제 #1
0
파일: Sf2Synth.cs 프로젝트: DotLab/Midif
        public Sf2Synth(Sf2File file, Table table, int voiceCount)
        {
            this.file  = file;
            this.table = table;

            masterGain = 1;

            this.voiceCount = voiceCount;
            voices          = new Voice[voiceCount];
            for (int i = 0; i < voiceCount; i += 1)
            {
                voices[i].Init(i, file.data, table);
            }

                        #if MIDIF_DEBUG_VISUALIZER
            WaveVisualizer.Request(0, 1024);
            WaveVisualizer.Request(1, 1024);
            WaveVisualizer.Request(2, 1024);
            WaveVisualizer.Request(3, 1024);
            WaveVisualizer.Request(4, 1024);
            WaveVisualizer.Request(5, 1024);
                        #endif

            Reset();
        }
예제 #2
0
파일: MidiSynth.cs 프로젝트: DotLab/Midif
        public void Process(float[] data)
        {
            for (int i = 0, length = data.Length; i < length; i += 2)
            {
                float left  = 0;
                float right = 0;

                for (int j = firstActiveVoice; j != -1; j = voices[j].next)
                {
                    float envelopeGain = voices[j].envelope.gain;
                    voices[j].envelope.AdvanceTime(sampleRateRecip);
                    float value = envelopeGain * (float)Math.Sin(voices[j].time * voices[j].freq * Table.Pi2);
                    left           += value * voices[j].gainLeft;
                    right          += value * voices[j].gainRight;
                    voices[j].time += sampleRateRecip;
                }

                data[i]     = left;
                data[i + 1] = right;

                                #if MIDIF_DEBUG_VISUALIZER
                WaveVisualizer.Push(0, left);
                                #endif
            }

            Panic();
        }
예제 #3
0
파일: Sf2Synth.cs 프로젝트: DotLab/Midif
        public void Process(float[] buffer)
        {
                        #if MIDIF_DEBUG_VISUALIZER
            WaveVisualizer.Clear(0);
            WaveVisualizer.Clear(1);
            WaveVisualizer.Clear(2);
            WaveVisualizer.Clear(3);
            WaveVisualizer.Clear(5);
                        #endif

            try {
                for (int j = firstActiveVoice; j != -1; j = voices[j].next)
                {
                    voices[j].Process(buffer);
                                        #if MIDIF_DEBUG_VISUALIZER
                    WaveVisualizer.SetI(0, 0);
                    WaveVisualizer.SetI(1, 0);
                    WaveVisualizer.SetI(2, 0);
                    WaveVisualizer.SetI(3, 0);
                    WaveVisualizer.SetI(5, 0);
                                        #endif
                }
            } catch (System.Exception e) {
                UnityEngine.Debug.LogError(e);
                Reset();
                return;
            }

                        #if MIDIF_DEBUG_VISUALIZER
            for (int i = 0, length = buffer.Length; i < length; i += 2)
            {
                WaveVisualizer.Push(4, buffer[i]);
            }
                        #endif

//			Panic();
        }
예제 #4
0
파일: MidiSynth.cs 프로젝트: DotLab/Midif
        public MidiSynth(Table table, float sampleRate, int voiceCount)
        {
                        #if MIDIF_DEBUG_VISUALIZER
            WaveVisualizer.Request(0, 1024);
                        #endif

            this.table = table;

            this.sampleRate = sampleRate;
            sampleRateRecip = 1f / sampleRate;

            masterGain = 1;

            envelopeConfig = new EnvelopeConfig(table, 120, .01f, 60, .1f, 100, .5f, 0, .01f);

            this.voiceCount = voiceCount;
            voices          = new Voice[voiceCount];
            for (int i = 0; i < voiceCount; i += 1)
            {
                voices[i].envelope = new Envelope(envelopeConfig);
            }

            Reset();
        }
예제 #5
0
파일: Sf2Synth.cs 프로젝트: DotLab/Midif
            public void Process(float[] buffer)
            {
                float min = 0, max = 0;

                for (int i = 0, length = buffer.Length; i < length; i += 2)
                {
                    // the first iteration will call update with count = 0 so that filter, lfos, envs can init
                    bool lfoFlag = (count & lfoMask) == 0;
                    bool envFlag = (count & envMask) == 0;
                    // maybe more specific flags will be better?
                    if (lfoFlag || envFlag)
                    {
                        Update(lfoFlag, envFlag);
                    }
                    count += 1;

                    // simple interpolation
                    float value;
                    if (killed)
                    {
                        value = 0;
                    }
                    else
                    {
                        if (phase < 0)
                        {
                            UnityEngine.Debug.LogWarning("phase < 0");
                            Kill();
                            return;
                        }
                        uint  uintPhase = (uint)phase;
                        float ut        = (float)(phase - uintPhase);
                        value = data[start + uintPhase] * (1f - ut) + data[start + uintPhase + 1] * ut;
                        //						Console.Log(phase, uintPhase, ut);
                    }

                    // filter even when fc > 13500 (set fc = 13500 when that happens) so that filter is always ready
                    if (useFilter)
                    {
                        value = filter.Process(value);
                    }

                    value = value * gain;
                    if (value < min)
                    {
                        min = value;
                    }
                    if (value > max)
                    {
                        max = value;
                    }

                    buffer[i]     += value * channelGainLeft * panLeft;
                    buffer[i + 1] += value * channelGainRight * panRight;

                                        #if MIDIF_DEBUG_VISUALIZER
                    WaveVisualizer.Inc(0, filter.h1 * attenuation);
                    WaveVisualizer.Inc(1, filter.h2 * attenuation);
                    WaveVisualizer.Inc(2, vibLfo.value * attenuation);
                    WaveVisualizer.Inc(3, modLfo.value * attenuation);
                    WaveVisualizer.Inc(5, data[start + (int)phase] * attenuation);
                                        #endif

                    phase += curStep * channelPitch;
                    switch (mode)
                    {
                    case Sf2File.SampleMode.contLoop:
                        if (phase > loopEnd)
                        {
                            phase -= loopDuration;
                        }
                        break;

                    case Sf2File.SampleMode.contLoopRelease:
                        if (volEnv.stage == Envelope.StageRelease)
                        {
                            if (phase > duration)
                            {
                                Kill();
                            }
                        }
                        else
                        {
                            if (phase > loopEnd)
                            {
                                phase -= loopDuration;
                            }
                        }
                        break;

                    // case Sf2File.SampleMode.noLoop:
                    default:
                        if (phase > duration)
                        {
                            Kill();
                        }
                        break;
                    }
                }
                if (max - min > 3f)
                {
                    UnityEngine.Debug.LogWarningFormat("max ({0:F2}) - min ({1:F2}) = ({2:F2})", max, min, max - min);
                    Kill();
                }
            }