1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
ix!();

use crate::{
    DualDelay,
    DualDelayParam,
    DUAL_DELAY_MAX_DELAY_LENGTH,
};

impl DualDelay {

    pub fn instantize_all(&mut self) {
        self.time_l.instantize();
        self.time_r.instantize();
        self.feedback.instantize();
        self.crossfeed.instantize();
        self.mix.instantize();
        self.width.instantize();
        self.pan.instantize();
        self.hp.coeff_instantize();
        self.lp.coeff_instantize();
    }

    pub fn clear_buffers(&mut self) {
        self.buffer = Align16(Self::new_delay_buffer());
    }
}

impl Init for DualDelay {

    fn init(&mut self) {

        self.clear_buffers();

        self.wpos          = 0;
        self.lfophase      = 0.0;
        self.envf          = 0.0;
        self.lfo_val       = 0.0;
        self.lfo_direction = true;

        self.lp.suspend();
        self.hp.suspend();

        self.update();
        self.instantize_all();

        self.inithadtempo = true;

        // See issue #1444 and the fix for this stuff
        if self.time_unit.temposyncratio_inv() == 0.0 {
            self.inithadtempo = false;
        }
    }
}

impl DualDelay {

    pub fn new( 
        tuner:     &TunerHandle,
        tables:    &TablesHandle,
        srunit:    &SampleRateHandle,
        time_unit: &TimeUnitHandle) -> Self {

        Self {
            feedback:           Align16(LipolPs::new_with_blocksize(BLOCK_SIZE)),
            crossfeed:          Align16(LipolPs::new_with_blocksize(BLOCK_SIZE)),
            aligpan:            Align16(LipolPs::new()),
            pan:                Align16(LipolPs::new_with_blocksize(BLOCK_SIZE)),
            mix:                Align16(LipolPs::new_with_blocksize(BLOCK_SIZE)),
            width:              Align16(LipolPs::new()),
            buffer:             Align16(Self::new_delay_buffer()),
            ringout:            Ringout::blocks(10000000),
            params:             DualDelayParam::new_runtime(), 
            time_l:             Lag::<f32>::new(0.0001),
            time_r:             Lag::<f32>::new(0.0001),
            inithadtempo:       false,
            envf:               0.0,
            wpos:               0,
            lp:                 BiquadFilter::new(tuner,tables,srunit),
            hp:                 BiquadFilter::new(tuner,tables,srunit),
            lfophase:           0.0,
            lfo_val:            0.0,
            lfo_direction:      false,

            scratch_left:       ScratchChannel::<f32>::new(BLOCK_SIZE),
            scratch_right:      ScratchChannel::<f32>::new(BLOCK_SIZE),
            wetblock:           WetBlock2::<BLOCK_SIZE>::default(),

            time_unit:          time_unit.clone(),
            tables:             tables.clone(),
            tuner:              tuner.clone(),
            srunit:             srunit.clone(),
        }
    }

    #[inline] pub fn new_delay_buffer() -> A2d::<f32> {
        A2d::<f32>::zeros((2, DUAL_DELAY_MAX_DELAY_LENGTH + FIR_IPOL_N))
    }
}