32
/***************************************************************************
34
***************************************************************************/
36
#define MAX_MIXER_CHANNELS 100
40
/***************************************************************************
42
***************************************************************************/
44
const device_type SPEAKER = speaker_device_config::static_alloc_device_config;
48
/***************************************************************************
50
***************************************************************************/
54
emu_timer *update_timer;
58
UINT32 finalmix_leftover;
73
/***************************************************************************
75
***************************************************************************/
77
static void sound_reset(running_machine &machine);
78
static void sound_exit(running_machine &machine);
79
static void sound_pause(running_machine &machine);
80
static void sound_resume(running_machine &machine);
81
static void sound_load(running_machine *machine, int config_type, xml_data_node *parentnode);
82
static void sound_save(running_machine *machine, int config_type, xml_data_node *parentnode);
83
static TIMER_CALLBACK( sound_update );
87
/***************************************************************************
89
***************************************************************************/
91
//-------------------------------------------------
92
// index_to_input - map an absolute index to
94
//-------------------------------------------------
96
INLINE speaker_device *index_to_input(running_machine *machine, int index, int &input)
59
//**************************************************************************
61
//**************************************************************************
65
//**************************************************************************
67
//**************************************************************************
69
const attotime sound_manager::STREAMS_UPDATE_ATTOTIME = attotime::from_hz(STREAMS_UPDATE_FREQUENCY);
73
//**************************************************************************
75
//**************************************************************************
77
//-------------------------------------------------
78
// sound_stream - constructor
79
//-------------------------------------------------
81
sound_stream::sound_stream(device_t &device, int inputs, int outputs, int sample_rate, void *param, stream_update_func callback)
84
m_sample_rate(sample_rate),
86
m_attoseconds_per_sample(0),
87
m_max_samples_per_update(0),
89
m_input((inputs == 0) ? NULL : auto_alloc_array_clear(device.machine(), stream_input, inputs)),
90
m_input_array((inputs == 0) ? NULL : auto_alloc_array_clear(device.machine(), stream_sample_t *, inputs)),
91
m_resample_bufalloc(0),
93
m_output((outputs == 0) ? NULL : auto_alloc_array_clear(device.machine(), stream_output, outputs)),
94
m_output_array((outputs == 0) ? NULL : auto_alloc_array_clear(device.machine(), stream_sample_t *, outputs)),
96
m_output_sampindex(0),
97
m_output_update_sampindex(0),
98
m_output_base_sampindex(0),
102
// get the device's sound interface
103
device_sound_interface *sound;
104
if (!device.interface(sound))
105
throw emu_fatalerror("Attempted to create a sound_stream with a non-sound device");
107
// this is also the implicit parameter if we are using our internal stub
108
if (m_callback == &sound_stream::device_stream_update_stub)
111
// create a unique tag for saving
113
state_tag.printf("%d", m_device.machine().sound().m_stream_list.count());
114
m_device.machine().state().save_item("stream", state_tag, 0, NAME(m_sample_rate));
115
m_device.machine().state().register_postload(state_postload_stub<sound_stream, &sound_stream::postload>, this);
117
// save the gain of each input and output
118
for (int inputnum = 0; inputnum < m_inputs; inputnum++)
119
m_device.machine().state().save_item("stream", state_tag, inputnum, NAME(m_input[inputnum].m_gain));
120
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
122
m_output[outputnum].m_stream = this;
123
m_device.machine().state().save_item("stream", state_tag, outputnum, NAME(m_output[outputnum].m_gain));
126
// force an update to the sample rates; this will cause everything to be recomputed
127
// and will generate the initial resample buffers for our inputs
128
recompute_sample_rate_data();
130
// set up the initial output buffer positions now that we have data
131
m_output_base_sampindex = -m_max_samples_per_update;
135
//-------------------------------------------------
136
// sample_time - return the emulation time of the
137
// next sample to be generated on the stream
138
//-------------------------------------------------
140
attotime sound_stream::sample_time() const
142
return attotime(m_device.machine().sound().last_update().seconds, 0) + attotime(0, m_output_sampindex * m_attoseconds_per_sample);
146
//-------------------------------------------------
147
// input_gain - return the input gain on a
148
// given stream's input
149
//-------------------------------------------------
151
float sound_stream::input_gain(int inputnum) const
153
assert(inputnum >= 0 && inputnum < m_inputs);
154
return float(m_input[inputnum].m_gain) / 256.0f;
158
//-------------------------------------------------
159
// initial_input_gain - return the original input
160
// gain on a given stream's input
161
//-------------------------------------------------
163
float sound_stream::initial_input_gain(int inputnum) const
165
assert(inputnum >= 0 && inputnum < m_inputs);
166
return float(m_input[inputnum].m_initial_gain) / 256.0f;
170
//-------------------------------------------------
171
// input_name - return the original input gain
172
// on a given stream's input
173
//-------------------------------------------------
175
const char *sound_stream::input_name(int inputnum, astring &string) const
177
// start with our device name and tag
178
assert(inputnum >= 0 && inputnum < m_inputs);
179
string.printf("%s '%s': ", m_device.name(), m_device.tag());
181
// if we have a source, indicate where the sound comes from by device name and tag
182
if (m_input[inputnum].m_source != NULL && m_input[inputnum].m_source->m_stream != NULL)
184
device_t &source = m_input[inputnum].m_source->m_stream->device();
185
string.catprintf("%s '%s'", source.name(), source.tag());
187
// get the sound interface; if there is more than 1 output we need to figure out which one
188
device_sound_interface *sound;
189
if (source.interface(sound) && sound->outputs() > 1)
191
// iterate over outputs until we find the stream that matches our source
192
// then look for a match on the output number
193
sound_stream *outstream;
195
for (int outputnum = 0; (outstream = sound->output_to_stream_output(outputnum, streamoutputnum)) != NULL; outputnum++)
196
if (outstream == m_input[inputnum].m_source->m_stream && m_input[inputnum].m_source == &outstream->m_output[streamoutputnum])
198
string.catprintf(" Ch.%d", outputnum);
207
//-------------------------------------------------
208
// output_gain - return the output gain on a
209
// given stream's output
210
//-------------------------------------------------
212
float sound_stream::output_gain(int outputnum) const
214
assert(outputnum >= 0 && outputnum < m_outputs);
215
return float(m_output[outputnum].m_gain) / 256.0f;
219
//-------------------------------------------------
220
// set_input - configure a stream's input
221
//-------------------------------------------------
223
void sound_stream::set_input(int index, sound_stream *input_stream, int output_index, float gain)
225
VPRINTF(("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", this, m_device.tag(), index, input_stream, output_index, gain));
227
// make sure it's a valid input
228
if (index >= m_inputs)
229
fatalerror("Fatal error: stream_set_input attempted to configure non-existant input %d (%d max)", index, m_inputs);
231
// make sure it's a valid output
232
if (input_stream != NULL && output_index >= input_stream->m_outputs)
233
fatalerror("Fatal error: stream_set_input attempted to use a non-existant output %d (%d max)", output_index, m_outputs);
235
// if this input is already wired, update the dependent info
236
stream_input &input = m_input[index];
237
if (input.m_source != NULL)
238
input.m_source->m_dependents--;
241
input.m_source = (input_stream != NULL) ? &input_stream->m_output[output_index] : NULL;
242
input.m_gain = input.m_initial_gain = int(0x100 * gain);
244
// update the dependent info
245
if (input.m_source != NULL)
246
input.m_source->m_dependents++;
248
// update sample rates now that we know the input
249
recompute_sample_rate_data();
253
//-------------------------------------------------
254
// update - force a stream to update to
255
// the current emulated time
256
//-------------------------------------------------
258
void sound_stream::update()
260
// determine the number of samples since the start of this second
261
attotime time = m_device.machine().time();
262
INT32 update_sampindex = INT32(time.attoseconds / m_attoseconds_per_sample);
264
// if we're ahead of the last update, then adjust upwards
265
attotime last_update = m_device.machine().sound().last_update();
266
if (time.seconds > last_update.seconds)
268
assert(time.seconds == last_update.seconds + 1);
269
update_sampindex += m_sample_rate;
272
// if we're behind the last update, then adjust downwards
273
if (time.seconds < last_update.seconds)
275
assert(time.seconds == last_update.seconds - 1);
276
update_sampindex -= m_sample_rate;
279
// generate samples to get us up to the appropriate time
280
g_profiler.start(PROFILER_SOUND);
281
assert(m_output_sampindex - m_output_base_sampindex >= 0);
282
assert(update_sampindex - m_output_base_sampindex <= m_output_bufalloc);
283
generate_samples(update_sampindex - m_output_sampindex);
286
// remember this info for next time
287
m_output_sampindex = update_sampindex;
291
//-------------------------------------------------
292
// output_since_last_update - return a pointer to
293
// the output buffer and the number of samples
294
// since the last global update
295
//-------------------------------------------------
297
const stream_sample_t *sound_stream::output_since_last_update(int outputnum, int &numsamples)
299
// force an update on the stream
302
// compute the number of samples and a pointer to the output buffer
303
numsamples = m_output_sampindex - m_output_update_sampindex;
304
return m_output[outputnum].m_buffer + (m_output_update_sampindex - m_output_base_sampindex);
308
//-------------------------------------------------
309
// set_sample_rate - set the sample rate on a
311
//-------------------------------------------------
313
void sound_stream::set_sample_rate(int new_rate)
315
// we will update this on the next global update
316
if (new_rate != sample_rate())
317
m_new_sample_rate = new_rate;
321
//-------------------------------------------------
322
// set_input_gain - set the input gain on a
323
// given stream's input
324
//-------------------------------------------------
326
void sound_stream::set_input_gain(int inputnum, float gain)
329
assert(inputnum >= 0 && inputnum < m_inputs);
330
m_input[inputnum].m_gain = int(0x100 * gain);
334
//-------------------------------------------------
335
// set_output_gain - set the output gain on a
336
// given stream's output
337
//-------------------------------------------------
339
void sound_stream::set_output_gain(int outputnum, float gain)
342
assert(outputnum >= 0 && outputnum < m_outputs);
343
m_output[outputnum].m_gain = int(0x100 * gain);
347
//-------------------------------------------------
348
// update_with_accounting - do a regular update,
349
// but also do periodic accounting
350
//-------------------------------------------------
352
void sound_stream::update_with_accounting(bool second_tick)
354
// do the normal update
357
// if we've ticked over another second, adjust all the counters that are relative to
358
// the current second
359
INT32 output_bufindex = m_output_sampindex - m_output_base_sampindex;
362
m_output_sampindex -= m_sample_rate;
363
m_output_base_sampindex -= m_sample_rate;
366
// note our current output sample
367
m_output_update_sampindex = m_output_sampindex;
369
// if we don't have enough output buffer space to hold two updates' worth of samples,
370
// we need to shuffle things down
371
if (m_output_bufalloc - output_bufindex < 2 * m_max_samples_per_update)
373
INT32 samples_to_lose = output_bufindex - m_max_samples_per_update;
374
if (samples_to_lose > 0)
376
// if we have samples to move, do so for each output
377
if (output_bufindex > 0)
378
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
380
stream_output &output = m_output[outputnum];
381
memmove(&output.m_buffer[0], &output.m_buffer[samples_to_lose], sizeof(output.m_buffer[0]) * (output_bufindex - samples_to_lose));
384
// update the base position
385
m_output_base_sampindex += samples_to_lose;
391
//-------------------------------------------------
392
// apply_sample_rate_changes - if there is a
393
// pending sample rate change, apply it now
394
//-------------------------------------------------
396
void sound_stream::apply_sample_rate_changes()
398
// skip if nothing to do
399
if (m_new_sample_rate == 0)
402
// update to the new rate and remember the old rate
403
UINT32 old_rate = m_sample_rate;
404
m_sample_rate = m_new_sample_rate;
405
m_new_sample_rate = 0;
407
// recompute all the data
408
recompute_sample_rate_data();
410
// reset our sample indexes to the current time
411
m_output_sampindex = (INT64)m_output_sampindex * (INT64)m_sample_rate / old_rate;
412
m_output_update_sampindex = (INT64)m_output_update_sampindex * (INT64)m_sample_rate / old_rate;
413
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
415
// clear out the buffer
416
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
417
memset(m_output[outputnum].m_buffer, 0, m_max_samples_per_update * sizeof(m_output[outputnum].m_buffer[0]));
421
//-------------------------------------------------
422
// device_stream_update_stub - stub callback for
423
// passing through to modern devices
424
//-------------------------------------------------
426
STREAM_UPDATE( sound_stream::device_stream_update_stub )
428
device_sound_interface *sound = reinterpret_cast<device_sound_interface *>(param);
429
sound->sound_stream_update(*stream, inputs, outputs, samples);
433
//-------------------------------------------------
434
// recompute_sample_rate_data - recompute sample
435
// rate data, and all streams that are affected
437
//-------------------------------------------------
439
void sound_stream::recompute_sample_rate_data()
441
// recompute the timing parameters
442
attoseconds_t update_attoseconds = m_device.machine().sound().update_attoseconds();
443
m_attoseconds_per_sample = ATTOSECONDS_PER_SECOND / m_sample_rate;
444
m_max_samples_per_update = (update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample;
446
// update resample and output buffer sizes
447
allocate_resample_buffers();
448
allocate_output_buffers();
450
// iterate over each input
451
for (int inputnum = 0; inputnum < m_inputs; inputnum++)
453
// if we have a source, see if its sample rate changed
454
stream_input &input = m_input[inputnum];
455
if (input.m_source != NULL)
457
// okay, we have a new sample rate; recompute the latency to be the maximum
458
// sample period between us and our input
459
attoseconds_t new_attosecs_per_sample = ATTOSECONDS_PER_SECOND / input.m_source->m_stream->m_sample_rate;
460
attoseconds_t latency = MAX(new_attosecs_per_sample, m_attoseconds_per_sample);
462
// if the input stream's sample rate is lower, we will use linear interpolation
463
// this requires an extra sample from the source
464
if (input.m_source->m_stream->m_sample_rate < m_sample_rate)
465
latency += new_attosecs_per_sample;
467
// if our sample rates match exactly, we don't need any latency
468
else if (input.m_source->m_stream->m_sample_rate == m_sample_rate)
471
// we generally don't want to tweak the latency, so we just keep the greatest
472
// one we've computed thus far
473
input.m_latency_attoseconds = MAX(input.m_latency_attoseconds, latency);
474
assert(input.m_latency_attoseconds < update_attoseconds);
480
//-------------------------------------------------
481
// allocate_resample_buffers - recompute the
482
// resample buffer sizes and expand if necessary
483
//-------------------------------------------------
485
void sound_stream::allocate_resample_buffers()
487
// compute the target number of samples
488
INT32 bufsize = 2 * m_max_samples_per_update;
490
// if we don't have enough room, allocate more
491
if (m_resample_bufalloc < bufsize)
493
// this becomes the new allocation size
494
int oldsize = m_resample_bufalloc;
495
m_resample_bufalloc = bufsize;
497
// iterate over outputs and realloc their buffers
498
for (int inputnum = 0; inputnum < m_inputs; inputnum++)
500
stream_input &input = m_input[inputnum];
501
stream_sample_t *newbuffer = auto_alloc_array(m_device.machine(), stream_sample_t, m_resample_bufalloc);
502
memcpy(newbuffer, input.m_resample, oldsize * sizeof(stream_sample_t));
503
auto_free(m_device.machine(), input.m_resample);
504
input.m_resample = newbuffer;
510
//-------------------------------------------------
511
// allocate_output_buffers - recompute the
512
// output buffer sizes and expand if necessary
513
//-------------------------------------------------
515
void sound_stream::allocate_output_buffers()
517
// if we don't have enough room, allocate more
518
INT32 bufsize = OUTPUT_BUFFER_UPDATES * m_max_samples_per_update;
519
if (m_output_bufalloc < bufsize)
521
// this becomes the new allocation size
522
int oldsize = m_output_bufalloc;
523
m_output_bufalloc = bufsize;
525
// iterate over outputs and realloc their buffers
526
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
528
stream_output &output = m_output[outputnum];
529
stream_sample_t *newbuffer = auto_alloc_array(m_device.machine(), stream_sample_t, m_output_bufalloc);
530
memcpy(newbuffer, output.m_buffer, oldsize * sizeof(stream_sample_t));
531
memset(newbuffer + oldsize, 0, (m_output_bufalloc - oldsize) * sizeof(stream_sample_t));
532
auto_free(m_device.machine(), output.m_buffer);
533
output.m_buffer = newbuffer;
539
//-------------------------------------------------
540
// postload - save/restore callback
541
//-------------------------------------------------
543
void sound_stream::postload()
545
// recompute the same rate information
546
recompute_sample_rate_data();
548
// make sure our output buffers are fully cleared
549
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
550
memset(m_output[outputnum].m_buffer, 0, m_output_bufalloc * sizeof(m_output[outputnum].m_buffer[0]));
552
// recompute the sample indexes to make sense
553
m_output_sampindex = m_device.machine().sound().last_update().attoseconds / m_attoseconds_per_sample;
554
m_output_update_sampindex = m_output_sampindex;
555
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
559
//-------------------------------------------------
560
// generate_samples - generate the requested
561
// number of samples for a stream, making sure
562
// all inputs have the appropriate number of
564
//-------------------------------------------------
566
void sound_stream::generate_samples(int samples)
568
// if we're already there, skip it
572
VPRINTF(("generate_samples(%p, %d)\n", this, samples));
574
// ensure all inputs are up to date and generate resampled data
575
for (int inputnum = 0; inputnum < m_inputs; inputnum++)
577
// update the stream to the current time
578
stream_input &input = m_input[inputnum];
579
if (input.m_source != NULL)
580
input.m_source->m_stream->update();
582
// generate the resampled data
583
m_input_array[inputnum] = generate_resampled_data(input, samples);
586
// loop over all outputs and compute the output pointer
587
for (int outputnum = 0; outputnum < m_outputs; outputnum++)
589
stream_output &output = m_output[outputnum];
590
m_output_array[outputnum] = output.m_buffer + (m_output_sampindex - m_output_base_sampindex);
594
VPRINTF((" callback(%p, %d)\n", this, samples));
595
(*m_callback)(&m_device, this, m_param, m_input_array, m_output_array, samples);
596
VPRINTF((" callback done\n"));
600
//-------------------------------------------------
601
// generate_resampled_data - generate the
602
// resample buffer for a given input
603
//-------------------------------------------------
605
stream_sample_t *sound_stream::generate_resampled_data(stream_input &input, UINT32 numsamples)
607
// if we don't have an output to pull data from, generate silence
608
stream_sample_t *dest = input.m_resample;
609
if (input.m_source == NULL)
611
memset(dest, 0, numsamples * sizeof(*dest));
612
return input.m_resample;
615
// grab data from the output
616
stream_output &output = *input.m_source;
617
sound_stream &input_stream = *output.m_stream;
618
int gain = (input.m_gain * output.m_gain) >> 8;
620
// determine the time at which the current sample begins, accounting for the
621
// latency we calculated between the input and output streams
622
attoseconds_t basetime = m_output_sampindex * m_attoseconds_per_sample - input.m_latency_attoseconds;
624
// now convert that time into a sample in the input stream
627
basesample = basetime / input_stream.m_attoseconds_per_sample;
629
basesample = -(-basetime / input_stream.m_attoseconds_per_sample) - 1;
631
// compute a source pointer to the first sample
632
assert(basesample >= input_stream.m_output_base_sampindex);
633
stream_sample_t *source = output.m_buffer + (basesample - input_stream.m_output_base_sampindex);
635
// determine the current fraction of a sample
636
UINT32 basefrac = (basetime - basesample * input_stream.m_attoseconds_per_sample) / ((input_stream.m_attoseconds_per_sample + FRAC_ONE - 1) >> FRAC_BITS);
637
assert(basefrac >= 0);
638
assert(basefrac < FRAC_ONE);
640
// compute the stepping fraction
641
UINT32 step = ((UINT64)input_stream.m_sample_rate << FRAC_BITS) / m_sample_rate;
643
// if we have equal sample rates, we just need to copy
644
if (step == FRAC_ONE)
648
// compute the sample
649
stream_sample_t sample = *source++;
650
*dest++ = (sample * gain) >> 8;
654
// input is undersampled: point sample except where our sample period covers a boundary
655
else if (step < FRAC_ONE)
657
while (numsamples != 0)
659
// fill in with point samples until we hit a boundary
661
while ((nextfrac = basefrac + step) < FRAC_ONE && numsamples--)
663
*dest++ = (source[0] * gain) >> 8;
667
// if we're done, we're done
668
if ((INT32)numsamples-- < 0)
671
// compute starting and ending fractional positions
672
int startfrac = basefrac >> (FRAC_BITS - 12);
673
int endfrac = nextfrac >> (FRAC_BITS - 12);
675
// blend between the two samples accordingly
676
stream_sample_t sample = (source[0] * (0x1000 - startfrac) + source[1] * (endfrac - 0x1000)) / (endfrac - startfrac);
677
*dest++ = (sample * gain) >> 8;
680
basefrac = nextfrac & FRAC_MASK;
685
// input is oversampled: sum the energy
688
// use 8 bits to allow some extra headroom
689
int smallstep = step >> (FRAC_BITS - 8);
692
int remainder = smallstep;
695
// compute the sample
696
int scale = (FRAC_ONE - basefrac) >> (FRAC_BITS - 8);
697
stream_sample_t sample = source[tpos++] * scale;
699
while (remainder > 0x100)
701
sample += source[tpos++] * 0x100;
704
sample += source[tpos] * remainder;
707
*dest++ = (sample * gain) >> 8;
711
source += basefrac >> FRAC_BITS;
712
basefrac &= FRAC_MASK;
716
return input.m_resample;
721
//**************************************************************************
723
//**************************************************************************
725
//-------------------------------------------------
726
// stream_input - constructor
727
//-------------------------------------------------
729
sound_stream::stream_input::stream_input()
734
m_latency_attoseconds(0),
736
m_initial_gain(0x100)
742
//**************************************************************************
744
//**************************************************************************
746
//-------------------------------------------------
747
// stream_output - constructor
748
//-------------------------------------------------
750
sound_stream::stream_output::stream_output()
759
//**************************************************************************
761
//**************************************************************************
763
//-------------------------------------------------
764
// sound_manager - constructor
765
//-------------------------------------------------
767
sound_manager::sound_manager(running_machine &machine)
768
: m_machine(machine),
769
m_update_timer(machine.scheduler().timer_alloc(FUNC(update_static), this)),
770
m_finalmix_leftover(0),
776
m_nosound_mode(!machine.options().sound()),
778
m_stream_list(machine.respool()),
779
m_update_attoseconds(STREAMS_UPDATE_ATTOTIME.attoseconds),
780
m_last_update(attotime::zero)
782
// get filename for WAV file or AVI file if specified
783
const char *wavfile = machine.options().wav_write();
784
const char *avifile = machine.options().avi_write();
786
// handle -nosound and lower sample rate if not recording WAV or AVI
787
if (m_nosound_mode && wavfile[0] == 0 && avifile[0] == 0)
788
machine.m_sample_rate = 11025;
790
// count the speakers
791
VPRINTF(("total speakers = %d\n", machine.m_devicelist.count(SPEAKER)));
793
// allocate memory for mix buffers
794
m_leftmix = auto_alloc_array(machine, INT32, machine.sample_rate());
795
m_rightmix = auto_alloc_array(machine, INT32, machine.sample_rate());
796
m_finalmix = auto_alloc_array(machine, INT16, machine.sample_rate());
798
// open the output WAV file if specified
800
m_wavfile = wav_open(wavfile, machine.sample_rate(), 2);
802
// register callbacks
803
config_register(machine, "mixer", &sound_manager::config_load, &sound_manager::config_save);
804
machine.add_notifier(MACHINE_NOTIFY_PAUSE, &sound_manager::pause);
805
machine.add_notifier(MACHINE_NOTIFY_RESUME, &sound_manager::resume);
806
machine.add_notifier(MACHINE_NOTIFY_RESET, &sound_manager::reset);
808
// register global states
809
state_save_register_global(machine, m_last_update);
811
// set the starting attenuation
812
set_attenuation(machine.options().volume());
814
// start the periodic update flushing timer
815
m_update_timer->adjust(STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME);
819
//-------------------------------------------------
820
// sound_manager - destructor
821
//-------------------------------------------------
823
sound_manager::~sound_manager()
825
// close any open WAV file
826
if (m_wavfile != NULL)
827
wav_close(m_wavfile);
832
//-------------------------------------------------
833
// stream_alloc - allocate a new stream
834
//-------------------------------------------------
836
sound_stream *sound_manager::stream_alloc(device_t &device, int inputs, int outputs, int sample_rate, void *param, sound_stream::stream_update_func callback)
838
if (callback != NULL)
839
return &m_stream_list.append(*auto_alloc(device.machine(), sound_stream(device, inputs, outputs, sample_rate, param, callback)));
841
return &m_stream_list.append(*auto_alloc(device.machine(), sound_stream(device, inputs, outputs, sample_rate)));
845
//-------------------------------------------------
846
// set_attenuation - set the global volume
847
//-------------------------------------------------
849
void sound_manager::set_attenuation(int attenuation)
851
m_attenuation = attenuation;
852
m_machine.osd().set_mastervolume(m_muted ? -32 : m_attenuation);
856
//-------------------------------------------------
857
// indexed_speaker_input - return the speaker
858
// device and input index of the global speaker
860
//-------------------------------------------------
862
bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const
98
864
// scan through the speakers until we find the indexed input
99
for (speaker_device *speaker = speaker_first(*machine); speaker != NULL; speaker = speaker_next(speaker))
865
for (info.speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); info.speaker != NULL; info.speaker = info.speaker->next_speaker())
101
if (index < speaker->inputs())
867
if (index < info.speaker->inputs())
869
info.stream = info.speaker->input_to_stream_input(index, info.inputnum);
870
assert(info.stream != NULL);
106
index -= speaker->inputs();
873
index -= info.speaker->inputs();
109
// index out of range
115
/***************************************************************************
117
***************************************************************************/
119
/*-------------------------------------------------
120
sound_init - start up the sound system
121
-------------------------------------------------*/
123
void sound_init(running_machine *machine)
125
sound_private *global;
126
const char *filename;
127
const char *filenameavi;
129
machine->sound_data = global = auto_alloc_clear(machine, sound_private);
131
/* get filename for WAV file or AVI file if specified */
132
filename = options_get_string(machine->options(), OPTION_WAVWRITE);
133
filenameavi = options_get_string(machine->options(), OPTION_AVIWRITE);
135
/* handle -nosound and lower sample rate if not recording WAV or AVI*/
136
global->nosound_mode = !options_get_bool(machine->options(), OPTION_SOUND);
137
if (global->nosound_mode && filename[0] == 0 && filenameavi[0] == 0)
138
machine->sample_rate = 11025;
140
/* count the speakers */
141
VPRINTF(("total speakers = %d\n", speaker_output_count(machine->config)));
143
/* allocate memory for mix buffers */
144
global->leftmix = auto_alloc_array(machine, INT32, machine->sample_rate);
145
global->rightmix = auto_alloc_array(machine, INT32, machine->sample_rate);
146
global->finalmix = auto_alloc_array(machine, INT16, machine->sample_rate);
148
/* allocate a global timer for sound timing */
149
global->update_timer = timer_alloc(machine, sound_update, NULL);
150
timer_adjust_periodic(global->update_timer, STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME);
152
/* open the output WAV file if specified */
153
if (filename[0] != 0)
154
global->wavfile = wav_open(filename, machine->sample_rate, 2);
156
/* enable sound by default */
157
global->enabled = TRUE;
158
global->muted = FALSE;
159
sound_set_attenuation(machine, options_get_int(machine->options(), OPTION_VOLUME));
161
/* register callbacks */
162
config_register(machine, "mixer", sound_load, sound_save);
163
machine->add_notifier(MACHINE_NOTIFY_PAUSE, sound_pause);
164
machine->add_notifier(MACHINE_NOTIFY_RESUME, sound_resume);
165
machine->add_notifier(MACHINE_NOTIFY_RESET, sound_reset);
166
machine->add_notifier(MACHINE_NOTIFY_EXIT, sound_exit);
170
/*-------------------------------------------------
171
sound_exit - clean up after ourselves
172
-------------------------------------------------*/
174
static void sound_exit(running_machine &machine)
176
sound_private *global = machine.sound_data;
178
/* close any open WAV file */
179
if (global->wavfile != NULL)
180
wav_close(global->wavfile);
181
global->wavfile = NULL;
183
/* reset variables */
184
global->totalsnd = 0;
189
/***************************************************************************
190
GLOBAL STATE MANAGEMENT
191
***************************************************************************/
193
/*-------------------------------------------------
194
sound_reset - reset all sound chips
195
-------------------------------------------------*/
197
static void sound_reset(running_machine &machine)
881
//-------------------------------------------------
882
// mute - mute sound output
883
//-------------------------------------------------
885
void sound_manager::mute(bool mute, UINT8 reason)
891
set_attenuation(m_attenuation);
895
//-------------------------------------------------
896
// reset - reset all sound chips
897
//-------------------------------------------------
899
void sound_manager::reset(running_machine &machine)
901
// reset all the sound chips
199
902
device_sound_interface *sound = NULL;
201
/* reset all the sound chips */
202
903
for (bool gotone = machine.m_devicelist.first(sound); gotone; gotone = sound->next(sound))
203
904
sound->device().reset();
207
/*-------------------------------------------------
208
sound_pause - pause sound output
209
-------------------------------------------------*/
211
static void sound_pause(running_machine &machine)
213
sound_private *global = machine.sound_data;
214
global->muted |= 0x02;
215
machine.osd().set_mastervolume(global->muted ? -32 : global->attenuation);
218
static void sound_resume(running_machine &machine)
220
sound_private *global = machine.sound_data;
221
global->muted &= ~0x02;
222
machine.osd().set_mastervolume(global->muted ? -32 : global->attenuation);
226
/*-------------------------------------------------
227
sound_mute - mute sound output
228
-------------------------------------------------*/
230
void sound_mute(running_machine *machine, int mute)
232
sound_private *global = machine->sound_data;
235
global->muted |= 0x01;
237
global->muted &= ~0x01;
238
machine->osd().set_mastervolume(global->muted ? -32 : global->attenuation);
242
/*-------------------------------------------------
243
sound_set_attenuation - set the global volume
244
-------------------------------------------------*/
246
void sound_set_attenuation(running_machine *machine, int attenuation)
248
sound_private *global = machine->sound_data;
249
global->attenuation = attenuation;
250
machine->osd().set_mastervolume(global->muted ? -32 : global->attenuation);
254
/*-------------------------------------------------
255
sound_get_attenuation - return the global
257
-------------------------------------------------*/
259
int sound_get_attenuation(running_machine *machine)
261
sound_private *global = machine->sound_data;
262
return global->attenuation;
266
/*-------------------------------------------------
267
sound_global_enable - enable/disable sound
269
-------------------------------------------------*/
271
void sound_global_enable(running_machine *machine, int enable)
273
sound_private *global = machine->sound_data;
274
global->enabled = enable;
279
/***************************************************************************
281
***************************************************************************/
283
/*-------------------------------------------------
284
sound_load - read and apply data from the
286
-------------------------------------------------*/
288
static void sound_load(running_machine *machine, int config_type, xml_data_node *parentnode)
290
xml_data_node *channelnode;
293
/* we only care about game files */
908
//-------------------------------------------------
909
// pause - pause sound output
910
//-------------------------------------------------
912
void sound_manager::pause(running_machine &machine)
914
machine.sound().mute(true, MUTE_REASON_PAUSE);
918
//-------------------------------------------------
919
// resume - resume sound output
920
//-------------------------------------------------
922
void sound_manager::resume(running_machine &machine)
924
machine.sound().mute(false, MUTE_REASON_PAUSE);
928
//-------------------------------------------------
929
// config_load - read and apply data from the
930
// configuration file
931
//-------------------------------------------------
933
void sound_manager::config_load(running_machine &machine, int config_type, xml_data_node *parentnode)
935
// we only care about game files
294
936
if (config_type != CONFIG_TYPE_GAME)
297
/* might not have any data */
939
// might not have any data
298
940
if (parentnode == NULL)
301
/* iterate over channel nodes */
302
for (channelnode = xml_get_sibling(parentnode->child, "channel"); channelnode; channelnode = xml_get_sibling(channelnode->next, "channel"))
943
// iterate over channel nodes
944
for (xml_data_node *channelnode = xml_get_sibling(parentnode->child, "channel"); channelnode != NULL; channelnode = xml_get_sibling(channelnode->next, "channel"))
304
mixernum = xml_get_attribute_int(channelnode, "index", -1);
305
if (mixernum >= 0 && mixernum < MAX_MIXER_CHANNELS)
947
if (machine.sound().indexed_speaker_input(xml_get_attribute_int(channelnode, "index", -1), info))
307
949
float defvol = xml_get_attribute_float(channelnode, "defvol", -1000.0);
308
950
float newvol = xml_get_attribute_float(channelnode, "newvol", -1000.0);
309
if (fabs(defvol - sound_get_default_gain(machine, mixernum)) < 1e-6 && newvol != -1000.0)
310
sound_set_user_gain(machine, mixernum, newvol);
951
if (fabs(defvol - info.stream->initial_input_gain(info.inputnum)) < 1e-6 && newvol != -1000.0)
952
info.stream->set_input_gain(info.inputnum, newvol);
316
/*-------------------------------------------------
317
sound_save - save data to the configuration
319
-------------------------------------------------*/
958
//-------------------------------------------------
959
// config_save - save data to the configuration
961
//-------------------------------------------------
321
static void sound_save(running_machine *machine, int config_type, xml_data_node *parentnode)
963
void sound_manager::config_save(running_machine &machine, int config_type, xml_data_node *parentnode)
325
/* we only care about game files */
965
// we only care about game files
326
966
if (config_type != CONFIG_TYPE_GAME)
329
/* iterate over mixer channels */
969
// iterate over mixer channels
330
970
if (parentnode != NULL)
331
for (mixernum = 0; mixernum < MAX_MIXER_CHANNELS; mixernum++)
971
for (int mixernum = 0; ; mixernum++)
333
float defvol = sound_get_default_gain(machine, mixernum);
334
float newvol = sound_get_user_gain(machine, mixernum);
974
if (!machine.sound().indexed_speaker_input(mixernum, info))
976
float defvol = info.stream->initial_input_gain(info.inputnum);
977
float newvol = info.stream->input_gain(info.inputnum);
336
979
if (defvol != newvol)
351
/***************************************************************************
353
***************************************************************************/
355
/*-------------------------------------------------
356
sound_update - mix everything down to
357
its final form and send it to the OSD layer
358
-------------------------------------------------*/
360
static TIMER_CALLBACK( sound_update )
993
//-------------------------------------------------
994
// update - mix everything down to its final form
995
// and send it to the OSD layer
996
//-------------------------------------------------
998
void sound_manager::update()
362
UINT32 finalmix_step, finalmix_offset;
1000
VPRINTF(("sound_update\n"));
1002
g_profiler.start(PROFILER_SOUND);
1004
// force all the speaker streams to generate the proper number of samples
363
1005
int samples_this_update = 0;
1006
for (speaker_device *speaker = downcast<speaker_device *>(m_machine.m_devicelist.first(SPEAKER)); speaker != NULL; speaker = speaker->next_speaker())
1007
speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM));
1009
// now downmix the final result
1010
UINT32 finalmix_step = m_machine.video().speed_factor();
1011
UINT32 finalmix_offset = 0;
1012
INT16 *finalmix = m_finalmix;
365
sound_private *global = machine->sound_data;
367
INT32 *leftmix, *rightmix;
369
VPRINTF(("sound_update\n"));
371
g_profiler.start(PROFILER_SOUND);
373
leftmix = global->leftmix;
374
rightmix = global->rightmix;
375
finalmix = global->finalmix;
377
/* force all the speaker streams to generate the proper number of samples */
378
for (speaker_device *speaker = speaker_first(*machine); speaker != NULL; speaker = speaker_next(speaker))
379
speaker->mix(leftmix, rightmix, samples_this_update, !global->enabled);
381
/* now downmix the final result */
382
finalmix_step = machine->video().speed_factor();
384
for (sample = global->finalmix_leftover; sample < samples_this_update * 100; sample += finalmix_step)
1014
for (sample = m_finalmix_leftover; sample < samples_this_update * 100; sample += finalmix_step)
386
1016
int sampindex = sample / 100;
389
/* clamp the left side */
390
samp = leftmix[sampindex];
1018
// clamp the left side
1019
INT32 samp = m_leftmix[sampindex];
391
1020
if (samp < -32768)
393
1022
else if (samp > 32767)
395
1024
finalmix[finalmix_offset++] = samp;
397
/* clamp the right side */
398
samp = rightmix[sampindex];
1026
// clamp the right side
1027
samp = m_rightmix[sampindex];
399
1028
if (samp < -32768)
401
1030
else if (samp > 32767)
403
1032
finalmix[finalmix_offset++] = samp;
405
global->finalmix_leftover = sample - samples_this_update * 100;
1034
m_finalmix_leftover = sample - samples_this_update * 100;
407
/* play the result */
408
1037
if (finalmix_offset > 0)
410
if (!global->nosound_mode)
411
machine->osd().update_audio_stream(finalmix, finalmix_offset / 2);
412
machine->video().add_sound_to_recording(finalmix, finalmix_offset / 2);
413
if (global->wavfile != NULL)
414
wav_add_data_16(global->wavfile, finalmix, finalmix_offset);
417
/* update the streamer */
418
streams_update(machine);
1039
if (!m_nosound_mode)
1040
m_machine.osd().update_audio_stream(finalmix, finalmix_offset / 2);
1041
m_machine.video().add_sound_to_recording(finalmix, finalmix_offset / 2);
1042
if (m_wavfile != NULL)
1043
wav_add_data_16(m_wavfile, finalmix, finalmix_offset);
1046
// see if we ticked over to the next second
1047
attotime curtime = m_machine.time();
1048
bool second_tick = false;
1049
if (curtime.seconds != m_last_update.seconds)
1051
assert(curtime.seconds == m_last_update.seconds + 1);
1055
// iterate over all the streams and update them
1056
for (sound_stream *stream = m_stream_list.first(); stream != NULL; stream = stream->next())
1057
stream->update_with_accounting(second_tick);
1059
// remember the update time
1060
m_last_update = curtime;
1062
// update sample rates if they have changed
1063
for (sound_stream *stream = m_stream_list.first(); stream != NULL; stream = stream->next())
1064
stream->apply_sample_rate_changes();
420
1066
g_profiler.stop();
425
//**************************************************************************
426
// SPEAKER DEVICE CONFIGURATION
427
//**************************************************************************
429
//-------------------------------------------------
430
// speaker_device_config - constructor
431
//-------------------------------------------------
433
speaker_device_config::speaker_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
434
: device_config(mconfig, static_alloc_device_config, "Speaker", tag, owner, clock),
442
//-------------------------------------------------
443
// static_alloc_device_config - allocate a new
444
// configuration object
445
//-------------------------------------------------
447
device_config *speaker_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
449
return global_alloc(speaker_device_config(mconfig, tag, owner, clock));
453
//-------------------------------------------------
454
// alloc_device - allocate a new device object
455
//-------------------------------------------------
457
device_t *speaker_device_config::alloc_device(running_machine &machine) const
459
return auto_alloc(&machine, speaker_device(machine, *this));
463
//-------------------------------------------------
464
// static_set_position - configuration helper to
465
// set the speaker position
466
//-------------------------------------------------
468
void speaker_device_config::static_set_position(device_config *device, double x, double y, double z)
470
speaker_device_config *speaker = downcast<speaker_device_config *>(device);
478
//**************************************************************************
479
// LIVE SPEAKER DEVICE
480
//**************************************************************************
482
//-------------------------------------------------
483
// speaker_device - constructor
484
//-------------------------------------------------
486
speaker_device::speaker_device(running_machine &_machine, const speaker_device_config &config)
487
: device_t(_machine, config),
489
m_mixer_stream(NULL),
495
m_clipped_samples(0),
502
//-------------------------------------------------
503
// ~speaker_device - destructor
504
//-------------------------------------------------
506
speaker_device::~speaker_device()
509
// log the maximum sample values for all speakers
510
if (m_max_sample > 0)
511
mame_printf_debug("Speaker \"%s\" - max = %d (gain *= %f) - %d%% samples clipped\n", tag(), m_max_sample, 32767.0 / (m_max_sample ? m_max_sample : 1), (int)((double)m_clipped_samples * 100.0 / m_total_samples));
512
#endif /* MAME_DEBUG */
516
//-------------------------------------------------
517
// device_start - perform device-specific
519
//-------------------------------------------------
521
void speaker_device::device_start()
523
// scan all the sound devices and count our inputs
525
device_sound_interface *sound = NULL;
526
for (bool gotone = machine->m_devicelist.first(sound); gotone; gotone = sound->next(sound))
528
// scan each route on the device
529
for (const device_config_sound_interface::sound_route *route = sound->sound_config().m_route_list; route != NULL; route = route->m_next)
531
// if we are the target of this route, accumulate inputs
532
device_t *target_device = machine->device(route->m_target);
533
if (target_device == this)
535
// if the sound device is not yet started, bail however -- we need the its stream
536
if (!sound->device().started())
537
throw device_missing_dependencies();
540
inputs += (route->m_output == ALL_OUTPUTS) ? stream_get_device_outputs(*sound) : 1;
545
// no inputs? that's weird
548
logerror("Warning: speaker \"%s\" has no inputs\n", tag());
552
// now we know how many inputs; allocate the mixers and input data
553
m_mixer_stream = stream_create(this, inputs, 1, machine->sample_rate, NULL, static_mixer_update);
554
m_input = auto_alloc_array(machine, speaker_input, inputs);
557
// iterate again over all the sound devices
558
for (bool gotone = machine->m_devicelist.first(sound); gotone; gotone = sound->next(sound))
560
// scan each route on the device
561
for (const device_config_sound_interface::sound_route *route = sound->sound_config().m_route_list; route != NULL; route = route->m_next)
563
// if we are the target of this route, hook it up
564
device_t *target_device = machine->device(route->m_target);
565
if (target_device == this)
567
// iterate over all outputs, matching any that apply
568
int numoutputs = stream_get_device_outputs(*sound);
569
for (int outputnum = 0; outputnum < numoutputs; outputnum++)
570
if (route->m_output == outputnum || route->m_output == ALL_OUTPUTS)
572
// fill in the input data on this speaker
573
m_input[m_inputs].m_gain = route->m_gain;
574
m_input[m_inputs].m_default_gain = route->m_gain;
575
m_input[m_inputs].m_name.printf("Speaker '%s': %s '%s'", tag(), sound->device().name(), sound->device().tag());
577
m_input[m_inputs].m_name.catprintf(" Ch.%d", outputnum);
579
// connect the output to the input
580
sound_stream *stream;
582
if (stream_device_output_to_stream_output(*sound, outputnum, &stream, &streamoutput))
583
stream_set_input(m_mixer_stream, m_inputs++, stream, streamoutput, route->m_gain);
591
//-------------------------------------------------
592
// device_post_load - after we load a save state
593
// be sure to update the mixer stream's output
595
//-------------------------------------------------
597
void speaker_device::device_post_load()
599
stream_set_sample_rate(m_mixer_stream, machine->sample_rate);
603
//-------------------------------------------------
604
// mixer_update - mix all inputs to one output
605
//-------------------------------------------------
607
void speaker_device::mixer_update(stream_sample_t **inputs, stream_sample_t **outputs, int samples)
609
VPRINTF(("Mixer_update(%d)\n", samples));
612
for (int pos = 0; pos < samples; pos++)
614
INT32 sample = inputs[0][pos];
617
// add up all the inputs
618
for (inp = 1; inp < m_inputs; inp++)
619
sample += inputs[inp][pos];
620
outputs[0][pos] = sample;
625
//-------------------------------------------------
626
// mix - mix in samples from the speaker's stream
627
//-------------------------------------------------
629
void speaker_device::mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress)
632
if (m_mixer_stream == NULL)
635
// update the stream, getting the start/end pointers around the operation
637
const stream_sample_t *stream_buf = stream_get_output_since_last_update(m_mixer_stream, 0, &numsamples);
639
// set or assert that all streams have the same count
640
if (samples_this_update == 0)
642
samples_this_update = numsamples;
644
/* reset the mixing streams */
645
memset(leftmix, 0, samples_this_update * sizeof(*leftmix));
646
memset(rightmix, 0, samples_this_update * sizeof(*rightmix));
648
assert(samples_this_update == numsamples);
651
// debug version: keep track of the maximum sample
652
for (int sample = 0; sample < samples_this_update; sample++)
654
if (stream_buf[sample] > m_max_sample)
655
m_max_sample = stream_buf[sample];
656
else if (-stream_buf[sample] > m_max_sample)
657
m_max_sample = -stream_buf[sample];
658
if (stream_buf[sample] > 32767 || stream_buf[sample] < -32768)
664
// mix if sound is enabled
667
// if the speaker is centered, send to both left and right
668
if (m_config.m_x == 0)
669
for (int sample = 0; sample < samples_this_update; sample++)
671
leftmix[sample] += stream_buf[sample];
672
rightmix[sample] += stream_buf[sample];
675
// if the speaker is to the left, send only to the left
676
else if (m_config.m_x < 0)
677
for (int sample = 0; sample < samples_this_update; sample++)
678
leftmix[sample] += stream_buf[sample];
680
// if the speaker is to the right, send only to the right
682
for (int sample = 0; sample < samples_this_update; sample++)
683
rightmix[sample] += stream_buf[sample];
688
//-------------------------------------------------
689
// set_input_gain - set the gain on a given
691
//-------------------------------------------------
693
void speaker_device::set_input_gain(int inputnum, float gain)
695
m_input[inputnum].m_gain = gain;
696
stream_set_input_gain(m_mixer_stream, inputnum, gain);
701
/***************************************************************************
702
MISCELLANEOUS HELPERS
703
***************************************************************************/
705
/*-------------------------------------------------
706
sound_set_output_gain - set the gain of a
708
-------------------------------------------------*/
710
void sound_set_output_gain(device_t *device, int output, float gain)
712
sound_stream *stream;
715
if (stream_device_output_to_stream_output(device, output, &stream, &outputnum))
716
stream_set_output_gain(stream, outputnum, gain);
721
/***************************************************************************
723
***************************************************************************/
725
/*-------------------------------------------------
726
sound_get_user_gain_count - return the number
727
of user-controllable gain parameters
728
-------------------------------------------------*/
730
int sound_get_user_gain_count(running_machine *machine)
732
// count up the number of speaker inputs
734
for (speaker_device *speaker = speaker_first(*machine); speaker != NULL; speaker = speaker_next(speaker))
735
count += speaker->inputs();
741
/*-------------------------------------------------
742
sound_set_user_gain - set the nth user gain
744
-------------------------------------------------*/
746
void sound_set_user_gain(running_machine *machine, int index, float gain)
749
speaker_device *speaker = index_to_input(machine, index, inputnum);
752
speaker->set_input_gain(inputnum, gain);
756
/*-------------------------------------------------
757
sound_get_user_gain - get the nth user gain
759
-------------------------------------------------*/
761
float sound_get_user_gain(running_machine *machine, int index)
764
speaker_device *speaker = index_to_input(machine, index, inputnum);
765
return (speaker != NULL) ? speaker->input_gain(inputnum) : 0;
769
/*-------------------------------------------------
770
sound_get_default_gain - return the default
771
gain of the nth user value
772
-------------------------------------------------*/
774
float sound_get_default_gain(running_machine *machine, int index)
777
speaker_device *speaker = index_to_input(machine, index, inputnum);
778
return (speaker != NULL) ? speaker->input_default_gain(inputnum) : 0;
782
/*-------------------------------------------------
783
sound_get_user_gain_name - return the name
784
of the nth user value
785
-------------------------------------------------*/
787
const char *sound_get_user_gain_name(running_machine *machine, int index)
790
speaker_device *speaker = index_to_input(machine, index, inputnum);
791
return (speaker != NULL) ? speaker->input_name(inputnum) : 0;