示例#1
0
        public double dx7_voice_recalculate_frequency(hexter_instance instance)
        {
            double freq;

            this.last_port_tuning = instance.tuning;

            instance.fixed_freq_multiplier = instance.tuning / 440.0;

            freq = this.pitch_eg.value + this.portamento.value +
                   instance.pitch_bend -
                   instance.lfo_value_for_pitch *
                   (this.pitch_mod_depth_pmd * Inline.FP_TO_DOUBLE(this.lfo_delay_value) +
                    this.pitch_mod_depth_mods);

            this.last_pitch = freq;

            freq += (double)(limit_note(this.key + this.transpose - 24));

            /* -FIX- this maybe could be optimized */

            /*       a lookup table of 8k values would give ~1.5 cent accuracy,
             *       but then would interpolating that be faster than exp()? */
            freq = instance.tuning * Math.Exp((freq - 69.0) * Constants.M_LN2 / 12.0);

            return(freq);
        }
示例#2
0
        public void dx7_voice_do_control_update()
        {
            double new_pitch;

            /* do those things which should be done only once per control-
             * calculation interval ("nugget"), such as voice check-for-dead,
             * pitch envelope calculations, etc. */

            /* check if we've decayed to nothing, turn off voice if so */
            if (dx7_voice_check_for_dead() != 0)
            {
                return; /* we're dead now, so return */
            }
            /* update pitch envelope and portamento */
            this.pitch_eg.dx7_pitch_eg_process(instance);
            this.portamento.dx7_portamento_process(instance);

            /* update phase increments if pitch or tuning changed */
            new_pitch = this.pitch_eg.value + this.portamento.value +
                        instance.pitch_bend -
                        instance.lfo_value_for_pitch *
                        (this.pitch_mod_depth_pmd * Inline.FP_TO_DOUBLE(this.lfo_delay_value) +
                         this.pitch_mod_depth_mods);
            if ((this.last_pitch != new_pitch) || (this.last_port_tuning != instance.tuning))
            {
                dx7_voice_recalculate_freq_and_inc(instance);
            }

            /* op envelope rounding correction */
            this.op[Constants.OP_6].eg.dx7_op_eg_adjust();
            this.op[Constants.OP_5].eg.dx7_op_eg_adjust();
            this.op[Constants.OP_4].eg.dx7_op_eg_adjust();
            this.op[Constants.OP_3].eg.dx7_op_eg_adjust();
            this.op[Constants.OP_2].eg.dx7_op_eg_adjust();
            this.op[Constants.OP_1].eg.dx7_op_eg_adjust();

            /* mods and output volume */
            if (!(this.amp_mod_env_duration != 0))
            {
                this.amp_mod_env_value = this.amp_mod_env_target;
            }
            if (!(this.amp_mod_lfo_mods_duration != 0))
            {
                this.amp_mod_lfo_mods_value = this.amp_mod_lfo_mods_target;
            }
            if (!(this.amp_mod_lfo_amd_duration != 0))
            {
                this.amp_mod_lfo_amd_value = this.amp_mod_lfo_amd_target;
            }
            if (!(this.volume_duration != 0))
            {
                this.volume_value = this.volume_target;
            }
        }
