1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     sound.cpp
6 
7     Core sound functions and definitions.
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "speaker.h"
13 #include "emuopts.h"
14 #include "osdepend.h"
15 #include "config.h"
16 #include "wavwrite.h"
17 
18 
19 
20 //**************************************************************************
21 //  DEBUGGING
22 //**************************************************************************
23 
24 #define VERBOSE         (0)
25 
26 #define VPRINTF(x)      do { if (VERBOSE) osd_printf_debug x; } while (0)
27 
28 #define LOG_OUTPUT_WAV  (0)
29 
30 
31 
32 //**************************************************************************
33 //  CONSTANTS
34 //**************************************************************************
35 
36 
37 
38 //**************************************************************************
39 //  GLOBAL VARIABLES
40 //**************************************************************************
41 
42 const attotime sound_manager::STREAMS_UPDATE_ATTOTIME = attotime::from_hz(STREAMS_UPDATE_FREQUENCY);
43 
44 
45 
46 //**************************************************************************
47 //  STREAM BUFFER
48 //**************************************************************************
49 
50 //-------------------------------------------------
51 //  stream_buffer - constructor
52 //-------------------------------------------------
53 
stream_buffer(u32 sample_rate)54 stream_buffer::stream_buffer(u32 sample_rate) :
55 	m_end_second(0),
56 	m_end_sample(0),
57 	m_sample_rate(sample_rate),
58 	m_sample_attos((sample_rate == 0) ? ATTOSECONDS_PER_SECOND : ((ATTOSECONDS_PER_SECOND + sample_rate - 1) / sample_rate)),
59 	m_buffer(sample_rate)
60 {
61 }
62 
63 
64 //-------------------------------------------------
65 //  stream_buffer - destructor
66 //-------------------------------------------------
67 
~stream_buffer()68 stream_buffer::~stream_buffer()
69 {
70 #if (SOUND_DEBUG)
71 	if (m_wav_file != nullptr)
72 	{
73 		flush_wav();
74 		close_wav();
75 	}
76 #endif
77 }
78 
79 
80 //-------------------------------------------------
81 //  set_sample_rate - set a new sample rate for
82 //  this buffer
83 //-------------------------------------------------
84 
set_sample_rate(u32 rate,bool resample)85 void stream_buffer::set_sample_rate(u32 rate, bool resample)
86 {
87 	// skip if nothing is actually changing
88 	if (rate == m_sample_rate)
89 		return;
90 
91 	// force resampling off if coming to or from an invalid rate, or if we're at time 0 (startup)
92 	sound_assert(rate >= SAMPLE_RATE_MINIMUM - 1);
93 	if (rate < SAMPLE_RATE_MINIMUM || m_sample_rate < SAMPLE_RATE_MINIMUM || (m_end_second == 0 && m_end_sample == 0))
94 		resample = false;
95 
96 	// note the time and period of the current buffer (end_time is AFTER the final sample)
97 	attotime prevperiod = sample_period();
98 	attotime prevend = end_time();
99 
100 	// compute the time and period of the new buffer
101 	attotime newperiod = attotime(0, (ATTOSECONDS_PER_SECOND + rate - 1) / rate);
102 	attotime newend = attotime(prevend.seconds(), (prevend.attoseconds() / newperiod.attoseconds()) * newperiod.attoseconds());
103 
104 	// buffer a short runway of previous samples; in order to support smooth
105 	// sample rate changes (needed by, e.g., Q*Bert's Votrax), we buffer a few
106 	// samples at the previous rate, and then reconstitute them resampled
107 	// (via simple point sampling) at the new rate. The litmus test is the
108 	// voice when jumping off the edge in Q*Bert; without this extra effort
109 	// it is crackly and/or glitchy at times
110 	sample_t buffer[64];
111 	int buffered_samples = std::min(m_sample_rate, std::min(rate, u32(ARRAY_LENGTH(buffer))));
112 
113 	// if the new rate is lower, downsample into our holding buffer;
114 	// otherwise just copy into our holding buffer for later upsampling
115 	bool new_rate_higher = (rate > m_sample_rate);
116 	if (resample)
117 	{
118 		if (!new_rate_higher)
119 			backfill_downsample(&buffer[0], buffered_samples, newend, newperiod);
120 		else
121 		{
122 			u32 end = m_end_sample;
123 			for (int index = 0; index < buffered_samples; index++)
124 			{
125 				end = prev_index(end);
126 #if (SOUND_DEBUG)
127 				// multiple resamples can occur before clearing out old NaNs so
128 				// neuter them for this specific case
129 				if (std::isnan(m_buffer[end]))
130 					buffer[index] = 0;
131 				else
132 #endif
133 					buffer[index] = get(end);
134 			}
135 		}
136 	}
137 
138 	// ensure our buffer is large enough to hold a full second at the new rate
139 	if (m_buffer.size() < rate)
140 		m_buffer.resize(rate);
141 
142 	// set the new rate
143 	m_sample_rate = rate;
144 	m_sample_attos = newperiod.attoseconds();
145 
146 	// compute the new end sample index based on the buffer time
147 	m_end_sample = time_to_buffer_index(prevend, false, true);
148 
149 	// if the new rate is higher, upsample from our temporary buffer;
150 	// otherwise just copy our previously-downsampled data
151 	if (resample)
152 	{
153 #if (SOUND_DEBUG)
154 		// for aggressive debugging, fill the buffer with NANs to catch anyone
155 		// reading beyond what we resample below
156 		fill(NAN);
157 #endif
158 
159 		if (new_rate_higher)
160 			backfill_upsample(&buffer[0], buffered_samples, prevend, prevperiod);
161 		else
162 		{
163 			u32 end = m_end_sample;
164 			for (int index = 0; index < buffered_samples; index++)
165 			{
166 				end = prev_index(end);
167 				put(end, buffer[index]);
168 			}
169 		}
170 	}
171 
172 	// if not resampling, clear the buffer
173 	else
174 		fill(0);
175 }
176 
177 
178 //-------------------------------------------------
179 //  open_wav - open a WAV file for logging purposes
180 //-------------------------------------------------
181 
182 #if (SOUND_DEBUG)
open_wav(char const * filename)183 void stream_buffer::open_wav(char const *filename)
184 {
185 	// always open at 48k so that sound programs can handle it
186 	// re-sample as needed
187 	m_wav_file = wav_open(filename, 48000, 1);
188 }
189 #endif
190 
191 
192 //-------------------------------------------------
193 //  flush_wav - flush data to the WAV file
194 //-------------------------------------------------
195 
196 #if (SOUND_DEBUG)
flush_wav()197 void stream_buffer::flush_wav()
198 {
199 	// skip if no file
200 	if (m_wav_file == nullptr)
201 		return;
202 
203 	// grab a view of the data from the last-written point
204 	read_stream_view view(this, m_last_written, m_end_sample, 1.0f);
205 	m_last_written = m_end_sample;
206 
207 	// iterate over chunks for conversion
208 	s16 buffer[1024];
209 	for (int samplebase = 0; samplebase < view.samples(); samplebase += ARRAY_LENGTH(buffer))
210 	{
211 		// clamp to the buffer size
212 		int cursamples = view.samples() - samplebase;
213 		if (cursamples > ARRAY_LENGTH(buffer))
214 			cursamples = ARRAY_LENGTH(buffer);
215 
216 		// convert and fill
217 		for (int sampindex = 0; sampindex < cursamples; sampindex++)
218 			buffer[sampindex] = s16(view.get(samplebase + sampindex) * 32768.0);
219 
220 		// write to the WAV
221 		wav_add_data_16(m_wav_file, buffer, cursamples);
222 	}
223 }
224 #endif
225 
226 
227 //-------------------------------------------------
228 //  close_wav - close the logging WAV file
229 //-------------------------------------------------
230 
231 #if (SOUND_DEBUG)
close_wav()232 void stream_buffer::close_wav()
233 {
234 	if (m_wav_file != nullptr)
235 		wav_close(m_wav_file);
236 	m_wav_file = nullptr;
237 }
238 #endif
239 
240 
241 //-------------------------------------------------
242 //  index_time - return the attotime of a given
243 //  index within the buffer
244 //-------------------------------------------------
245 
index_time(s32 index) const246 attotime stream_buffer::index_time(s32 index) const
247 {
248 	index = clamp_index(index);
249 	return attotime(m_end_second - ((index > m_end_sample) ? 1 : 0), index * m_sample_attos);
250 }
251 
252 
253 //-------------------------------------------------
254 //  time_to_buffer_index - given an attotime,
255 //  return the buffer index corresponding to it
256 //-------------------------------------------------
257 
time_to_buffer_index(attotime time,bool round_up,bool allow_expansion)258 u32 stream_buffer::time_to_buffer_index(attotime time, bool round_up, bool allow_expansion)
259 {
260 	// compute the sample index within the second
261 	int sample = (time.attoseconds() + (round_up ? (m_sample_attos - 1) : 0)) / m_sample_attos;
262 	sound_assert(sample >= 0 && sample <= size());
263 
264 	// if the time is past the current end, make it the end
265 	if (time.seconds() > m_end_second || (time.seconds() == m_end_second && sample > m_end_sample))
266 	{
267 		sound_assert(allow_expansion);
268 
269 		m_end_sample = sample;
270 		m_end_second = time.m_seconds;
271 
272 		// due to round_up, we could tweak over the line into the next second
273 		if (sample >= size())
274 		{
275 			m_end_sample -= size();
276 			m_end_second++;
277 		}
278 	}
279 
280 	// if the time is before the start, fail
281 	if (time.seconds() + 1 < m_end_second || (time.seconds() + 1 == m_end_second && sample < m_end_sample))
282 		throw emu_fatalerror("Attempt to create an out-of-bounds view");
283 
284 	return clamp_index(sample);
285 }
286 
287 
288 //-------------------------------------------------
289 //  backfill_downsample - this is called BEFORE
290 //  the sample rate change to downsample from the
291 //  end of the current buffer into a temporary
292 //  holding location
293 //-------------------------------------------------
294 
backfill_downsample(sample_t * dest,int samples,attotime newend,attotime newperiod)295 void stream_buffer::backfill_downsample(sample_t *dest, int samples, attotime newend, attotime newperiod)
296 {
297 	// compute the time of the first sample to be backfilled; start one period before
298 	attotime time = newend - newperiod;
299 
300 	// loop until we run out of buffered data
301 	int dstindex;
302 	for (dstindex = 0; dstindex < samples && time.seconds() >= 0; dstindex++)
303 	{
304 		u32 srcindex = time_to_buffer_index(time, false);
305 #if (SOUND_DEBUG)
306 		// multiple resamples can occur before clearing out old NaNs so
307 		// neuter them for this specific case
308 		if (std::isnan(m_buffer[srcindex]))
309 			dest[dstindex] = 0;
310 		else
311 #endif
312 			dest[dstindex] = get(srcindex);
313 		time -= newperiod;
314 	}
315 	for ( ; dstindex < samples; dstindex++)
316 		dest[dstindex] = 0;
317 }
318 
319 
320 //-------------------------------------------------
321 //  backfill_upsample - this is called AFTER the
322 //  sample rate change to take a copied buffer
323 //  of samples at the old rate and upsample them
324 //  to the new (current) rate
325 //-------------------------------------------------
326 
backfill_upsample(sample_t const * src,int samples,attotime prevend,attotime prevperiod)327 void stream_buffer::backfill_upsample(sample_t const *src, int samples, attotime prevend, attotime prevperiod)
328 {
329 	// compute the time of the first sample to be backfilled; start one period before
330 	attotime time = end_time() - sample_period();
331 
332 	// also adjust the buffered sample end time to point to the sample time of the
333 	// final sample captured
334 	prevend -= prevperiod;
335 
336 	// loop until we run out of buffered data
337 	u32 end = m_end_sample;
338 	int srcindex = 0;
339 	while (1)
340 	{
341 		// if our backfill time is before the current buffered sample time,
342 		// back up until we have a sample that covers this time
343 		while (time < prevend && srcindex < samples)
344 		{
345 			prevend -= prevperiod;
346 			srcindex++;
347 		}
348 
349 		// stop when we run out of source
350 		if (srcindex >= samples)
351 			break;
352 
353 		// write this sample at the pevious position
354 		end = prev_index(end);
355 		put(end, src[srcindex]);
356 
357 		// back up to the next sample time
358 		time -= sample_period();
359 	}
360 }
361 
362 
363 
364 //**************************************************************************
365 //  SOUND STREAM OUTPUT
366 //**************************************************************************
367 
368 //-------------------------------------------------
369 //  sound_stream_output - constructor
370 //-------------------------------------------------
371 
sound_stream_output()372 sound_stream_output::sound_stream_output() :
373 	m_stream(nullptr),
374 	m_index(0),
375 	m_gain(1.0)
376 {
377 }
378 
379 
380 //-------------------------------------------------
381 //  init - initialization
382 //-------------------------------------------------
383 
init(sound_stream & stream,u32 index,char const * tag)384 void sound_stream_output::init(sound_stream &stream, u32 index, char const *tag)
385 {
386 	// set the passed-in data
387 	m_stream = &stream;
388 	m_index = index;
389 
390 	// save our state
391 	auto &save = stream.device().machine().save();
392 	save.save_item(&stream.device(), "stream.output", tag, index, NAME(m_gain));
393 
394 #if (LOG_OUTPUT_WAV)
395 	std::string filename = stream.device().machine().basename();
396 	filename += stream.device().tag();
397 	for (int index = 0; index < filename.size(); index++)
398 		if (filename[index] == ':')
399 			filename[index] = '_';
400 	if (dynamic_cast<default_resampler_stream *>(&stream) != nullptr)
401 		filename += "_resampler";
402 	filename += "_OUT_";
403 	char buf[10];
404 	sprintf(buf, "%d", index);
405 	filename += buf;
406 	filename += ".wav";
407 	m_buffer.open_wav(filename.c_str());
408 #endif
409 }
410 
411 
412 //-------------------------------------------------
413 //  name - return the friendly name of this output
414 //-------------------------------------------------
415 
name() const416 std::string sound_stream_output::name() const
417 {
418 	// start with our owning stream's name
419 	std::ostringstream str;
420 	util::stream_format(str, "%s Ch.%d", m_stream->name(), m_stream->output_base() + m_index);
421 	return str.str();
422 }
423 
424 
425 //-------------------------------------------------
426 //  optimize_resampler - optimize resamplers by
427 //  either returning the native rate or another
428 //  input's resampler if they can be reused
429 //-------------------------------------------------
430 
optimize_resampler(sound_stream_output * input_resampler)431 sound_stream_output &sound_stream_output::optimize_resampler(sound_stream_output *input_resampler)
432 {
433 	// if no resampler, or if the resampler rate matches our rate, return ourself
434 	if (input_resampler == nullptr || buffer_sample_rate() == input_resampler->buffer_sample_rate())
435 		return *this;
436 
437 	// scan our list of resamplers to see if there's another match
438 	for (auto &resampler : m_resampler_list)
439 		if (resampler->buffer_sample_rate() == input_resampler->buffer_sample_rate())
440 			return *resampler;
441 
442 	// add the input to our list and return the one we were given back
443 	m_resampler_list.push_back(input_resampler);
444 	return *input_resampler;
445 }
446 
447 
448 
449 //**************************************************************************
450 //  SOUND STREAM INPUT
451 //**************************************************************************
452 
453 //-------------------------------------------------
454 //  sound_stream_input - constructor
455 //-------------------------------------------------
456 
sound_stream_input()457 sound_stream_input::sound_stream_input() :
458 	m_owner(nullptr),
459 	m_native_source(nullptr),
460 	m_resampler_source(nullptr),
461 	m_index(0),
462 	m_gain(1.0),
463 	m_user_gain(1.0)
464 {
465 }
466 
467 
468 //-------------------------------------------------
469 //  init - initialization
470 //-------------------------------------------------
471 
init(sound_stream & stream,u32 index,char const * tag,sound_stream_output * resampler)472 void sound_stream_input::init(sound_stream &stream, u32 index, char const *tag, sound_stream_output *resampler)
473 {
474 	// set the passed-in values
475 	m_owner = &stream;
476 	m_index = index;
477 	m_resampler_source = resampler;
478 
479 	// save our state
480 	auto &save = stream.device().machine().save();
481 	save.save_item(&stream.device(), "stream.input", tag, index, NAME(m_gain));
482 	save.save_item(&stream.device(), "stream.input", tag, index, NAME(m_user_gain));
483 }
484 
485 
486 //-------------------------------------------------
487 //  name - return the friendly name of this input
488 //-------------------------------------------------
489 
name() const490 std::string sound_stream_input::name() const
491 {
492 	// start with our owning stream's name
493 	std::ostringstream str;
494 	util::stream_format(str, "%s", m_owner->name());
495 
496 	// if we have a source, indicate where the sound comes from by device name and tag
497 	if (valid())
498 		util::stream_format(str, " <- %s", m_native_source->name());
499 	return str.str();
500 }
501 
502 
503 //-------------------------------------------------
504 //  set_source - wire up the output source for
505 //  our consumption
506 //-------------------------------------------------
507 
set_source(sound_stream_output * source)508 void sound_stream_input::set_source(sound_stream_output *source)
509 {
510 	m_native_source = source;
511 	if (m_resampler_source != nullptr)
512 		m_resampler_source->stream().set_input(0, &source->stream(), source->index());
513 }
514 
515 
516 //-------------------------------------------------
517 //  update - update our source's stream to the
518 //  current end time and return a view to its
519 //  contents
520 //-------------------------------------------------
521 
update(attotime start,attotime end)522 read_stream_view sound_stream_input::update(attotime start, attotime end)
523 {
524 	// shouldn't get here unless valid
525 	sound_assert(valid());
526 
527 	// pick an optimized resampler
528 	sound_stream_output &source = m_native_source->optimize_resampler(m_resampler_source);
529 
530 	// if not using our own resampler, keep it up to date in case we need to invoke it later
531 	if (m_resampler_source != nullptr && &source != m_resampler_source)
532 		m_resampler_source->set_end_time(end);
533 
534 	// update the source, returning a view of the needed output over the start and end times
535 	return source.stream().update_view(start, end, source.index()).apply_gain(m_gain * m_user_gain * source.gain());
536 }
537 
538 
539 //-------------------------------------------------
540 //  apply_sample_rate_changes - tell our sources
541 //  to apply any sample rate changes, informing
542 //  them of our current rate
543 //-------------------------------------------------
544 
apply_sample_rate_changes(u32 updatenum,u32 downstream_rate)545 void sound_stream_input::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate)
546 {
547 	// shouldn't get here unless valid
548 	sound_assert(valid());
549 
550 	// if we have a resampler, tell it (and it will tell the native source)
551 	if (m_resampler_source != nullptr)
552 		m_resampler_source->stream().apply_sample_rate_changes(updatenum, downstream_rate);
553 
554 	// otherwise, just tell the native source directly
555 	else
556 		m_native_source->stream().apply_sample_rate_changes(updatenum, downstream_rate);
557 }
558 
559 
560 
561 //**************************************************************************
562 //  SOUND STREAM
563 //**************************************************************************
564 
565 //-------------------------------------------------
566 //  sound_stream - private common constructor
567 //-------------------------------------------------
568 
sound_stream(device_t & device,u32 inputs,u32 outputs,u32 output_base,u32 sample_rate,sound_stream_flags flags)569 sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, sound_stream_flags flags) :
570 	m_device(device),
571 	m_next(nullptr),
572 	m_sample_rate((sample_rate < SAMPLE_RATE_MINIMUM) ? (SAMPLE_RATE_MINIMUM - 1) : (sample_rate < SAMPLE_RATE_OUTPUT_ADAPTIVE) ? sample_rate : 48000),
573 	m_pending_sample_rate(SAMPLE_RATE_INVALID),
574 	m_last_sample_rate_update(0),
575 	m_input_adaptive(sample_rate == SAMPLE_RATE_INPUT_ADAPTIVE),
576 	m_output_adaptive(sample_rate == SAMPLE_RATE_OUTPUT_ADAPTIVE),
577 	m_synchronous((flags & STREAM_SYNCHRONOUS) != 0),
578 	m_resampling_disabled((flags & STREAM_DISABLE_INPUT_RESAMPLING) != 0),
579 	m_sync_timer(nullptr),
580 	m_input(inputs),
581 	m_input_view(inputs),
582 	m_empty_buffer(100),
583 	m_output_base(output_base),
584 	m_output(outputs),
585 	m_output_view(outputs)
586 {
587 	sound_assert(outputs > 0);
588 
589 	// create a name
590 	m_name = m_device.name();
591 	m_name += " '";
592 	m_name += m_device.tag();
593 	m_name += "'";
594 
595 	// create a unique tag for saving
596 	std::string state_tag = string_format("%d", m_device.machine().sound().unique_id());
597 	auto &save = m_device.machine().save();
598 	save.save_item(&m_device, "stream.sample_rate", state_tag.c_str(), 0, NAME(m_sample_rate));
599 	save.register_postload(save_prepost_delegate(FUNC(sound_stream::postload), this));
600 
601 	// initialize all inputs
602 	for (unsigned int inputnum = 0; inputnum < m_input.size(); inputnum++)
603 	{
604 		// allocate a resampler stream if needed, and get a pointer to its output
605 		sound_stream_output *resampler = nullptr;
606 		if (!m_resampling_disabled)
607 		{
608 			m_resampler_list.push_back(std::make_unique<default_resampler_stream>(m_device));
609 			resampler = &m_resampler_list.back()->m_output[0];
610 		}
611 
612 		// add the new input
613 		m_input[inputnum].init(*this, inputnum, state_tag.c_str(), resampler);
614 	}
615 
616 	// initialize all outputs
617 	for (unsigned int outputnum = 0; outputnum < m_output.size(); outputnum++)
618 		m_output[outputnum].init(*this, outputnum, state_tag.c_str());
619 
620 	// create an update timer for synchronous streams
621 	if (synchronous())
622 		m_sync_timer = m_device.machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sound_stream::sync_update), this));
623 
624 	// force an update to the sample rates
625 	sample_rate_changed();
626 }
627 
628 
629 //-------------------------------------------------
630 //  sound_stream - constructor
631 //-------------------------------------------------
632 
sound_stream(device_t & device,u32 inputs,u32 outputs,u32 output_base,u32 sample_rate,stream_update_delegate callback,sound_stream_flags flags)633 sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags) :
634 	sound_stream(device, inputs, outputs, output_base, sample_rate, flags)
635 {
636 	m_callback_ex = std::move(callback);
637 }
638 
639 
640 //-------------------------------------------------
641 //  ~sound_stream - destructor
642 //-------------------------------------------------
643 
~sound_stream()644 sound_stream::~sound_stream()
645 {
646 }
647 
648 
649 //-------------------------------------------------
650 //  set_sample_rate - set the sample rate on a
651 //  given stream
652 //-------------------------------------------------
653 
set_sample_rate(u32 new_rate)654 void sound_stream::set_sample_rate(u32 new_rate)
655 {
656 	// we will update this on the next global update
657 	if (new_rate != sample_rate())
658 		m_pending_sample_rate = new_rate;
659 }
660 
661 
662 //-------------------------------------------------
663 //  set_input - configure a stream's input
664 //-------------------------------------------------
665 
set_input(int index,sound_stream * input_stream,int output_index,float gain)666 void sound_stream::set_input(int index, sound_stream *input_stream, int output_index, float gain)
667 {
668 	VPRINTF(("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", (void *)this, m_device.tag(),
669 			index, (void *)input_stream, output_index, (double) gain));
670 
671 	// make sure it's a valid input
672 	if (index >= m_input.size())
673 		fatalerror("stream_set_input attempted to configure nonexistent input %d (%d max)\n", index, int(m_input.size()));
674 
675 	// make sure it's a valid output
676 	if (input_stream != nullptr && output_index >= input_stream->m_output.size())
677 		fatalerror("stream_set_input attempted to use a nonexistent output %d (%d max)\n", output_index, int(m_output.size()));
678 
679 	// wire it up
680 	m_input[index].set_source((input_stream != nullptr) ? &input_stream->m_output[output_index] : nullptr);
681 	m_input[index].set_gain(gain);
682 
683 	// update sample rates now that we know the input
684 	sample_rate_changed();
685 }
686 
687 
688 //-------------------------------------------------
689 //  update - force a stream to update to
690 //  the current emulated time
691 //-------------------------------------------------
692 
update()693 void sound_stream::update()
694 {
695 	// ignore any update requests if we're already up to date
696 	attotime start = m_output[0].end_time();
697 	attotime end = m_device.machine().time();
698 	if (start >= end)
699 		return;
700 
701 	// regular update then
702 	update_view(start, end);
703 }
704 
705 
706 //-------------------------------------------------
707 //  update_view - force a stream to update to
708 //  the current emulated time and return a view
709 //  to the generated samples from the given
710 //  output number
711 //-------------------------------------------------
712 
update_view(attotime start,attotime end,u32 outputnum)713 read_stream_view sound_stream::update_view(attotime start, attotime end, u32 outputnum)
714 {
715 	sound_assert(start <= end);
716 	sound_assert(outputnum < m_output.size());
717 
718 	// clean up parameters for when the asserts go away
719 	if (outputnum >= m_output.size())
720 		outputnum = 0;
721 	if (start > end)
722 		start = end;
723 
724 	g_profiler.start(PROFILER_SOUND);
725 
726 	// reposition our start to coincide with the current buffer end
727 	attotime update_start = m_output[outputnum].end_time();
728 	if (update_start <= end)
729 	{
730 		// create views for all the outputs
731 		for (unsigned int outindex = 0; outindex < m_output.size(); outindex++)
732 			m_output_view[outindex] = m_output[outindex].view(update_start, end);
733 
734 		// skip if nothing to do
735 		u32 samples = m_output_view[0].samples();
736 		sound_assert(samples >= 0);
737 		if (samples != 0 && m_sample_rate >= SAMPLE_RATE_MINIMUM)
738 		{
739 			sound_assert(!synchronous() || samples == 1);
740 
741 			// ensure all input streams are up to date, and create views for them as well
742 			for (unsigned int inputnum = 0; inputnum < m_input.size(); inputnum++)
743 			{
744 				if (m_input[inputnum].valid())
745 					m_input_view[inputnum] = m_input[inputnum].update(update_start, end);
746 				else
747 					m_input_view[inputnum] = empty_view(update_start, end);
748 				sound_assert(m_input_view[inputnum].samples() > 0);
749 				sound_assert(m_resampling_disabled || m_input_view[inputnum].sample_rate() == m_sample_rate);
750 			}
751 
752 #if (SOUND_DEBUG)
753 			// clear each output view to NANs before we call the callback
754 			for (unsigned int outindex = 0; outindex < m_output.size(); outindex++)
755 				m_output_view[outindex].fill(NAN);
756 #endif
757 
758 			// if we have an extended callback, that's all we need
759 			m_callback_ex(*this, m_input_view, m_output_view);
760 
761 #if (SOUND_DEBUG)
762 			// make sure everything was overwritten
763 			for (unsigned int outindex = 0; outindex < m_output.size(); outindex++)
764 				for (int sampindex = 0; sampindex < m_output_view[outindex].samples(); sampindex++)
765 					m_output_view[outindex].get(sampindex);
766 
767 			for (unsigned int outindex = 0; outindex < m_output.size(); outindex++)
768 				m_output[outindex].m_buffer.flush_wav();
769 #endif
770 		}
771 	}
772 	g_profiler.stop();
773 
774 	// return the requested view
775 	return read_stream_view(m_output_view[outputnum], start);
776 }
777 
778 
779 //-------------------------------------------------
780 //  apply_sample_rate_changes - if there is a
781 //  pending sample rate change, apply it now
782 //-------------------------------------------------
783 
apply_sample_rate_changes(u32 updatenum,u32 downstream_rate)784 void sound_stream::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate)
785 {
786 	// grab the new rate and invalidate
787 	u32 new_rate = (m_pending_sample_rate != SAMPLE_RATE_INVALID) ? m_pending_sample_rate : m_sample_rate;
788 	m_pending_sample_rate = SAMPLE_RATE_INVALID;
789 
790 	// clamp to the minimum - 1 (anything below minimum means "off" and
791 	// will not call the sound callback at all)
792 	if (new_rate < SAMPLE_RATE_MINIMUM)
793 		new_rate = SAMPLE_RATE_MINIMUM - 1;
794 
795 	// if we're input adaptive, override with the rate of our input
796 	if (input_adaptive() && m_input.size() > 0 && m_input[0].valid())
797 		new_rate = m_input[0].source().stream().sample_rate();
798 
799 	// if we're output adaptive, override with the rate of our output
800 	if (output_adaptive())
801 	{
802 		if (m_last_sample_rate_update == updatenum)
803 			sound_assert(new_rate == m_sample_rate);
804 		else
805 			m_last_sample_rate_update = updatenum;
806 		new_rate = downstream_rate;
807 	}
808 
809 	// if something is different, process the change
810 	if (new_rate != SAMPLE_RATE_INVALID && new_rate != m_sample_rate)
811 	{
812 		// update to the new rate and notify everyone
813 #if (SOUND_DEBUG)
814 		printf("stream %s changing rates %d -> %d\n", name().c_str(), m_sample_rate, new_rate);
815 #endif
816 		m_sample_rate = new_rate;
817 		sample_rate_changed();
818 	}
819 
820 	// now call through our inputs and apply the rate change there
821 	for (auto &input : m_input)
822 		if (input.valid())
823 			input.apply_sample_rate_changes(updatenum, m_sample_rate);
824 }
825 
826 
827 //-------------------------------------------------
828 //  print_graph_recursive - helper for debugging;
829 //  prints info on this stream and then recursively
830 //  prints info on all inputs
831 //-------------------------------------------------
832 
833 #if (SOUND_DEBUG)
print_graph_recursive(int indent,int index)834 void sound_stream::print_graph_recursive(int indent, int index)
835 {
836 	osd_printf_info("%*s%s Ch.%d @ %d\n", indent, "", name().c_str(), index + m_output_base, sample_rate());
837 	for (int index = 0; index < m_input.size(); index++)
838 		if (m_input[index].valid())
839 		{
840 			if (m_input[index].m_resampler_source != nullptr)
841 				m_input[index].m_resampler_source->stream().print_graph_recursive(indent + 2, m_input[index].m_resampler_source->index());
842 			else
843 				m_input[index].m_native_source->stream().print_graph_recursive(indent + 2, m_input[index].m_native_source->index());
844 		}
845 }
846 #endif
847 
848 
849 //-------------------------------------------------
850 //  sample_rate_changed - recompute sample
851 //  rate data, and all streams that are affected
852 //  by this stream
853 //-------------------------------------------------
854 
sample_rate_changed()855 void sound_stream::sample_rate_changed()
856 {
857 	// if invalid, just punt
858 	if (m_sample_rate == SAMPLE_RATE_INVALID)
859 		return;
860 
861 	// update all output buffers
862 	for (auto &output : m_output)
863 		output.sample_rate_changed(m_sample_rate);
864 
865 	// if synchronous, prime the timer
866 	if (synchronous())
867 		reprime_sync_timer();
868 }
869 
870 
871 //-------------------------------------------------
872 //  postload - save/restore callback
873 //-------------------------------------------------
874 
postload()875 void sound_stream::postload()
876 {
877 	// set the end time of all of our streams to now
878 	for (auto &output : m_output)
879 		output.set_end_time(m_device.machine().time());
880 
881 	// recompute the sample rate information
882 	sample_rate_changed();
883 }
884 
885 
886 //-------------------------------------------------
887 //  reprime_sync_timer - set up the next sync
888 //  timer to go off just a hair after the end of
889 //  the current sample period
890 //-------------------------------------------------
891 
reprime_sync_timer()892 void sound_stream::reprime_sync_timer()
893 {
894 	attotime curtime = m_device.machine().time();
895 	attotime target = m_output[0].end_time() + attotime(0, 1);
896 	m_sync_timer->adjust(target - curtime);
897 }
898 
899 
900 //-------------------------------------------------
901 //  sync_update - timer callback to handle a
902 //  synchronous stream
903 //-------------------------------------------------
904 
sync_update(void *,s32)905 void sound_stream::sync_update(void *, s32)
906 {
907 	update();
908 	reprime_sync_timer();
909 }
910 
911 
912 //-------------------------------------------------
913 //  empty_view - return an empty view covering the
914 //  given time period as a substitute for invalid
915 //  inputs
916 //-------------------------------------------------
917 
empty_view(attotime start,attotime end)918 read_stream_view sound_stream::empty_view(attotime start, attotime end)
919 {
920 	// if our dummy buffer doesn't match our sample rate, update and clear it
921 	if (m_empty_buffer.sample_rate() != m_sample_rate)
922 		m_empty_buffer.set_sample_rate(m_sample_rate, false);
923 
924 	// allocate a write view so that it can expand, and convert back to a read view
925 	// on the return
926 	return write_stream_view(m_empty_buffer, start, end);
927 }
928 
929 
930 
931 //**************************************************************************
932 //  RESAMPLER STREAM
933 //**************************************************************************
934 
935 //-------------------------------------------------
936 //  default_resampler_stream - derived sound_stream
937 //  class that handles resampling
938 //-------------------------------------------------
939 
default_resampler_stream(device_t & device)940 default_resampler_stream::default_resampler_stream(device_t &device) :
941 	sound_stream(device, 1, 1, 0, SAMPLE_RATE_OUTPUT_ADAPTIVE, stream_update_delegate(&default_resampler_stream::resampler_sound_update, this), STREAM_DISABLE_INPUT_RESAMPLING),
942 	m_max_latency(0)
943 {
944 	// create a name
945 	m_name = "Default Resampler '";
946 	m_name += device.tag();
947 	m_name += "'";
948 }
949 
950 
951 //-------------------------------------------------
952 //  resampler_sound_update - stream callback
953 //  handler for resampling an input stream to the
954 //  target sample rate of the output
955 //-------------------------------------------------
956 
resampler_sound_update(sound_stream & stream,std::vector<read_stream_view> const & inputs,std::vector<write_stream_view> & outputs)957 void default_resampler_stream::resampler_sound_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
958 {
959 	sound_assert(inputs.size() == 1);
960 	sound_assert(outputs.size() == 1);
961 
962 	auto &input = inputs[0];
963 	auto &output = outputs[0];
964 
965 	// if the input has an invalid rate, just fill with zeros
966 	if (input.sample_rate() <= 1)
967 	{
968 		output.fill(0);
969 		return;
970 	}
971 
972 	// optimize_resampler ensures we should not have equal sample rates
973 	sound_assert(input.sample_rate() != output.sample_rate());
974 
975 	// compute the stepping value and the inverse
976 	stream_buffer::sample_t step = stream_buffer::sample_t(input.sample_rate()) / stream_buffer::sample_t(output.sample_rate());
977 	stream_buffer::sample_t stepinv = 1.0 / step;
978 
979 	// determine the latency we need to introduce, in input samples:
980 	//    1 input sample for undersampled inputs
981 	//    1 + step input samples for oversampled inputs
982 	s64 latency_samples = 1 + ((step < 1.0) ? 0 : s32(step));
983 	if (latency_samples <= m_max_latency)
984 		latency_samples = m_max_latency;
985 	else
986 		m_max_latency = latency_samples;
987 	attotime latency = latency_samples * input.sample_period();
988 
989 	// clamp the latency to the start (only relevant at the beginning)
990 	s32 dstindex = 0;
991 	attotime output_start = output.start_time();
992 	auto numsamples = output.samples();
993 	while (latency > output_start && dstindex < numsamples)
994 	{
995 		output.put(dstindex++, 0);
996 		output_start += output.sample_period();
997 	}
998 	if (dstindex >= numsamples)
999 		return;
1000 
1001 	// create a rebased input buffer around the adjusted start time
1002 	read_stream_view rebased(input, output_start - latency);
1003 	sound_assert(rebased.start_time() + latency <= output_start);
1004 
1005 	// compute the fractional input start position
1006 	attotime delta = output_start - (rebased.start_time() + latency);
1007 	sound_assert(delta.seconds() == 0);
1008 	stream_buffer::sample_t srcpos = stream_buffer::sample_t(double(delta.attoseconds()) / double(rebased.sample_period_attoseconds()));
1009 	sound_assert(srcpos <= 1.0f);
1010 
1011 	// input is undersampled: point sample except where our sample period covers a boundary
1012 	s32 srcindex = 0;
1013 	if (step < 1.0)
1014 	{
1015 		stream_buffer::sample_t cursample = rebased.get(srcindex++);
1016 		for ( ; dstindex < numsamples; dstindex++)
1017 		{
1018 			// if still within the current sample, just replicate
1019 			srcpos += step;
1020 			if (srcpos <= 1.0)
1021 				output.put(dstindex, cursample);
1022 
1023 			// if crossing a sample boundary, blend with the neighbor
1024 			else
1025 			{
1026 				srcpos -= 1.0;
1027 				sound_assert(srcpos <= step + 1e-5);
1028 				stream_buffer::sample_t prevsample = cursample;
1029 				cursample = rebased.get(srcindex++);
1030 				output.put(dstindex, stepinv * (prevsample * (step - srcpos) + srcpos * cursample));
1031 			}
1032 		}
1033 		sound_assert(srcindex <= rebased.samples());
1034 	}
1035 
1036 	// input is oversampled: sum the energy
1037 	else
1038 	{
1039 		float cursample = rebased.get(srcindex++);
1040 		for ( ; dstindex < numsamples; dstindex++)
1041 		{
1042 			// compute the partial first sample and advance
1043 			stream_buffer::sample_t scale = 1.0 - srcpos;
1044 			stream_buffer::sample_t sample = cursample * scale;
1045 
1046 			// add in complete samples until we only have a fraction left
1047 			stream_buffer::sample_t remaining = step - scale;
1048 			while (remaining >= 1.0)
1049 			{
1050 				sample += rebased.get(srcindex++);
1051 				remaining -= 1.0;
1052 			}
1053 
1054 			// add in the final partial sample
1055 			cursample = rebased.get(srcindex++);
1056 			sample += cursample * remaining;
1057 			output.put(dstindex, sample * stepinv);
1058 
1059 			// our position is now the remainder
1060 			srcpos = remaining;
1061 			sound_assert(srcindex <= rebased.samples());
1062 		}
1063 	}
1064 }
1065 
1066 
1067 
1068 //**************************************************************************
1069 //  SOUND MANAGER
1070 //**************************************************************************
1071 
1072 //-------------------------------------------------
1073 //  sound_manager - constructor
1074 //-------------------------------------------------
1075 
sound_manager(running_machine & machine)1076 sound_manager::sound_manager(running_machine &machine) :
1077 	m_machine(machine),
1078 	m_update_timer(nullptr),
1079 	m_update_number(0),
1080 	m_last_update(attotime::zero),
1081 	m_finalmix_leftover(0),
1082 	m_samples_this_update(0),
1083 	m_finalmix(machine.sample_rate()),
1084 	m_leftmix(machine.sample_rate()),
1085 	m_rightmix(machine.sample_rate()),
1086 	m_compressor_scale(1.0),
1087 	m_compressor_counter(0),
1088 	m_muted(0),
1089 	m_nosound_mode(machine.osd().no_sound()),
1090 	m_attenuation(0),
1091 	m_unique_id(0),
1092 	m_wavfile(nullptr),
1093 	m_first_reset(true)
1094 {
1095 	// get filename for WAV file or AVI file if specified
1096 	const char *wavfile = machine.options().wav_write();
1097 	const char *avifile = machine.options().avi_write();
1098 
1099 	// handle -nosound and lower sample rate if not recording WAV or AVI
1100 	if (m_nosound_mode && wavfile[0] == 0 && avifile[0] == 0)
1101 		machine.m_sample_rate = 11025;
1102 
1103 	// count the mixers
1104 #if VERBOSE
1105 	mixer_interface_iterator iter(machine.root_device());
1106 	VPRINTF(("total mixers = %d\n", iter.count()));
1107 #endif
1108 
1109 	// register callbacks
1110 	machine.configuration().config_register("mixer", config_load_delegate(&sound_manager::config_load, this), config_save_delegate(&sound_manager::config_save, this));
1111 	machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(&sound_manager::pause, this));
1112 	machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(&sound_manager::resume, this));
1113 	machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&sound_manager::reset, this));
1114 	machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&sound_manager::stop_recording, this));
1115 
1116 	// register global states
1117 	machine.save().save_item(NAME(m_last_update));
1118 
1119 	// set the starting attenuation
1120 	set_attenuation(machine.options().volume());
1121 
1122 	// start the periodic update flushing timer
1123 	m_update_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(sound_manager::update), this));
1124 	m_update_timer->adjust(STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME);
1125 }
1126 
1127 
1128 //-------------------------------------------------
1129 //  sound_manager - destructor
1130 //-------------------------------------------------
1131 
~sound_manager()1132 sound_manager::~sound_manager()
1133 {
1134 }
1135 
1136 
1137 //-------------------------------------------------
1138 //  stream_alloc - allocate a new stream with the
1139 //  new-style callback and flags
1140 //-------------------------------------------------
1141 
stream_alloc(device_t & device,u32 inputs,u32 outputs,u32 sample_rate,stream_update_delegate callback,sound_stream_flags flags)1142 sound_stream *sound_manager::stream_alloc(device_t &device, u32 inputs, u32 outputs, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags)
1143 {
1144 	// determine output base
1145 	u32 output_base = 0;
1146 	for (auto &stream : m_stream_list)
1147 		if (&stream->device() == &device)
1148 			output_base += stream->output_count();
1149 
1150 	m_stream_list.push_back(std::make_unique<sound_stream>(device, inputs, outputs, output_base, sample_rate, callback, flags));
1151 	return m_stream_list.back().get();
1152 }
1153 
1154 
1155 //-------------------------------------------------
1156 //  start_recording - begin audio recording
1157 //-------------------------------------------------
1158 
start_recording()1159 void sound_manager::start_recording()
1160 {
1161 	// open the output WAV file if specified
1162 	const char *wavfile = machine().options().wav_write();
1163 	if (wavfile[0] != 0 && m_wavfile == nullptr)
1164 		m_wavfile = wav_open(wavfile, machine().sample_rate(), 2);
1165 }
1166 
1167 
1168 //-------------------------------------------------
1169 //  stop_recording - end audio recording
1170 //-------------------------------------------------
1171 
stop_recording()1172 void sound_manager::stop_recording()
1173 {
1174 	// close any open WAV file
1175 	if (m_wavfile != nullptr)
1176 		wav_close(m_wavfile);
1177 	m_wavfile = nullptr;
1178 }
1179 
1180 
1181 //-------------------------------------------------
1182 //  set_attenuation - set the global volume
1183 //-------------------------------------------------
1184 
set_attenuation(float attenuation)1185 void sound_manager::set_attenuation(float attenuation)
1186 {
1187 	// currently OSD only supports integral attenuation
1188 	m_attenuation = int(attenuation);
1189 	machine().osd().set_mastervolume(m_muted ? -32 : m_attenuation);
1190 }
1191 
1192 
1193 //-------------------------------------------------
1194 //  indexed_mixer_input - return the mixer
1195 //  device and input index of the global mixer
1196 //  input
1197 //-------------------------------------------------
1198 
indexed_mixer_input(int index,mixer_input & info) const1199 bool sound_manager::indexed_mixer_input(int index, mixer_input &info) const
1200 {
1201 	// scan through the mixers until we find the indexed input
1202 	for (device_mixer_interface &mixer : mixer_interface_iterator(machine().root_device()))
1203 	{
1204 		if (index < mixer.inputs())
1205 		{
1206 			info.mixer = &mixer;
1207 			info.stream = mixer.input_to_stream_input(index, info.inputnum);
1208 			sound_assert(info.stream != nullptr);
1209 			return true;
1210 		}
1211 		index -= mixer.inputs();
1212 	}
1213 
1214 	// didn't locate
1215 	info.mixer = nullptr;
1216 	return false;
1217 }
1218 
1219 
1220 //-------------------------------------------------
1221 //  samples - fills the specified buffer with
1222 //  16-bit stereo audio samples generated during
1223 //  the current frame
1224 //-------------------------------------------------
1225 
samples(s16 * buffer)1226 void sound_manager::samples(s16 *buffer)
1227 {
1228 	for (int sample = 0; sample < m_samples_this_update * 2; sample++)
1229 		*buffer++ = m_finalmix[sample];
1230 }
1231 
1232 
1233 //-------------------------------------------------
1234 //  mute - mute sound output
1235 //-------------------------------------------------
1236 
mute(bool mute,u8 reason)1237 void sound_manager::mute(bool mute, u8 reason)
1238 {
1239 	if (mute)
1240 		m_muted |= reason;
1241 	else
1242 		m_muted &= ~reason;
1243 	set_attenuation(m_attenuation);
1244 }
1245 
1246 
1247 //-------------------------------------------------
1248 //  recursive_remove_stream_from_orphan_list -
1249 //  remove the given stream from the orphan list
1250 //  and recursively remove all our inputs
1251 //-------------------------------------------------
1252 
recursive_remove_stream_from_orphan_list(sound_stream * which)1253 void sound_manager::recursive_remove_stream_from_orphan_list(sound_stream *which)
1254 {
1255 	m_orphan_stream_list.erase(which);
1256 	for (int inputnum = 0; inputnum < which->input_count(); inputnum++)
1257 	{
1258 		auto &input = which->input(inputnum);
1259 		if (input.valid())
1260 			recursive_remove_stream_from_orphan_list(&input.source().stream());
1261 	}
1262 }
1263 
1264 
1265 //-------------------------------------------------
1266 //  apply_sample_rate_changes - recursively
1267 //  update sample rates throughout the system
1268 //-------------------------------------------------
1269 
apply_sample_rate_changes()1270 void sound_manager::apply_sample_rate_changes()
1271 {
1272 	// update sample rates if they have changed
1273 	for (speaker_device &speaker : speaker_device_iterator(machine().root_device()))
1274 	{
1275 		int stream_out;
1276 		sound_stream *stream = speaker.output_to_stream_output(0, stream_out);
1277 
1278 		// due to device removal, some speakers may end up with no outputs; just skip those
1279 		if (stream != nullptr)
1280 		{
1281 			sound_assert(speaker.outputs() == 1);
1282 			stream->apply_sample_rate_changes(m_update_number, machine().sample_rate());
1283 		}
1284 	}
1285 }
1286 
1287 
1288 //-------------------------------------------------
1289 //  reset - reset all sound chips
1290 //-------------------------------------------------
1291 
reset()1292 void sound_manager::reset()
1293 {
1294 	// reset all the sound chips
1295 	for (device_sound_interface &sound : sound_interface_iterator(machine().root_device()))
1296 		sound.device().reset();
1297 
1298 	// apply any sample rate changes now
1299 	apply_sample_rate_changes();
1300 
1301 	// on first reset, identify any orphaned streams
1302 	if (m_first_reset)
1303 	{
1304 		m_first_reset = false;
1305 
1306 		// put all the streams on the orphan list to start
1307 		for (auto &stream : m_stream_list)
1308 			m_orphan_stream_list[stream.get()] = 0;
1309 
1310 		// then walk the graph like we do on update and remove any we touch
1311 		for (speaker_device &speaker : speaker_device_iterator(machine().root_device()))
1312 		{
1313 			int dummy;
1314 			sound_stream *output = speaker.output_to_stream_output(0, dummy);
1315 			if (output != nullptr)
1316 				recursive_remove_stream_from_orphan_list(output);
1317 		}
1318 
1319 #if (SOUND_DEBUG)
1320 		// dump the sound graph when we start up
1321 		for (speaker_device &speaker : speaker_device_iterator(machine().root_device()))
1322 		{
1323 			int index;
1324 			sound_stream *output = speaker.output_to_stream_output(0, index);
1325 			if (output != nullptr)
1326 				output->print_graph_recursive(0, index);
1327 		}
1328 
1329 		// dump the orphan list as well
1330 		if (m_orphan_stream_list.size() != 0)
1331 		{
1332 			osd_printf_info("\nOrphaned streams:\n");
1333 			for (auto &stream : m_orphan_stream_list)
1334 				osd_printf_info("   %s\n", stream.first->name());
1335 		}
1336 #endif
1337 	}
1338 }
1339 
1340 
1341 //-------------------------------------------------
1342 //  pause - pause sound output
1343 //-------------------------------------------------
1344 
pause()1345 void sound_manager::pause()
1346 {
1347 	mute(true, MUTE_REASON_PAUSE);
1348 }
1349 
1350 
1351 //-------------------------------------------------
1352 //  resume - resume sound output
1353 //-------------------------------------------------
1354 
resume()1355 void sound_manager::resume()
1356 {
1357 	mute(false, MUTE_REASON_PAUSE);
1358 }
1359 
1360 
1361 //-------------------------------------------------
1362 //  config_load - read and apply data from the
1363 //  configuration file
1364 //-------------------------------------------------
1365 
config_load(config_type cfg_type,util::xml::data_node const * parentnode)1366 void sound_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
1367 {
1368 	// we only care about game files
1369 	if (cfg_type != config_type::GAME)
1370 		return;
1371 
1372 	// might not have any data
1373 	if (parentnode == nullptr)
1374 		return;
1375 
1376 	// iterate over channel nodes
1377 	for (util::xml::data_node const *channelnode = parentnode->get_child("channel"); channelnode != nullptr; channelnode = channelnode->get_next_sibling("channel"))
1378 	{
1379 		mixer_input info;
1380 		if (indexed_mixer_input(channelnode->get_attribute_int("index", -1), info))
1381 		{
1382 			float defvol = channelnode->get_attribute_float("defvol", 1.0f);
1383 			float newvol = channelnode->get_attribute_float("newvol", -1000.0f);
1384 			if (newvol != -1000.0f)
1385 				info.stream->input(info.inputnum).set_user_gain(newvol / defvol);
1386 		}
1387 	}
1388 }
1389 
1390 
1391 //-------------------------------------------------
1392 //  config_save - save data to the configuration
1393 //  file
1394 //-------------------------------------------------
1395 
config_save(config_type cfg_type,util::xml::data_node * parentnode)1396 void sound_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
1397 {
1398 	// we only care about game files
1399 	if (cfg_type != config_type::GAME)
1400 		return;
1401 
1402 	// iterate over mixer channels
1403 	if (parentnode != nullptr)
1404 		for (int mixernum = 0; ; mixernum++)
1405 		{
1406 			mixer_input info;
1407 			if (!indexed_mixer_input(mixernum, info))
1408 				break;
1409 			float newvol = info.stream->input(info.inputnum).user_gain();
1410 
1411 			if (newvol != 1.0f)
1412 			{
1413 				util::xml::data_node *const channelnode = parentnode->add_child("channel", nullptr);
1414 				if (channelnode != nullptr)
1415 				{
1416 					channelnode->set_attribute_int("index", mixernum);
1417 					channelnode->set_attribute_float("newvol", newvol);
1418 				}
1419 			}
1420 		}
1421 }
1422 
1423 
1424 //-------------------------------------------------
1425 //  adjust_toward_compressor_scale - adjust the
1426 //  current scale factor toward the current goal,
1427 //  in small increments
1428 //-------------------------------------------------
1429 
adjust_toward_compressor_scale(stream_buffer::sample_t curscale,stream_buffer::sample_t prevsample,stream_buffer::sample_t rawsample)1430 stream_buffer::sample_t sound_manager::adjust_toward_compressor_scale(stream_buffer::sample_t curscale, stream_buffer::sample_t prevsample, stream_buffer::sample_t rawsample)
1431 {
1432 	stream_buffer::sample_t proposed_scale = curscale;
1433 
1434 	// if we want to get larger, increment by 0.01
1435 	if (curscale < m_compressor_scale)
1436 	{
1437 		proposed_scale += 0.01f;
1438 		if (proposed_scale > m_compressor_scale)
1439 			proposed_scale = m_compressor_scale;
1440 	}
1441 
1442 	// otherwise, decrement by 0.01
1443 	else
1444 	{
1445 		proposed_scale -= 0.01f;
1446 		if (proposed_scale < m_compressor_scale)
1447 			proposed_scale = m_compressor_scale;
1448 	}
1449 
1450 	// compute the sample at the current scale and at the proposed scale
1451 	stream_buffer::sample_t cursample = rawsample * curscale;
1452 	stream_buffer::sample_t proposed_sample = rawsample * proposed_scale;
1453 
1454 	// if they trend in the same direction, it's ok to take the step
1455 	if ((cursample < prevsample && proposed_sample < prevsample) || (cursample > prevsample && proposed_sample > prevsample))
1456 		curscale = proposed_scale;
1457 
1458 	// return the current scale
1459 	return curscale;
1460 }
1461 
1462 
1463 //-------------------------------------------------
1464 //  update - mix everything down to its final form
1465 //  and send it to the OSD layer
1466 //-------------------------------------------------
1467 
update(void * ptr,int param)1468 void sound_manager::update(void *ptr, int param)
1469 {
1470 	VPRINTF(("sound_update\n"));
1471 
1472 	g_profiler.start(PROFILER_SOUND);
1473 
1474 	// determine the duration of this update
1475 	attotime update_period = machine().time() - m_last_update;
1476 	sound_assert(update_period.seconds() == 0);
1477 
1478 	// use that to compute the number of samples we need from the speakers
1479 	attoseconds_t sample_rate_attos = HZ_TO_ATTOSECONDS(machine().sample_rate());
1480 	m_samples_this_update = update_period.attoseconds() / sample_rate_attos;
1481 
1482 	// recompute the end time to an even sample boundary
1483 	attotime endtime = m_last_update + attotime(0, m_samples_this_update * sample_rate_attos);
1484 
1485 	// clear out the mix bufers
1486 	std::fill_n(&m_leftmix[0], m_samples_this_update, 0);
1487 	std::fill_n(&m_rightmix[0], m_samples_this_update, 0);
1488 
1489 	// force all the speaker streams to generate the proper number of samples
1490 	for (speaker_device &speaker : speaker_device_iterator(machine().root_device()))
1491 		speaker.mix(&m_leftmix[0], &m_rightmix[0], m_last_update, endtime, m_samples_this_update, (m_muted & MUTE_REASON_SYSTEM));
1492 
1493 	// determine the maximum in this section
1494 	stream_buffer::sample_t curmax = 0;
1495 	for (int sampindex = 0; sampindex < m_samples_this_update; sampindex++)
1496 	{
1497 		auto sample = m_leftmix[sampindex];
1498 		if (sample < 0)
1499 			sample = -sample;
1500 		if (sample > curmax)
1501 			curmax = sample;
1502 
1503 		sample = m_rightmix[sampindex];
1504 		if (sample < 0)
1505 			sample = -sample;
1506 		if (sample > curmax)
1507 			curmax = sample;
1508 	}
1509 
1510 	// pull in current compressor scale factor before modifying
1511 	stream_buffer::sample_t lscale = m_compressor_scale;
1512 	stream_buffer::sample_t rscale = m_compressor_scale;
1513 
1514 	// if we're above what the compressor will handle, adjust the compression
1515 	if (curmax * m_compressor_scale > 1.0)
1516 	{
1517 		m_compressor_scale = 1.0 / curmax;
1518 		m_compressor_counter = STREAMS_UPDATE_FREQUENCY / 5;
1519 	}
1520 
1521 	// if we're currently scaled, wait a bit to see if we can trend back toward 1.0
1522 	else if (m_compressor_counter != 0)
1523 		m_compressor_counter--;
1524 
1525 	// try to migrate toward 0 unless we're going to introduce clipping
1526 	else if (m_compressor_scale < 1.0 && curmax * 1.01 * m_compressor_scale < 1.0)
1527 	{
1528 		m_compressor_scale *= 1.01f;
1529 		if (m_compressor_scale > 1.0)
1530 			m_compressor_scale = 1.0;
1531 	}
1532 
1533 #if (SOUND_DEBUG)
1534 	if (lscale != m_compressor_scale)
1535 	printf("scale=%.5f\n", m_compressor_scale);
1536 #endif
1537 
1538 	// track whether there are pending scale changes in left/right
1539 	stream_buffer::sample_t lprev = 0, rprev = 0;
1540 
1541 	// now downmix the final result
1542 	u32 finalmix_step = machine().video().speed_factor();
1543 	u32 finalmix_offset = 0;
1544 	s16 *finalmix = &m_finalmix[0];
1545 	int sample;
1546 	for (sample = m_finalmix_leftover; sample < m_samples_this_update * 1000; sample += finalmix_step)
1547 	{
1548 		int sampindex = sample / 1000;
1549 
1550 		// ensure that changing the compression won't reverse direction to reduce "pops"
1551 		stream_buffer::sample_t lsamp = m_leftmix[sampindex];
1552 		if (lscale != m_compressor_scale && sample != m_finalmix_leftover)
1553 			lscale = adjust_toward_compressor_scale(lscale, lprev, lsamp);
1554 
1555 		// clamp the left side
1556 		lprev = lsamp *= lscale;
1557 		if (lsamp > 1.0)
1558 			lsamp = 1.0;
1559 		else if (lsamp < -1.0)
1560 			lsamp = -1.0;
1561 		finalmix[finalmix_offset++] = s16(lsamp * 32767.0);
1562 
1563 		// ensure that changing the compression won't reverse direction to reduce "pops"
1564 		stream_buffer::sample_t rsamp = m_rightmix[sampindex];
1565 		if (rscale != m_compressor_scale && sample != m_finalmix_leftover)
1566 			rscale = adjust_toward_compressor_scale(rscale, rprev, rsamp);
1567 
1568 		// clamp the left side
1569 		rprev = rsamp *= rscale;
1570 		if (rsamp > 1.0)
1571 			rsamp = 1.0;
1572 		else if (rsamp < -1.0)
1573 			rsamp = -1.0;
1574 		finalmix[finalmix_offset++] = s16(rsamp * 32767.0);
1575 	}
1576 	m_finalmix_leftover = sample - m_samples_this_update * 1000;
1577 
1578 	// play the result
1579 	if (finalmix_offset > 0)
1580 	{
1581 		if (!m_nosound_mode)
1582 			machine().osd().update_audio_stream(finalmix, finalmix_offset / 2);
1583 		machine().osd().add_audio_to_recording(finalmix, finalmix_offset / 2);
1584 		machine().video().add_sound_to_recording(finalmix, finalmix_offset / 2);
1585 		if (m_wavfile != nullptr)
1586 			wav_add_data_16(m_wavfile, finalmix, finalmix_offset);
1587 	}
1588 
1589 	// update any orphaned streams so they don't get too far behind
1590 	for (auto &stream : m_orphan_stream_list)
1591 		stream.first->update();
1592 
1593 	// remember the update time
1594 	m_last_update = endtime;
1595 	m_update_number++;
1596 
1597 	// apply sample rate changes
1598 	apply_sample_rate_changes();
1599 
1600 	// notify that new samples have been generated
1601 	emulator_info::sound_hook();
1602 
1603 	g_profiler.stop();
1604 }
1605