94 Impl(
const std::string& name,
const std::string& desc,
95 const std::string& romFilename,
const DeviceConfig& config);
103 template<
typename Archive>
104 void serialize(Archive& ar,
unsigned version);
107 void setRST(
bool pin);
108 void setVCU(
bool pin);
109 void setST (
bool pin);
112 virtual void generateChannels(
int** bufs,
unsigned num);
114 void setupParameter(
byte param);
115 int getBits(
unsigned sbit,
unsigned bits);
118 std::unique_ptr<Rom> rom;
127 unsigned current_energy;
128 unsigned current_pitch;
160 static const int FR_SIZE = 4;
162 static const int IP_SIZE_SLOWER = 240 / FR_SIZE;
163 static const int IP_SIZE_SLOW = 200 / FR_SIZE;
164 static const int IP_SIZE_NORMAL = 160 / FR_SIZE;
165 static const int IP_SIZE_FAST = 120 / FR_SIZE;
166 static const int IP_SIZE_FASTER = 80 / FR_SIZE;
186 static const int VLM5030_speed_table[8] =
203 static word energytable[0x20] =
205 0, 2, 4, 6, 10, 12, 14, 18,
206 22, 26, 30, 34, 38, 44, 48, 54,
207 62, 68, 76, 84, 94,102,114,124,
208 136,150,164,178,196,214,232,254
212 static const byte pitchtable [0x20] =
216 23, 24, 25, 26, 27, 28, 29, 30,
217 32, 34, 36, 38, 40, 42, 44, 46,
218 50, 54, 58, 62, 66, 70, 74, 78,
219 86, 94, 102,110,118,126
223 -24898, -25672, -26446, -27091, -27736, -28252, -28768, -29155,
224 -29542, -29929, -30316, -30574, -30832, -30961, -31219, -31348,
225 -31606, -31735, -31864, -31864, -31993, -32122, -32122, -32251,
226 -32251, -32380, -32380, -32380, -32509, -32509, -32509, -32509,
227 24898, 23995, 22963, 21931, 20770, 19480, 18061, 16642,
228 15093, 13416, 11610, 9804, 7998, 6063, 3999, 1935,
229 0, -1935, -3999, -6063, -7998, -9804, -11610, -13416,
230 -15093, -16642, -18061, -19480, -20770, -21931, -22963, -23995
233 0, -3096, -6321, -9417, -12513, -15351, -18061, -20770,
234 -23092, -25285, -27220, -28897, -30187, -31348, -32122, -32638,
235 0, 32638, 32122, 31348, 30187, 28897, 27220, 25285,
236 23092, 20770, 18061, 15351, 12513, 9417, 6321, 3096
239 0, -3999, -8127, -12255, -16384, -20383, -24511, -28639,
240 32638, 28639, 24511, 20383, 16254, 12255, 8127, 3999
243 0, -8127, -16384, -24511, 32638, 24511, 16254, 8127
246 int VLM5030::Impl::getBits(
unsigned sbit,
unsigned bits)
248 unsigned offset = address + (sbit / 8);
249 unsigned data = (*rom)[(offset + 0) & address_mask] +
250 (*rom)[(offset + 1) & address_mask] * 256;
252 data &= (0xFF >> (8 - bits));
257 int VLM5030::Impl::parseFrame()
260 old_energy = new_energy;
261 old_pitch = new_pitch;
262 for (
int i = 0; i <= 9; ++i) {
266 byte cmd = (*rom)[address & address_mask];
269 new_energy = new_pitch = 0;
270 for (
int i = 0; i <= 9; ++i) {
279 int nums = ((cmd >> 2) + 1) * 2;
280 return nums * FR_SIZE;
284 new_pitch = (pitchtable[getBits(1, 5)] + pitch_offset) & 0xff;
286 new_energy = energytable[getBits(6, 5)];
289 new_k[9] = K5_table[getBits(11, 3)];
290 new_k[8] = K5_table[getBits(14, 3)];
291 new_k[7] = K5_table[getBits(17, 3)];
292 new_k[6] = K5_table[getBits(20, 3)];
293 new_k[5] = K5_table[getBits(23, 3)];
294 new_k[4] = K5_table[getBits(26, 3)];
295 new_k[3] = K3_table[getBits(29, 4)];
296 new_k[2] = K3_table[getBits(33, 4)];
297 new_k[1] = K2_table[getBits(37, 5)];
298 new_k[0] = K1_table[getBits(42, 6)];
305 void VLM5030::Impl::generateChannels(
int** bufs,
unsigned length)
320 if (sample_count == 0) {
326 sample_count = frame_size;
328 if (interp_count == 0) {
330 interp_count = parseFrame();
331 if (interp_count == 0 ) {
333 interp_count = FR_SIZE;
334 sample_count = frame_size;
338 current_energy = old_energy;
339 current_pitch = old_pitch;
340 for (
int i = 0; i <= 9; ++i) {
341 current_k[i] = old_k[i];
344 if (current_energy == 0) {
346 target_pitch = current_pitch;
347 for (
int i = 0; i <= 9; ++i) {
348 target_k[i] = current_k[i];
352 target_energy = new_energy;
353 target_pitch = new_pitch;
354 for (
int i = 0; i <= 9; ++i) {
355 target_k[i] = new_k[i];
361 interp_count -= interp_step;
363 int interp_effect = FR_SIZE - (interp_count % FR_SIZE);
364 current_energy = old_energy + (target_energy - old_energy) * interp_effect / FR_SIZE;
366 current_pitch = old_pitch + (target_pitch - old_pitch) * interp_effect / FR_SIZE;
368 for (
int i = 0; i <= 9; ++i)
369 current_k[i] = old_k[i] + (target_k[i] - old_k[i]) * interp_effect / FR_SIZE;
372 if (old_energy == 0) {
375 }
else if (old_pitch <= 1) {
377 current_val = (rand() & 1) ?
int(current_energy)
378 : -int(current_energy);
381 current_val = (pitch_count == 0) ? current_energy : 0;
387 for (
int i = 9; i >= 0; --i) {
388 u[i] = u[i + 1] - ((current_k[i] * x[i]) / 32768);
390 for (
int i = 9; i >= 1; --i) {
391 x[i] = x[i - 1] + ((current_k[i - 1] * u[i - 1]) / 32768);
397 bufs[0][buf_count] += 511 << 6;
398 }
else if (u[0] < -511) {
399 bufs[0][buf_count] += -511 << 6;
401 bufs[0][buf_count] += (u[0] << 6);
406 if (pitch_count >= current_pitch) {
416 if (sample_count <= length) {
421 sample_count -= length;
425 if (sample_count <= length) {
430 sample_count -= length;
441 void VLM5030::Impl::setupParameter(
byte param)
449 }
else if (param & 1) {
456 frame_size = VLM5030_speed_table[(param >> 3) & 7];
461 }
else if (param & 0x40) {
475 old_energy = old_pitch = 0;
476 new_energy = new_pitch = 0;
477 current_energy = current_pitch = 0;
478 target_energy = target_pitch = 0;
479 memset(old_k, 0,
sizeof(old_k));
480 memset(new_k, 0,
sizeof(new_k));
481 memset(current_k, 0,
sizeof(current_k));
482 memset(target_k, 0,
sizeof(target_k));
483 interp_count = sample_count = pitch_count = 0;
484 memset(x, 0,
sizeof(x));
486 setupParameter(0x00);
505 setRST((data & 0x01) != 0);
506 setVCU((data & 0x04) != 0);
507 setST ((data & 0x02) != 0);
511 void VLM5030::Impl::setRST(
bool pin)
516 setupParameter(latch_data);
529 void VLM5030::Impl::setVCU(
bool pin)
536 void VLM5030::Impl::setST(
bool pin)
547 vcu_addr_h = (int(latch_data) << 8) + 0x01;
552 address = (vcu_addr_h & 0xff00) + latch_data;
556 int table = (latch_data & 0xfe) + ((
int(latch_data) & 1) << 8);
557 address = (((*rom)[(table + 0) & address_mask]) << 8) |
558 (*rom)[(table + 1) & address_mask];
561 sample_count = frame_size;
562 interp_count = FR_SIZE;
578 const std::string& romFilename,
const DeviceConfig& config)
585 "sha1",
"4f36d139ee4baa7d5980f765de9895570ee05f40"));
589 "filename",
"keyboardmaster/voice.rom"));
590 voiceROMconfig.
addChild(std::move(romElement));
591 rom = make_unique<Rom>(
592 name +
" ROM",
"rom",
DeviceConfig(config, voiceROMconfig));
595 pin_RST = pin_ST = pin_VCU =
false;
601 address_mask = rom->getSize() - 1;
603 const int CLOCK_FREQ = 3579545;
604 double input = CLOCK_FREQ / 440.0;
615 template<
typename Archive>
618 ar.serialize(
"address_mask", address_mask);
619 ar.serialize(
"frame_size", frame_size);
620 ar.serialize(
"pitch_offset", pitch_offset);
621 ar.serialize(
"current_energy", current_energy);
622 ar.serialize(
"current_pitch", current_pitch);
623 ar.serialize(
"current_k", current_k);
624 ar.serialize(
"x", x);
625 ar.serialize(
"address", address);
626 ar.serialize(
"vcu_addr_h", vcu_addr_h);
627 ar.serialize(
"old_k", old_k);
628 ar.serialize(
"new_k", new_k);
629 ar.serialize(
"target_k", target_k);
630 ar.serialize(
"old_energy", old_energy);
631 ar.serialize(
"new_energy", new_energy);
632 ar.serialize(
"target_energy", target_energy);
633 ar.serialize(
"old_pitch", old_pitch);
634 ar.serialize(
"new_pitch", new_pitch);
635 ar.serialize(
"target_pitch", target_pitch);
636 ar.serialize(
"interp_step", interp_step);
637 ar.serialize(
"interp_count", interp_count);
638 ar.serialize(
"sample_count", sample_count);
639 ar.serialize(
"pitch_count", pitch_count);
640 ar.serialize(
"latch_data", latch_data);
641 ar.serialize(
"parameter", parameter);
642 ar.serialize(
"phase", phase);
643 ar.serialize(
"pin_BSY", pin_BSY);
644 ar.serialize(
"pin_ST", pin_ST);
645 ar.serialize(
"pin_VCU", pin_VCU);
646 ar.serialize(
"pin_RST", pin_RST);
653 const std::string& romFilename,
const DeviceConfig& config)
669 pimpl->writeData(data);
674 pimpl->writeControl(data, time);
679 return pimpl->getBSY(time);
682 template<
typename Archive>
685 pimpl->serialize(ar, version);