1 module pxtone.master; 2 // '12/03/03 3 4 import pxtone.pxtn; 5 6 import pxtone.descriptor; 7 import pxtone.error; 8 import pxtone.evelist; 9 import pxtone.util; 10 11 ///////////////////////////////// 12 // file io 13 ///////////////////////////////// 14 15 // master info(8byte) ================ 16 struct _x4x_MASTER { 17 ushort data_num; // data-num is 3 ( clock / status / volume ) 18 ushort rrr; 19 uint event_num; 20 } 21 22 struct pxtnMaster { 23 private: 24 int _beat_num = EVENTDEFAULT_BEATNUM; 25 float _beat_tempo = EVENTDEFAULT_BEATTEMPO; 26 int _beat_clock = EVENTDEFAULT_BEATCLOCK; 27 int _meas_num = 1; 28 int _repeat_meas; 29 int _last_meas; 30 int _volume_; 31 32 public: 33 void Reset() nothrow @safe { 34 _beat_num = EVENTDEFAULT_BEATNUM; 35 _beat_tempo = EVENTDEFAULT_BEATTEMPO; 36 _beat_clock = EVENTDEFAULT_BEATCLOCK; 37 _meas_num = 1; 38 _repeat_meas = 0; 39 _last_meas = 0; 40 } 41 42 void Set(int beat_num, float beat_tempo, int beat_clock) nothrow @safe { 43 _beat_num = beat_num; 44 _beat_tempo = beat_tempo; 45 _beat_clock = beat_clock; 46 } 47 48 void Get(int* p_beat_num, float* p_beat_tempo, int* p_beat_clock, int* p_meas_num) const nothrow @safe { 49 if (p_beat_num) { 50 *p_beat_num = _beat_num; 51 } 52 if (p_beat_tempo) { 53 *p_beat_tempo = _beat_tempo; 54 } 55 if (p_beat_clock) { 56 *p_beat_clock = _beat_clock; 57 } 58 if (p_meas_num) { 59 *p_meas_num = _meas_num; 60 } 61 } 62 63 int get_beat_num() const nothrow @safe { 64 return _beat_num; 65 } 66 67 float get_beat_tempo() const nothrow @safe { 68 return _beat_tempo; 69 } 70 71 int get_beat_clock() const nothrow @safe { 72 return _beat_clock; 73 } 74 75 int get_meas_num() const nothrow @safe { 76 return _meas_num; 77 } 78 79 int get_repeat_meas() const nothrow @safe { 80 return _repeat_meas; 81 } 82 83 int get_last_meas() const nothrow @safe { 84 return _last_meas; 85 } 86 87 int get_last_clock() const nothrow @safe { 88 return _last_meas * _beat_clock * _beat_num; 89 } 90 91 int get_play_meas() const nothrow @safe { 92 if (_last_meas) { 93 return _last_meas; 94 } 95 return _meas_num; 96 } 97 98 void set_meas_num(int meas_num) nothrow @safe { 99 if (meas_num < 1) { 100 meas_num = 1; 101 } 102 if (meas_num <= _repeat_meas) { 103 meas_num = _repeat_meas + 1; 104 } 105 if (meas_num < _last_meas) { 106 meas_num = _last_meas; 107 } 108 _meas_num = meas_num; 109 } 110 111 void set_repeat_meas(int meas) nothrow @safe { 112 if (meas < 0) { 113 meas = 0; 114 } 115 _repeat_meas = meas; 116 } 117 118 void set_last_meas(int meas) nothrow @safe { 119 if (meas < 0) { 120 meas = 0; 121 } 122 _last_meas = meas; 123 } 124 125 void set_beat_clock(int beat_clock) nothrow @safe { 126 if (beat_clock < 0) { 127 beat_clock = 0; 128 } 129 _beat_clock = beat_clock; 130 } 131 132 void AdjustMeasNum(int clock) nothrow @safe { 133 int m_num; 134 int b_num; 135 136 b_num = (clock + _beat_clock - 1) / _beat_clock; 137 m_num = (b_num + _beat_num - 1) / _beat_num; 138 if (_meas_num <= m_num) { 139 _meas_num = m_num; 140 } 141 if (_repeat_meas >= _meas_num) { 142 _repeat_meas = 0; 143 } 144 if (_last_meas > _meas_num) { 145 _last_meas = _meas_num; 146 } 147 } 148 149 int get_this_clock(int meas, int beat, int clock) const nothrow @safe { 150 return _beat_num * _beat_clock * meas + _beat_clock * beat + clock; 151 } 152 153 void io_w_v5(ref pxtnDescriptor p_doc, int rough) const @safe { 154 155 uint size = 15; 156 short bclock = cast(short)(_beat_clock / rough); 157 int clock_repeat = bclock * _beat_num * get_repeat_meas(); 158 int clock_last = bclock * _beat_num * get_last_meas(); 159 byte bnum = cast(byte) _beat_num; 160 float btempo = _beat_tempo; 161 p_doc.w_asfile(size); 162 p_doc.w_asfile(bclock); 163 p_doc.w_asfile(bnum); 164 p_doc.w_asfile(btempo); 165 p_doc.w_asfile(clock_repeat); 166 p_doc.w_asfile(clock_last); 167 } 168 169 void io_r_v5(ref pxtnDescriptor p_doc) @safe { 170 short beat_clock = 0; 171 byte beat_num = 0; 172 float beat_tempo = 0; 173 int clock_repeat = 0; 174 int clock_last = 0; 175 176 uint size = 0; 177 178 p_doc.r(size); 179 if (size != 15) { 180 throw new PxtoneException("fmt unknown"); 181 } 182 183 p_doc.r(beat_clock); 184 p_doc.r(beat_num); 185 p_doc.r(beat_tempo); 186 p_doc.r(clock_repeat); 187 p_doc.r(clock_last); 188 189 _beat_clock = beat_clock; 190 _beat_num = beat_num; 191 _beat_tempo = beat_tempo; 192 193 set_repeat_meas(clock_repeat / (beat_num * beat_clock)); 194 set_last_meas(clock_last / (beat_num * beat_clock)); 195 } 196 197 int io_r_v5_EventNum(ref pxtnDescriptor p_doc) @safe { 198 uint size; 199 p_doc.r(size); 200 if (size != 15) { 201 return 0; 202 } 203 byte[15] buf; 204 p_doc.r(buf[]); 205 return 5; 206 } 207 208 void io_r_x4x(ref pxtnDescriptor p_doc) @safe { 209 _x4x_MASTER mast; 210 int size = 0; 211 int e = 0; 212 int status = 0; 213 int clock = 0; 214 int volume = 0; 215 int absolute = 0; 216 217 int beat_clock, beat_num, repeat_clock, last_clock; 218 float beat_tempo = 0; 219 220 p_doc.r(size); 221 p_doc.r(mast); 222 223 // unknown format 224 if (mast.data_num != 3) { 225 throw new PxtoneException("fmt unknown"); 226 } 227 if (mast.rrr) { 228 throw new PxtoneException("fmt unknown"); 229 } 230 231 beat_clock = EVENTDEFAULT_BEATCLOCK; 232 beat_num = EVENTDEFAULT_BEATNUM; 233 beat_tempo = EVENTDEFAULT_BEATTEMPO; 234 repeat_clock = 0; 235 last_clock = 0; 236 237 absolute = 0; 238 239 for (e = 0; e < cast(int) mast.event_num; e++) { 240 p_doc.v_r(status); 241 p_doc.v_r(clock); 242 p_doc.v_r(volume); 243 absolute += clock; 244 clock = absolute; 245 246 switch (status) { 247 case EVENTKIND.BEATCLOCK: 248 beat_clock = volume; 249 if (clock) { 250 throw new PxtoneException("desc broken"); 251 } 252 break; 253 case EVENTKIND.BEATTEMPO: 254 beat_tempo = reinterpretInt(volume); 255 if (clock) { 256 throw new PxtoneException("desc broken"); 257 } 258 break; 259 case EVENTKIND.BEATNUM: 260 beat_num = volume; 261 if (clock) { 262 throw new PxtoneException("desc broken"); 263 } 264 break; 265 case EVENTKIND.REPEAT: 266 repeat_clock = clock; 267 if (volume) { 268 throw new PxtoneException("desc broken"); 269 } 270 break; 271 case EVENTKIND.LAST: 272 last_clock = clock; 273 if (volume) { 274 throw new PxtoneException("desc broken"); 275 } 276 break; 277 default: 278 throw new PxtoneException("fmt unknown"); 279 } 280 } 281 282 if (e != mast.event_num) { 283 throw new PxtoneException("desc broken"); 284 } 285 286 _beat_num = beat_num; 287 _beat_tempo = beat_tempo; 288 _beat_clock = beat_clock; 289 290 set_repeat_meas(repeat_clock / (beat_num * beat_clock)); 291 set_last_meas(last_clock / (beat_num * beat_clock)); 292 } 293 294 int io_r_x4x_EventNum(ref pxtnDescriptor p_doc) @safe { 295 _x4x_MASTER mast; 296 int size; 297 int work; 298 int e; 299 300 p_doc.r(size); 301 p_doc.r(mast); 302 303 if (mast.data_num != 3) { 304 return 0; 305 } 306 307 for (e = 0; e < cast(int) mast.event_num; e++) { 308 p_doc.v_r(work); 309 p_doc.v_r(work); 310 p_doc.v_r(work); 311 } 312 313 return mast.event_num; 314 } 315 }