1 module pxtone.delay; 2 3 import pxtone.pxtn; 4 5 import pxtone.descriptor; 6 import pxtone.error; 7 import pxtone.max; 8 9 enum DELAYUNIT { 10 Beat = 0, 11 Meas, 12 Second, 13 num, 14 } 15 16 // (12byte) ================= 17 struct _DELAYSTRUCT { 18 ushort unit; 19 ushort group; 20 float rate = 0.0; 21 float freq = 0.0; 22 } 23 24 struct pxtnDelay { 25 private: 26 bool _b_played = true; 27 DELAYUNIT _unit = DELAYUNIT.Beat; 28 int _group = 0; 29 float _rate = 33.0; 30 float _freq = 3.0f; 31 32 int _smp_num = 0; 33 int _offset = 0; 34 int[][pxtnMAX_CHANNEL] _bufs = null; 35 int _rate_s32 = 0; 36 37 public: 38 39 ~this() nothrow @system { 40 Tone_Release(); 41 } 42 43 DELAYUNIT get_unit() const nothrow @safe { 44 return _unit; 45 } 46 47 int get_group() const nothrow @safe { 48 return _group; 49 } 50 51 float get_rate() const nothrow @safe { 52 return _rate; 53 } 54 55 float get_freq() const nothrow @safe { 56 return _freq; 57 } 58 59 void Set(DELAYUNIT unit, float freq, float rate, int group) nothrow @safe { 60 _unit = unit; 61 _group = group; 62 _rate = rate; 63 _freq = freq; 64 } 65 66 bool get_played() const nothrow @safe { 67 return _b_played; 68 } 69 70 void set_played(bool b) nothrow @safe { 71 _b_played = b; 72 } 73 74 bool switch_played() nothrow @safe { 75 _b_played = !_b_played; 76 return _b_played; 77 } 78 79 void Tone_Release() nothrow @system { 80 _bufs = null; 81 _smp_num = 0; 82 } 83 84 void Tone_Ready(int beat_num, float beat_tempo, int sps) @system { 85 Tone_Release(); 86 87 scope(failure) { 88 Tone_Release(); 89 } 90 if (_freq && _rate) { 91 _offset = 0; 92 _rate_s32 = cast(int) _rate; // /100; 93 94 switch (_unit) { 95 case DELAYUNIT.Beat: 96 _smp_num = cast(int)(sps * 60 / beat_tempo / _freq); 97 break; 98 case DELAYUNIT.Meas: 99 _smp_num = cast(int)(sps * 60 * beat_num / beat_tempo / _freq); 100 break; 101 case DELAYUNIT.Second: 102 _smp_num = cast(int)(sps / _freq); 103 break; 104 default: 105 break; 106 } 107 108 for (int c = 0; c < pxtnMAX_CHANNEL; c++) { 109 _bufs[c] = new int[](_smp_num); 110 } 111 } 112 } 113 114 void Tone_Supple(int ch, int[] group_smps) nothrow @safe { 115 if (!_smp_num) { 116 return; 117 } 118 int a = _bufs[ch][_offset] * _rate_s32 / 100; 119 if (_b_played) { 120 group_smps[_group] += a; 121 } 122 _bufs[ch][_offset] = group_smps[_group]; 123 } 124 125 void Tone_Increment() nothrow @safe { 126 if (!_smp_num) { 127 return; 128 } 129 if (++_offset >= _smp_num) { 130 _offset = 0; 131 } 132 } 133 134 void Tone_Clear() nothrow @system { 135 if (!_smp_num) { 136 return; 137 } 138 int def = 0; // .. 139 for (int i = 0; i < pxtnMAX_CHANNEL; i++) { 140 _bufs[i][0 .. _smp_num] = def; 141 } 142 } 143 144 void Write(ref pxtnDescriptor p_doc) const @system { 145 _DELAYSTRUCT dela; 146 int size; 147 148 dela.unit = cast(ushort) _unit; 149 dela.group = cast(ushort) _group; 150 dela.rate = _rate; 151 dela.freq = _freq; 152 153 // dela ---------- 154 size = _DELAYSTRUCT.sizeof; 155 p_doc.w_asfile(size); 156 p_doc.w_asfile(dela); 157 } 158 159 void Read(ref pxtnDescriptor p_doc) @system { 160 _DELAYSTRUCT dela; 161 int size = 0; 162 163 p_doc.r(size); 164 p_doc.r(dela); 165 if (dela.unit >= DELAYUNIT.num) { 166 throw new PxtoneException("fmt unknown"); 167 } 168 169 _unit = cast(DELAYUNIT) dela.unit; 170 _freq = dela.freq; 171 _rate = dela.rate; 172 _group = dela.group; 173 174 if (_group >= pxtnMAX_TUNEGROUPNUM) { 175 _group = 0; 176 } 177 } 178 }