1 // license:BSD-3-Clause
2 // copyright-holders:Miguel Angel Horna
3 /*
4  * Yamaha YMW-258-F 'GEW8' (aka Sega 315-5560) emulation.
5  *
6  * by Miguel Angel Horna (ElSemi) for Model 2 Emulator and MAME.
7  * Information by R. Belmont and the YMF278B (OPL4) manual.
8  *
9  * voice registers:
10  * 0: Pan
11  * 1: Index of sample
12  * 2: LSB of pitch (low 2 bits seem unused so)
13  * 3: MSB of pitch (ooooppppppppppxx) (o=octave (4 bit signed), p=pitch (10 bits), x=unused?
14  * 4: voice control: top bit = 1 for key on, 0 for key off
15  * 5: bit 0: 0: interpolate volume changes, 1: direct set volume,
16       bits 1-7 = volume attenuate (0=max, 7f=min)
17  * 6: LFO frequency + Phase LFO depth
18  * 7: Amplitude LFO size
19  *
20  * The first sample ROM contains a variable length metadata table with 12
21  * bytes per instrument sample. This is very similar to the YMF278B 'OPL4'.
22  * This sample format might be derived from the one used by the older YM7138 'GEW6' chip.
23  *
24  * The first 3 bytes are the offset into the file (big endian). (0, 1, 2)
25  * The next 2 are the loop start point, in samples (big endian) (3, 4)
26  * The next 2 are the 2's complement negation of of the total number of samples (big endian) (5, 6)
27  * The next byte is LFO freq + depth (copied to reg 6 ?) (7, 8)
28  * The next 3 are envelope params (Attack, Decay1 and 2, sustain level, release, Key Rate Scaling) (9, 10, 11)
29  * The next byte is Amplitude LFO size (copied to reg 7 ?)
30  *
31  * TODO
32  * - http://dtech.lv/techarticles_yamaha_chips.html indicates FM and 12-bit sample support,
33  *   which we don't have yet.
34  */
35 
36 #include "emu.h"
37 #include "multipcm.h"
38 #include "wavwrite.h"
39 
40 ALLOW_SAVE_TYPE(multipcm_device::state_t); // allow save_item on a non-fundamental type
41 
42 /*******************************
43         ENVELOPE SECTION
44 *******************************/
45 
46 //Times are based on a 44100Hz timebase. It's adjusted to the actual sampling rate on startup
47 
48 const double multipcm_device::BASE_TIMES[64] = {
49 	0,          0,          0,          0,
50 	6222.95,    4978.37,    4148.66,    3556.01,
51 	3111.47,    2489.21,    2074.33,    1778.00,
52 	1555.74,    1244.63,    1037.19,    889.02,
53 	777.87,     622.31,     518.59,     444.54,
54 	388.93,     311.16,     259.32,     222.27,
55 	194.47,     155.60,     129.66,     111.16,
56 	97.23,      77.82,      64.85,      55.60,
57 	48.62,      38.91,      32.43,      27.80,
58 	24.31,      19.46,      16.24,      13.92,
59 	12.15,      9.75,       8.12,       6.98,
60 	6.08,       4.90,       4.08,       3.49,
61 	3.04,       2.49,       2.13,       1.90,
62 	1.72,       1.41,       1.18,       1.04,
63 	0.91,       0.73,       0.59,       0.50,
64 	0.45,       0.45,       0.45,       0.45
65 };
66 
67 const int32_t multipcm_device::VALUE_TO_CHANNEL[32] =
68 {
69 	0, 1, 2, 3, 4, 5, 6 , -1,
70 	7, 8, 9, 10,11,12,13, -1,
71 	14,15,16,17,18,19,20, -1,
72 	21,22,23,24,25,26,27, -1,
73 };
74 
75 constexpr uint32_t multipcm_device::TL_SHIFT;
76 constexpr uint32_t multipcm_device::EG_SHIFT;
77 
init_sample(sample_t * sample,uint32_t index)78 void multipcm_device::init_sample(sample_t *sample, uint32_t index)
79 {
80 	uint32_t address = index * 12;
81 
82 	sample->m_start = (read_byte(address) << 16) | (read_byte(address + 1) << 8) | read_byte(address + 2);
83 	sample->m_start &= 0x3fffff;
84 	sample->m_loop = (read_byte(address + 3) << 8) | read_byte(address + 4);
85 	sample->m_end = 0xffff - ((read_byte(address + 5) << 8) | read_byte(address + 6));
86 	sample->m_attack_reg = (read_byte(address + 8) >> 4) & 0xf;
87 	sample->m_decay1_reg = read_byte(address + 8) & 0xf;
88 	sample->m_decay2_reg = read_byte(address + 9) & 0xf;
89 	sample->m_decay_level = (read_byte(address + 9) >> 4) & 0xf;
90 	sample->m_release_reg = read_byte(address + 10) & 0xf;
91 	sample->m_key_rate_scale = (read_byte(address + 10) >> 4) & 0xf;
92 	sample->m_lfo_vibrato_reg = read_byte(address + 7);
93 	sample->m_lfo_amplitude_reg = read_byte(address + 11) & 0xf;
94 }
95 
envelope_generator_update(slot_t & slot)96 int32_t multipcm_device::envelope_generator_update(slot_t &slot)
97 {
98 	switch(slot.m_envelope_gen.m_state)
99 	{
100 		case state_t::ATTACK:
101 			slot.m_envelope_gen.m_volume += slot.m_envelope_gen.m_attack_rate;
102 			if (slot.m_envelope_gen.m_volume >= (0x3ff << EG_SHIFT))
103 			{
104 				slot.m_envelope_gen.m_state = state_t::DECAY1;
105 				if (slot.m_envelope_gen.m_decay1_rate >= (0x400 << EG_SHIFT)) //Skip DECAY1, go directly to DECAY2
106 				{
107 					slot.m_envelope_gen.m_state = state_t::DECAY2;
108 				}
109 				slot.m_envelope_gen.m_volume = 0x3ff << EG_SHIFT;
110 			}
111 			break;
112 		case state_t::DECAY1:
113 			slot.m_envelope_gen.m_volume -= slot.m_envelope_gen.m_decay1_rate;
114 			if (slot.m_envelope_gen.m_volume <= 0)
115 			{
116 				slot.m_envelope_gen.m_volume = 0;
117 			}
118 			if (slot.m_envelope_gen.m_volume >> EG_SHIFT <= (slot.m_envelope_gen.m_decay_level << 6))
119 			{
120 				slot.m_envelope_gen.m_state = state_t::DECAY2;
121 			}
122 			break;
123 		case state_t::DECAY2:
124 			slot.m_envelope_gen.m_volume -= slot.m_envelope_gen.m_decay2_rate;
125 			if (slot.m_envelope_gen.m_volume <= 0)
126 			{
127 				slot.m_envelope_gen.m_volume = 0;
128 			}
129 			break;
130 		case state_t::RELEASE:
131 			slot.m_envelope_gen.m_volume -= slot.m_envelope_gen.m_release_rate;
132 			if (slot.m_envelope_gen.m_volume <= 0)
133 			{
134 				slot.m_envelope_gen.m_volume = 0;
135 				slot.m_playing = false;
136 			}
137 			break;
138 		default:
139 			return 1 << TL_SHIFT;
140 	}
141 
142 	return m_linear_to_exp_volume[slot.m_envelope_gen.m_volume >> EG_SHIFT];
143 }
144 
get_rate(uint32_t * steps,uint32_t rate,uint32_t val)145 uint32_t multipcm_device::get_rate(uint32_t *steps, uint32_t rate, uint32_t val)
146 {
147 	int32_t r = 4 * val + rate;
148 	if (val == 0)
149 	{
150 		return steps[0];
151 	}
152 	if (val == 0xf)
153 	{
154 		return steps[0x3f];
155 	}
156 	if (r > 0x3f)
157 	{
158 		r = 0x3f;
159 	}
160 	return steps[r];
161 }
162 
envelope_generator_calc(slot_t & slot)163 void multipcm_device::envelope_generator_calc(slot_t &slot)
164 {
165 	int32_t octave = ((slot.m_regs[3] >> 4) - 1) & 0xf;
166 	if (octave & 8) {
167 		octave = octave - 16;
168 	}
169 
170 	int32_t rate;
171 	if (slot.m_sample.m_key_rate_scale != 0xf)
172 	{
173 		rate = (octave + slot.m_sample.m_key_rate_scale) * 2 + ((slot.m_regs[3] >> 3) & 1);
174 	}
175 	else
176 	{
177 		rate = 0;
178 	}
179 
180 	slot.m_envelope_gen.m_attack_rate = get_rate(m_attack_step.get(), rate, slot.m_sample.m_attack_reg);
181 	slot.m_envelope_gen.m_decay1_rate = get_rate(m_decay_release_step.get(), rate, slot.m_sample.m_decay1_reg);
182 	slot.m_envelope_gen.m_decay2_rate = get_rate(m_decay_release_step.get(), rate, slot.m_sample.m_decay2_reg);
183 	slot.m_envelope_gen.m_release_rate = get_rate(m_decay_release_step.get(), rate, slot.m_sample.m_release_reg);
184 	slot.m_envelope_gen.m_decay_level = 0xf - slot.m_sample.m_decay_level;
185 
186 }
187 
188 /*****************************
189         LFO  SECTION
190 *****************************/
191 
192 constexpr uint32_t multipcm_device::LFO_SHIFT;
193 
194 const float multipcm_device::LFO_FREQ[8] = // In Hertz
195 {
196 	0.168f,
197 	2.019f,
198 	3.196f,
199 	4.206f,
200 	5.215f,
201 	5.888f,
202 	6.224f,
203 	7.066f
204 };
205 
206 const float multipcm_device::PHASE_SCALE_LIMIT[8] = // In Cents
207 {
208 	0.0f,
209 	3.378f,
210 	5.065f,
211 	6.750f,
212 	10.114f,
213 	20.170f,
214 	40.180f,
215 	79.307f
216 };
217 
218 const float multipcm_device::AMPLITUDE_SCALE_LIMIT[8] = // In Decibels
219 {
220 	0.0f,
221 	0.4f,
222 	0.8f,
223 	1.5f,
224 	3.0f,
225 	6.0f,
226 	12.0f,
227 	24.0f
228 };
229 
lfo_init()230 void multipcm_device::lfo_init()
231 {
232 	m_pitch_table = make_unique_clear<int32_t[]>(256);
233 	m_amplitude_table = make_unique_clear<int32_t[]>(256);
234 	for (int32_t i = 0; i < 256; ++i)
235 	{
236 		if (i < 64)
237 		{
238 			m_pitch_table[i] = i * 2 + 128;
239 		}
240 		else if (i < 128)
241 		{
242 			m_pitch_table[i] = 383 - i * 2;
243 		}
244 		else if (i < 192)
245 		{
246 			m_pitch_table[i] = 384 - i * 2;
247 		}
248 		else
249 		{
250 			m_pitch_table[i] = i * 2 - 383;
251 		}
252 
253 		if (i < 128)
254 		{
255 			m_amplitude_table[i] = 255 - (i * 2);
256 		}
257 		else
258 		{
259 			m_amplitude_table[i] = (i * 2) - 256;
260 		}
261 	}
262 
263 	for (int32_t table = 0; table < 8; ++table)
264 	{
265 		float limit = PHASE_SCALE_LIMIT[table];
266 		m_pitch_scale_tables[table] = make_unique_clear<int32_t[]>(256);
267 		for(int32_t i = -128; i < 128; ++i)
268 		{
269 			const float value = (limit * (float)i) / 128.0f;
270 			const float converted = powf(2.0f, value / 1200.0f);
271 			m_pitch_scale_tables[table][i + 128] = value_to_fixed(LFO_SHIFT, converted);
272 		}
273 
274 		limit = -AMPLITUDE_SCALE_LIMIT[table];
275 		m_amplitude_scale_tables[table] = make_unique_clear<int32_t[]>(256);
276 		for(int32_t i = 0; i < 256; ++i)
277 		{
278 			const float value = (limit * (float)i) / 256.0f;
279 			const float converted = powf(10.0f, value / 20.0f);
280 			m_amplitude_scale_tables[table][i] = value_to_fixed(LFO_SHIFT, converted);
281 		}
282 	}
283 }
284 
value_to_fixed(const uint32_t bits,const float value)285 uint32_t multipcm_device::value_to_fixed(const uint32_t bits, const float value)
286 {
287 	const float float_shift = float(1 << bits);
288 	return uint32_t(float_shift * value);
289 }
290 
pitch_lfo_step(lfo_t & lfo)291 int32_t multipcm_device::pitch_lfo_step(lfo_t &lfo)
292 {
293 	lfo.m_phase += lfo.m_phase_step;
294 	int32_t p = lfo.m_table[(lfo.m_phase >> LFO_SHIFT) & 0xff];
295 	p = lfo.m_scale[p];
296 	return p << (TL_SHIFT - LFO_SHIFT);
297 }
298 
amplitude_lfo_step(lfo_t & lfo)299 int32_t multipcm_device::amplitude_lfo_step(lfo_t &lfo)
300 {
301 	lfo.m_phase += lfo.m_phase_step;
302 	int32_t p = lfo.m_table[(lfo.m_phase >> LFO_SHIFT) & 0xff];
303 	p = lfo.m_scale[p];
304 	return p << (TL_SHIFT - LFO_SHIFT);
305 }
306 
lfo_compute_step(lfo_t & lfo,uint32_t lfo_frequency,uint32_t lfo_scale,int32_t amplitude_lfo)307 void multipcm_device::lfo_compute_step(lfo_t &lfo, uint32_t lfo_frequency, uint32_t lfo_scale, int32_t amplitude_lfo)
308 {
309 	float step = (float)LFO_FREQ[lfo_frequency] * 256.0f / (float)m_rate;
310 	lfo.m_phase_step = uint32_t(float(1 << LFO_SHIFT) * step);
311 	if (amplitude_lfo)
312 	{
313 		lfo.m_table = m_amplitude_table.get();
314 		lfo.m_scale = m_amplitude_scale_tables[lfo_scale].get();
315 	}
316 	else
317 	{
318 		lfo.m_table = m_pitch_table.get();
319 		lfo.m_scale = m_pitch_scale_tables[lfo_scale].get();
320 	}
321 }
322 
write_slot(slot_t & slot,int32_t reg,uint8_t data)323 void multipcm_device::write_slot(slot_t &slot, int32_t reg, uint8_t data)
324 {
325 	slot.m_regs[reg] = data;
326 
327 	switch(reg)
328 	{
329 		case 0: // PANPOT
330 			slot.m_pan = (data >> 4) & 0xf;
331 			break;
332 		case 1: // Sample
333 		{
334 			//according to YMF278 sample write causes some base params written to the regs (envelope+lfos)
335 			//the game should never change the sample while playing.
336 			sample_t sample;
337 			init_sample(&sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8));
338 			write_slot(slot, 6, sample.m_lfo_vibrato_reg);
339 			write_slot(slot, 7, sample.m_lfo_amplitude_reg);
340 			break;
341 		}
342 		case 2: //Pitch
343 		case 3:
344 			{
345 				uint32_t oct = ((slot.m_regs[3] >> 4) - 1) & 0xf;
346 				uint32_t pitch = ((slot.m_regs[3] & 0xf) << 6) | (slot.m_regs[2] >> 2);
347 				pitch = m_freq_step_table[pitch];
348 				if (oct & 0x8)
349 				{
350 					pitch >>= (16 - oct);
351 				}
352 				else
353 				{
354 					pitch <<= oct;
355 				}
356 				slot.m_step = pitch / m_rate;
357 			}
358 			break;
359 		case 4:     //KeyOn/Off (and more?)
360 			if (data & 0x80)       //KeyOn
361 			{
362 				init_sample(&slot.m_sample, slot.m_regs[1] | ((slot.m_regs[2] & 1) << 8));
363 				slot.m_playing = true;
364 				slot.m_base = slot.m_sample.m_start;
365 				slot.m_offset = 0;
366 				slot.m_prev_sample = 0;
367 				slot.m_total_level = slot.m_dest_total_level << TL_SHIFT;
368 
369 				envelope_generator_calc(slot);
370 				slot.m_envelope_gen.m_state = state_t::ATTACK;
371 				slot.m_envelope_gen.m_volume = 0;
372 
373 #if MULTIPCM_LOG_SAMPLES
374 				dump_sample(slot);
375 #endif
376 			}
377 			else
378 			{
379 				if (slot.m_playing)
380 				{
381 					if (slot.m_sample.m_release_reg != 0xf)
382 					{
383 						slot.m_envelope_gen.m_state = state_t::RELEASE;
384 					}
385 					else
386 					{
387 						slot.m_playing = false;
388 					}
389 				}
390 			}
391 			break;
392 		case 5: // TL + Interpolation
393 			slot.m_dest_total_level = (data >> 1) & 0x7f;
394 			if (!(data & 1))   //Interpolate TL
395 			{
396 				if ((slot.m_total_level >> TL_SHIFT) > slot.m_dest_total_level)
397 				{
398 					slot.m_total_level_step = m_total_level_steps[0]; // decrease
399 				}
400 				else
401 				{
402 					slot.m_total_level_step = m_total_level_steps[1]; // increase
403 				}
404 			}
405 			else
406 			{
407 				slot.m_total_level = slot.m_dest_total_level << TL_SHIFT;
408 			}
409 			break;
410 		case 6: // LFO frequency + Pitch LFO
411 			if (data)
412 			{
413 				lfo_compute_step(slot.m_pitch_lfo, (slot.m_regs[6] >> 3) & 7, slot.m_regs[6] & 7, 0);
414 				lfo_compute_step(slot.m_amplitude_lfo, (slot.m_regs[6] >> 3) & 7, slot.m_regs[7] & 7, 1);
415 			}
416 			break;
417 		case 7: // Amplitude LFO
418 			if (data)
419 			{
420 				lfo_compute_step(slot.m_pitch_lfo, (slot.m_regs[6] >> 3) & 7, slot.m_regs[6] & 7, 0);
421 				lfo_compute_step(slot.m_amplitude_lfo, (slot.m_regs[6] >> 3) & 7, slot.m_regs[7] & 7, 1);
422 			}
423 			break;
424 	}
425 }
426 
read()427 uint8_t multipcm_device::read()
428 {
429 	return 0;
430 }
431 
write(offs_t offset,uint8_t data)432 void multipcm_device::write(offs_t offset, uint8_t data)
433 {
434 	switch(offset)
435 	{
436 		case 0:     //Data write
437 			write_slot(m_slots[m_cur_slot], m_address, data);
438 			break;
439 		case 1:
440 			m_cur_slot = VALUE_TO_CHANNEL[data & 0x1f];
441 			break;
442 
443 		case 2:
444 			m_address = (data > 7) ? 7 : data;
445 			break;
446 	}
447 }
448 
449 /* MAME/M1 access functions */
450 
451 DEFINE_DEVICE_TYPE(MULTIPCM, multipcm_device, "ymw258f", "Yamaha YMW-258-F")
452 
multipcm_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)453 multipcm_device::multipcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
454 	device_t(mconfig, MULTIPCM, tag, owner, clock),
455 	device_sound_interface(mconfig, *this),
456 	device_rom_interface(mconfig, *this),
457 	m_stream(nullptr),
458 	m_slots(nullptr),
459 	m_cur_slot(0),
460 	m_address(0),
461 	m_rate(0),
462 	m_attack_step(nullptr),
463 	m_decay_release_step(nullptr),
464 	m_freq_step_table(nullptr),
465 	m_left_pan_table(nullptr),
466 	m_right_pan_table(nullptr),
467 	m_linear_to_exp_volume(nullptr),
468 	m_total_level_steps(nullptr)
469 {
470 }
471 
472 
473 //-------------------------------------------------
474 //  device_start - device-specific startup
475 //-------------------------------------------------
476 
device_start()477 void multipcm_device::device_start()
478 {
479 	const float clock_divider = 180.0f;
480 	m_rate = (float)clock() / clock_divider;
481 
482 	m_stream = stream_alloc(0, 2, m_rate);
483 
484 	// Volume + pan table
485 	m_left_pan_table = make_unique_clear<int32_t[]>(0x800);
486 	m_right_pan_table = make_unique_clear<int32_t[]>(0x800);
487 	for (int32_t level = 0; level < 0x80; ++level)
488 	{
489 		const float vol_db = (float)level * (-24.0f) / 64.0f;
490 		const float total_level = powf(10.0f, vol_db / 20.0f) / 4.0f;
491 
492 		for (int32_t pan = 0; pan < 0x10; ++pan)
493 		{
494 			float pan_left, pan_right;
495 			if (pan == 0x8)
496 			{
497 				pan_left = 0.0;
498 				pan_right = 0.0;
499 			}
500 			else if (pan == 0x0)
501 			{
502 				pan_left = 1.0;
503 				pan_right = 1.0;
504 			}
505 			else if (pan & 0x8)
506 			{
507 				pan_left = 1.0;
508 
509 				const int32_t inverted_pan = 0x10 - pan;
510 				const float pan_vol_db = (float)inverted_pan * (-12.0f) / 4.0f;
511 
512 				pan_right = pow(10.0f, pan_vol_db / 20.0f);
513 
514 				if ((inverted_pan & 0x7) == 7)
515 				{
516 					pan_right = 0.0;
517 				}
518 			}
519 			else
520 			{
521 				pan_right = 1.0;
522 
523 				const float pan_vol_db = (float)pan * (-12.0f) / 4.0f;
524 
525 				pan_left = pow(10.0f, pan_vol_db / 20.0f);
526 
527 				if ((pan & 0x7) == 7)
528 				{
529 					pan_left = 0.0;
530 				}
531 			}
532 
533 			m_left_pan_table[(pan << 7) | level] = value_to_fixed(TL_SHIFT, pan_left * total_level);
534 			m_right_pan_table[(pan << 7) | level] = value_to_fixed(TL_SHIFT, pan_right * total_level);
535 		}
536 	}
537 
538 	//Pitch steps
539 	m_freq_step_table = make_unique_clear<uint32_t[]>(0x400);
540 	for (int32_t i = 0; i < 0x400; ++i)
541 	{
542 		const float fcent = m_rate * (1024.0f + (float)i) / 1024.0f;
543 		m_freq_step_table[i] = value_to_fixed(TL_SHIFT, fcent);
544 	}
545 
546 	// Envelope steps
547 	m_attack_step = make_unique_clear<uint32_t[]>(0x40);
548 	m_decay_release_step = make_unique_clear<uint32_t[]>(0x40);
549 	const double attack_rate_to_decay_rate = 14.32833;
550 	for (int32_t i = 4; i < 0x40; ++i)
551 	{
552 		// Times are based on 44100Hz clock, adjust to real chip clock
553 		m_attack_step[i] = (float)(0x400 << EG_SHIFT) / (float)(BASE_TIMES[i] * 44100.0 / 1000.0);
554 		m_decay_release_step[i] = (float)(0x400 << EG_SHIFT) / (float)(BASE_TIMES[i] * attack_rate_to_decay_rate * 44100.0 / 1000.0);
555 	}
556 	m_attack_step[0] = m_attack_step[1] = m_attack_step[2] = m_attack_step[3] = 0;
557 	m_attack_step[0x3f] = 0x400 << EG_SHIFT;
558 	m_decay_release_step[0] = m_decay_release_step[1] = m_decay_release_step[2] = m_decay_release_step[3] = 0;
559 
560 	// Total level interpolation steps
561 	m_total_level_steps = make_unique_clear<int32_t[]>(2);
562 	m_total_level_steps[0] = -(float)(0x80 << TL_SHIFT) / (78.2f * 44100.0f / 1000.0f); // lower
563 	m_total_level_steps[1] = (float)(0x80 << TL_SHIFT) / (78.2f * 2 * 44100.0f / 1000.0f); // raise
564 
565 	// build the linear->exponential ramps
566 	m_linear_to_exp_volume = make_unique_clear<int32_t[]>(0x400);
567 	for(int32_t i = 0; i < 0x400; ++i)
568 	{
569 		const float db = -(96.0f - (96.0f * (float)i / (float)0x400));
570 		const float exp_volume = powf(10.0f, db / 20.0f);
571 		m_linear_to_exp_volume[i] = value_to_fixed(TL_SHIFT, exp_volume);
572 	}
573 
574 	save_item(NAME(m_cur_slot));
575 	save_item(NAME(m_address));
576 
577 	// Slots
578 	m_slots = std::make_unique<slot_t []>(28);
579 
580 	save_pointer(STRUCT_MEMBER(m_slots, m_regs), 28);
581 	save_pointer(STRUCT_MEMBER(m_slots, m_playing), 28);
582 	save_pointer(STRUCT_MEMBER(m_slots, m_base), 28);
583 	save_pointer(STRUCT_MEMBER(m_slots, m_offset), 28);
584 	save_pointer(STRUCT_MEMBER(m_slots, m_step), 28);
585 	save_pointer(STRUCT_MEMBER(m_slots, m_pan), 28);
586 	save_pointer(STRUCT_MEMBER(m_slots, m_total_level), 28);
587 	save_pointer(STRUCT_MEMBER(m_slots, m_dest_total_level), 28);
588 	save_pointer(STRUCT_MEMBER(m_slots, m_total_level_step), 28);
589 	save_pointer(STRUCT_MEMBER(m_slots, m_prev_sample), 28);
590 
591 	for (int32_t slot = 0; slot < 28; ++slot)
592 	{
593 		m_slots[slot].m_playing = false;
594 
595 		save_item(NAME(m_slots[slot].m_envelope_gen.m_volume), slot);
596 		save_item(NAME(m_slots[slot].m_envelope_gen.m_state), slot);
597 		save_item(NAME(m_slots[slot].m_envelope_gen.step), slot);
598 		save_item(NAME(m_slots[slot].m_envelope_gen.m_attack_rate), slot);
599 		save_item(NAME(m_slots[slot].m_envelope_gen.m_decay1_rate), slot);
600 		save_item(NAME(m_slots[slot].m_envelope_gen.m_decay2_rate), slot);
601 		save_item(NAME(m_slots[slot].m_envelope_gen.m_release_rate), slot);
602 		save_item(NAME(m_slots[slot].m_envelope_gen.m_decay_level), slot);
603 		save_item(NAME(m_slots[slot].m_pitch_lfo.m_phase), slot);
604 		save_item(NAME(m_slots[slot].m_pitch_lfo.m_phase_step), slot);
605 		save_item(NAME(m_slots[slot].m_amplitude_lfo.m_phase), slot);
606 		save_item(NAME(m_slots[slot].m_amplitude_lfo.m_phase_step), slot);
607 	}
608 
609 	lfo_init();
610 }
611 
612 //-------------------------------------------------
613 //  device_clock_changed - called if the clock
614 //  changes
615 //-------------------------------------------------
616 
device_clock_changed()617 void multipcm_device::device_clock_changed()
618 {
619 	const float clock_divider = 180.0f;
620 	m_rate = (float)clock() / clock_divider;
621 	m_stream->set_sample_rate(m_rate);
622 
623 	for (int32_t i = 0; i < 0x400; ++i)
624 	{
625 		const float fcent = m_rate * (1024.0f + (float)i) / 1024.0f;
626 		m_freq_step_table[i] = value_to_fixed(TL_SHIFT, fcent);
627 	}
628 }
629 
630 //-----------------------------------------------------
631 //  convert_to_stream_sample - clamp a 32-bit value to
632 //  16 bits and convert to a stream_buffer::sample_t
633 //-----------------------------------------------------
634 
635 #if MULTIPCM_LOG_SAMPLES
dump_sample(slot_t & slot)636 void multipcm_device::dump_sample(slot_t &slot)
637 {
638 	if (m_logged_map[slot.m_base])
639 		return;
640 
641 	m_logged_map[slot.m_base] = true;
642 
643 	char filebuf[256];
644 	snprintf(filebuf, 256, "multipcm%08x.wav", slot.m_base);
645 	wav_file *file = wav_open(filebuf, m_stream->sample_rate(), 1);
646 	if (file == nullptr)
647 		return;
648 
649 	uint32_t offset = slot.m_offset;
650 	bool done = false;
651 	while (!done)
652 	{
653 		int16_t sample = (int16_t) (read_byte(slot.m_base + (offset >> TL_SHIFT)) << 8);
654 		wav_add_data_16(file, &sample, 1);
655 
656 		offset += 1 << TL_SHIFT;
657 		if (offset >= (slot.m_sample.m_end << TL_SHIFT))
658 		{
659 			done = true;
660 		}
661 	}
662 
663 	wav_close(file);
664 }
665 #endif
666 
667 //-------------------------------------------------
668 //  sound_stream_update - handle a stream update
669 //-------------------------------------------------
670 
sound_stream_update(sound_stream & stream,std::vector<read_stream_view> const & inputs,std::vector<write_stream_view> & outputs)671 void multipcm_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
672 {
673 	for (int32_t i = 0; i < outputs[0].samples(); ++i)
674 	{
675 		int32_t smpl = 0;
676 		int32_t smpr = 0;
677 		for (int32_t sl = 0; sl < 28; ++sl)
678 		{
679 			slot_t &slot = m_slots[sl];
680 			if (slot.m_playing)
681 			{
682 				uint32_t vol = (slot.m_total_level >> TL_SHIFT) | (slot.m_pan << 7);
683 				uint32_t adr = slot.m_offset >> TL_SHIFT;
684 				uint32_t step = slot.m_step;
685 				int32_t csample = (int16_t) (read_byte(slot.m_base + adr) << 8);
686 				int32_t fpart = slot.m_offset & ((1 << TL_SHIFT) - 1);
687 				int32_t sample = (csample * fpart + slot.m_prev_sample * ((1 << TL_SHIFT) - fpart)) >> TL_SHIFT;
688 
689 				if (slot.m_regs[6] & 7) // Vibrato enabled
690 				{
691 					step = step * pitch_lfo_step(slot.m_pitch_lfo);
692 					step >>= TL_SHIFT;
693 				}
694 
695 				slot.m_offset += step;
696 				if (slot.m_offset >= (slot.m_sample.m_end << TL_SHIFT))
697 				{
698 					slot.m_offset = slot.m_sample.m_loop << TL_SHIFT;
699 				}
700 
701 				if (adr ^ (slot.m_offset >> TL_SHIFT))
702 				{
703 					slot.m_prev_sample = csample;
704 				}
705 
706 				if ((slot.m_total_level >> TL_SHIFT) != slot.m_dest_total_level)
707 				{
708 					slot.m_total_level += slot.m_total_level_step;
709 				}
710 
711 				if (slot.m_regs[7] & 7) // Tremolo enabled
712 				{
713 					sample = sample * amplitude_lfo_step(slot.m_amplitude_lfo);
714 					sample >>= TL_SHIFT;
715 				}
716 
717 				sample = (sample * envelope_generator_update(slot)) >> 10;
718 
719 				smpl += (m_left_pan_table[vol] * sample) >> TL_SHIFT;
720 				smpr += (m_right_pan_table[vol] * sample) >> TL_SHIFT;
721 			}
722 		}
723 
724 		outputs[0].put_int_clamp(i, smpl, 32768);
725 		outputs[1].put_int_clamp(i, smpr, 32768);
726 	}
727 }
728 
729 
730 //-------------------------------------------------
731 //  rom_bank_updated - the rom bank has changed
732 //-------------------------------------------------
733 
rom_bank_updated()734 void multipcm_device::rom_bank_updated()
735 {
736 	m_stream->update();
737 }
738