示例#3
0
        public void dx7_lfo_update(UInt64 sample_count)
        {
            UInt64 sample;

            switch (this.lfo_wave)
            {
            default:
            case 0:      /* triangle */
            case 1:      /* saw down */
            case 2:      /* saw up */
                for (sample = 0; sample < sample_count; sample++)
                {
                    this.lfo_buffer[sample] = this.lfo_value;
                    this.lfo_value         += this.lfo_increment;
                    if ((--this.lfo_duration) == 0)
                    {
                        if (this.lfo_phase != 0)
                        {
                            this.lfo_phase     = 0;
                            this.lfo_value     = 0;
                            this.lfo_duration  = this.lfo_duration0;
                            this.lfo_increment = this.lfo_increment0;
                        }
                        else
                        {
                            this.lfo_phase     = 1;
                            this.lfo_value     = Constants.FP_SIZE;
                            this.lfo_duration  = this.lfo_duration1;
                            this.lfo_increment = this.lfo_increment1;
                        }
                    }
                }
                this.lfo_value_for_pitch = Inline.FP_TO_DOUBLE(this.lfo_value) * 2.0 - 1.0;      /* -FIX- this is still ramped for saw! */
                break;

            case 3:      /* square */
                for (sample = 0; sample < sample_count; sample++)
                {
                    this.lfo_buffer[sample] = this.lfo_value;
                    this.lfo_value         += this.lfo_increment;
                    if ((--this.lfo_duration) == 0)
                    {
                        switch (this.lfo_phase)
                        {
                        default:
                        case 0:
                            this.lfo_phase     = 1;
                            this.lfo_duration  = this.lfo_duration1;
                            this.lfo_increment = this.lfo_increment0;
                            break;

                        case 1:
                            this.lfo_phase     = 2;
                            this.lfo_value     = 0;
                            this.lfo_duration  = this.lfo_duration0;
                            this.lfo_increment = 0;
                            break;

                        case 2:
                            this.lfo_phase     = 3;
                            this.lfo_duration  = this.lfo_duration1;
                            this.lfo_increment = this.lfo_increment1;
                            break;

                        case 3:
                            this.lfo_phase     = 0;
                            this.lfo_value     = Constants.FP_SIZE;
                            this.lfo_duration  = this.lfo_duration0;
                            this.lfo_increment = 0;
                            break;
                        }
                    }
                }
                if (this.lfo_phase == 0 || this.lfo_phase == 3)
                {
                    this.lfo_value_for_pitch = 1.0;
                }
                else
                {
                    this.lfo_value_for_pitch = -1.0;
                }
                break;

            case 4:      /* sine */
                for (sample = 0; sample < sample_count; sample++)
                {
                    Int32 phase, index, outx;

                    phase = this.lfo_value;
                    index = (phase >> Constants.FP_TO_SINE_SHIFT) & Constants.SINE_MASK;
                    outx  = Data.dx7_voice_sin_table[index];
                    outx += (Int32)((((Int64)(Data.dx7_voice_sin_table[index + 1] - outx) *
                                      (Int64)(phase & Constants.FP_TO_SINE_MASK)) >>
                                     (Constants.FP_SHIFT + Constants.FP_TO_SINE_SHIFT)));
                    outx = (outx + Constants.FP_SIZE) >> 1;      /* shift to unipolar */
                    this.lfo_buffer[sample] = outx;
                    this.lfo_value         += this.lfo_increment;
                }
                this.lfo_value_for_pitch = Inline.FP_TO_DOUBLE(this.lfo_buffer[sample - 1]) * 2.0 - 1.0;
                break;

            case 5:      /* sample/hold */
                for (sample = 0; sample < sample_count; sample++)
                {
                    this.lfo_buffer[sample] = this.lfo_value;
                    this.lfo_value         += this.lfo_increment;
                    if ((--this.lfo_duration) == 0)
                    {
                        if (this.lfo_phase != 0)
                        {
                            this.lfo_phase     = 0;
                            this.lfo_value     = this.lfo_target;
                            this.lfo_duration  = this.lfo_duration0;
                            this.lfo_increment = 0;
                        }
                        else
                        {
                            this.lfo_phase     = 1;
                            this.lfo_duration  = this.lfo_duration1;
                            this.lfo_target    = StaticRandom.Next(Constants.FP_SIZE);
                            this.lfo_increment = (this.lfo_target - this.lfo_value) /
                                                 (Int32)this.lfo_duration;
                        }
                    }
                }
                this.lfo_value_for_pitch = Inline.FP_TO_DOUBLE(this.lfo_target) * 2.0 - 1.0;
                break;
            }
        }