~ubuntu-branches/debian/wheezy/mame/wheezy

« back to all changes in this revision

Viewing changes to src/emu/sound.c

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach, Emmanuel Kasper, Félix Arreola Rodríguez, Jordi Mallach
  • Date: 2011-05-11 21:06:50 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110511210650-jizvh8a6x117y9hr
Tags: 0.142-1
[ Emmanuel Kasper ]
* New upstream release
* Set NOWERROR=1 to allow compiling with gcc-4.6
* Remove fix_powerpc_build.patch, as upstream has taken it in this release
* Add gnome-video-arcade front end as a suggested package

[ Félix Arreola Rodríguez ]
* Add kfreebsd-build.patch to quilt series, to fix build on kfreebsd

[ Jordi Mallach ]
* Remove unneeded and bogus addition of --with-quilt to the dh invocation.
* Add Cesare Falco (long time Ubuntu maintainer) to Uploaders, and wrap
  them into multiple lines.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
    Core sound functions and definitions.
6
6
 
7
 
    Copyright Nicola Salmoria and the MAME Team.
8
 
    Visit http://mamedev.org for licensing and usage restrictions.
 
7
****************************************************************************
 
8
 
 
9
    Copyright Aaron Giles
 
10
    All rights reserved.
 
11
 
 
12
    Redistribution and use in source and binary forms, with or without
 
13
    modification, are permitted provided that the following conditions are
 
14
    met:
 
15
 
 
16
        * Redistributions of source code must retain the above copyright
 
17
          notice, this list of conditions and the following disclaimer.
 
18
        * Redistributions in binary form must reproduce the above copyright
 
19
          notice, this list of conditions and the following disclaimer in
 
20
          the documentation and/or other materials provided with the
 
21
          distribution.
 
22
        * Neither the name 'MAME' nor the names of its contributors may be
 
23
          used to endorse or promote products derived from this software
 
24
          without specific prior written permission.
 
25
 
 
26
    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
 
27
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
28
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
29
    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
 
30
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
31
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
32
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
33
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
34
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
35
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
36
    POSSIBILITY OF SUCH DAMAGE.
9
37
 
10
38
***************************************************************************/
11
39
 
12
40
#include "emu.h"
13
41
#include "emuopts.h"
14
42
#include "osdepend.h"
15
 
#include "streams.h"
16
43
#include "config.h"
17
44
#include "profiler.h"
18
45
#include "sound/wavwrite.h"
19
46
 
20
47
 
21
48
 
22
 
/***************************************************************************
23
 
    DEBUGGING
24
 
***************************************************************************/
 
49
//**************************************************************************
 
50
//  DEBUGGING
 
51
//**************************************************************************
25
52
 
26
53
#define VERBOSE                 (0)
27
54
 
29
56
 
30
57
 
31
58
 
32
 
/***************************************************************************
33
 
    CONSTANTS
34
 
***************************************************************************/
35
 
 
36
 
#define MAX_MIXER_CHANNELS              100
37
 
 
38
 
 
39
 
 
40
 
/***************************************************************************
41
 
    DEVICE DEFINITIONS
42
 
***************************************************************************/
43
 
 
44
 
const device_type SPEAKER = speaker_device_config::static_alloc_device_config;
45
 
 
46
 
 
47
 
 
48
 
/***************************************************************************
49
 
    TYPE DEFINITIONS
50
 
***************************************************************************/
51
 
 
52
 
struct _sound_private
53
 
{
54
 
        emu_timer *update_timer;
55
 
 
56
 
        int totalsnd;
57
 
 
58
 
        UINT32 finalmix_leftover;
59
 
        INT16 *finalmix;
60
 
        INT32 *leftmix;
61
 
        INT32 *rightmix;
62
 
 
63
 
        int muted;
64
 
        int attenuation;
65
 
        int enabled;
66
 
        int nosound_mode;
67
 
 
68
 
        wav_file *wavfile;
69
 
};
70
 
 
71
 
 
72
 
 
73
 
/***************************************************************************
74
 
    FUNCTION PROTOTYPES
75
 
***************************************************************************/
76
 
 
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 );
84
 
 
85
 
 
86
 
 
87
 
/***************************************************************************
88
 
    INLINE FUNCTIONS
89
 
***************************************************************************/
90
 
 
91
 
//-------------------------------------------------
92
 
//  index_to_input - map an absolute index to
93
 
//  a particular input
94
 
//-------------------------------------------------
95
 
 
96
 
INLINE speaker_device *index_to_input(running_machine *machine, int index, int &input)
 
59
//**************************************************************************
 
60
//  CONSTANTS
 
61
//**************************************************************************
 
62
 
 
63
 
 
64
 
 
65
//**************************************************************************
 
66
//  GLOBAL VARIABLES
 
67
//**************************************************************************
 
68
 
 
69
const attotime sound_manager::STREAMS_UPDATE_ATTOTIME = attotime::from_hz(STREAMS_UPDATE_FREQUENCY);
 
70
 
 
71
 
 
72
 
 
73
//**************************************************************************
 
74
//  INITIALIZATION
 
75
//**************************************************************************
 
76
 
 
77
//-------------------------------------------------
 
78
//  sound_stream - constructor
 
79
//-------------------------------------------------
 
80
 
 
81
sound_stream::sound_stream(device_t &device, int inputs, int outputs, int sample_rate, void *param, stream_update_func callback)
 
82
        : m_device(device),
 
83
          m_next(NULL),
 
84
          m_sample_rate(sample_rate),
 
85
          m_new_sample_rate(0),
 
86
          m_attoseconds_per_sample(0),
 
87
          m_max_samples_per_update(0),
 
88
          m_inputs(inputs),
 
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),
 
92
          m_outputs(outputs),
 
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)),
 
95
          m_output_bufalloc(0),
 
96
          m_output_sampindex(0),
 
97
          m_output_update_sampindex(0),
 
98
          m_output_base_sampindex(0),
 
99
          m_callback(callback),
 
100
          m_param(param)
 
101
{
 
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");
 
106
 
 
107
        // this is also the implicit parameter if we are using our internal stub
 
108
        if (m_callback == &sound_stream::device_stream_update_stub)
 
109
                m_param = sound;
 
110
 
 
111
        // create a unique tag for saving
 
112
        astring state_tag;
 
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);
 
116
 
 
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++)
 
121
        {
 
122
                m_output[outputnum].m_stream = this;
 
123
                m_device.machine().state().save_item("stream", state_tag, outputnum, NAME(m_output[outputnum].m_gain));
 
124
        }
 
125
 
 
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();
 
129
 
 
130
        // set up the initial output buffer positions now that we have data
 
131
        m_output_base_sampindex = -m_max_samples_per_update;
 
132
}
 
133
 
 
134
 
 
135
//-------------------------------------------------
 
136
//  sample_time - return the emulation time of the
 
137
//  next sample to be generated on the stream
 
138
//-------------------------------------------------
 
139
 
 
140
attotime sound_stream::sample_time() const
 
141
{
 
142
        return attotime(m_device.machine().sound().last_update().seconds, 0) + attotime(0, m_output_sampindex * m_attoseconds_per_sample);
 
143
}
 
144
 
 
145
 
 
146
//-------------------------------------------------
 
147
//  input_gain - return the input gain on a
 
148
//  given stream's input
 
149
//-------------------------------------------------
 
150
 
 
151
float sound_stream::input_gain(int inputnum) const
 
152
{
 
153
        assert(inputnum >= 0 && inputnum < m_inputs);
 
154
        return float(m_input[inputnum].m_gain) / 256.0f;
 
155
}
 
156
 
 
157
 
 
158
//-------------------------------------------------
 
159
//  initial_input_gain - return the original input
 
160
//  gain on a given stream's input
 
161
//-------------------------------------------------
 
162
 
 
163
float sound_stream::initial_input_gain(int inputnum) const
 
164
{
 
165
        assert(inputnum >= 0 && inputnum < m_inputs);
 
166
        return float(m_input[inputnum].m_initial_gain) / 256.0f;
 
167
}
 
168
 
 
169
 
 
170
//-------------------------------------------------
 
171
//  input_name - return the original input gain
 
172
//  on a given stream's input
 
173
//-------------------------------------------------
 
174
 
 
175
const char *sound_stream::input_name(int inputnum, astring &string) const
 
176
{
 
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());
 
180
 
 
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)
 
183
        {
 
184
                device_t &source = m_input[inputnum].m_source->m_stream->device();
 
185
                string.catprintf("%s '%s'", source.name(), source.tag());
 
186
 
 
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)
 
190
                {
 
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;
 
194
                        int streamoutputnum;
 
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])
 
197
                                {
 
198
                                        string.catprintf(" Ch.%d", outputnum);
 
199
                                        break;
 
200
                                }
 
201
                }
 
202
        }
 
203
        return string;
 
204
}
 
205
 
 
206
 
 
207
//-------------------------------------------------
 
208
//  output_gain - return the output gain on a
 
209
//  given stream's output
 
210
//-------------------------------------------------
 
211
 
 
212
float sound_stream::output_gain(int outputnum) const
 
213
{
 
214
        assert(outputnum >= 0 && outputnum < m_outputs);
 
215
        return float(m_output[outputnum].m_gain) / 256.0f;
 
216
}
 
217
 
 
218
 
 
219
//-------------------------------------------------
 
220
//  set_input - configure a stream's input
 
221
//-------------------------------------------------
 
222
 
 
223
void sound_stream::set_input(int index, sound_stream *input_stream, int output_index, float gain)
 
224
{
 
225
        VPRINTF(("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", this, m_device.tag(), index, input_stream, output_index, gain));
 
226
 
 
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);
 
230
 
 
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);
 
234
 
 
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--;
 
239
 
 
240
        // wire it up
 
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);
 
243
 
 
244
        // update the dependent info
 
245
        if (input.m_source != NULL)
 
246
                input.m_source->m_dependents++;
 
247
 
 
248
        // update sample rates now that we know the input
 
249
        recompute_sample_rate_data();
 
250
}
 
251
 
 
252
 
 
253
//-------------------------------------------------
 
254
//  update - force a stream to update to
 
255
//  the current emulated time
 
256
//-------------------------------------------------
 
257
 
 
258
void sound_stream::update()
 
259
{
 
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);
 
263
 
 
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)
 
267
        {
 
268
                assert(time.seconds == last_update.seconds + 1);
 
269
                update_sampindex += m_sample_rate;
 
270
        }
 
271
 
 
272
        // if we're behind the last update, then adjust downwards
 
273
        if (time.seconds < last_update.seconds)
 
274
        {
 
275
                assert(time.seconds == last_update.seconds - 1);
 
276
                update_sampindex -= m_sample_rate;
 
277
        }
 
278
 
 
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);
 
284
        g_profiler.stop();
 
285
 
 
286
        // remember this info for next time
 
287
        m_output_sampindex = update_sampindex;
 
288
}
 
289
 
 
290
 
 
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
//-------------------------------------------------
 
296
 
 
297
const stream_sample_t *sound_stream::output_since_last_update(int outputnum, int &numsamples)
 
298
{
 
299
        // force an update on the stream
 
300
        update();
 
301
 
 
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);
 
305
}
 
306
 
 
307
 
 
308
//-------------------------------------------------
 
309
//  set_sample_rate - set the sample rate on a
 
310
//  given stream
 
311
//-------------------------------------------------
 
312
 
 
313
void sound_stream::set_sample_rate(int new_rate)
 
314
{
 
315
        // we will update this on the next global update
 
316
        if (new_rate != sample_rate())
 
317
                m_new_sample_rate = new_rate;
 
318
}
 
319
 
 
320
 
 
321
//-------------------------------------------------
 
322
//  set_input_gain - set the input gain on a
 
323
//  given stream's input
 
324
//-------------------------------------------------
 
325
 
 
326
void sound_stream::set_input_gain(int inputnum, float gain)
 
327
{
 
328
        update();
 
329
        assert(inputnum >= 0 && inputnum < m_inputs);
 
330
        m_input[inputnum].m_gain = int(0x100 * gain);
 
331
}
 
332
 
 
333
 
 
334
//-------------------------------------------------
 
335
//  set_output_gain - set the output gain on a
 
336
//  given stream's output
 
337
//-------------------------------------------------
 
338
 
 
339
void sound_stream::set_output_gain(int outputnum, float gain)
 
340
{
 
341
        update();
 
342
        assert(outputnum >= 0 && outputnum < m_outputs);
 
343
        m_output[outputnum].m_gain = int(0x100 * gain);
 
344
}
 
345
 
 
346
 
 
347
//-------------------------------------------------
 
348
//  update_with_accounting - do a regular update,
 
349
//  but also do periodic accounting
 
350
//-------------------------------------------------
 
351
 
 
352
void sound_stream::update_with_accounting(bool second_tick)
 
353
{
 
354
        // do the normal update
 
355
        update();
 
356
 
 
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;
 
360
        if (second_tick)
 
361
        {
 
362
                m_output_sampindex -= m_sample_rate;
 
363
                m_output_base_sampindex -= m_sample_rate;
 
364
        }
 
365
 
 
366
        // note our current output sample
 
367
        m_output_update_sampindex = m_output_sampindex;
 
368
 
 
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)
 
372
        {
 
373
                INT32 samples_to_lose = output_bufindex - m_max_samples_per_update;
 
374
                if (samples_to_lose > 0)
 
375
                {
 
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++)
 
379
                                {
 
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));
 
382
                                }
 
383
 
 
384
                        // update the base position
 
385
                        m_output_base_sampindex += samples_to_lose;
 
386
                }
 
387
        }
 
388
}
 
389
 
 
390
 
 
391
//-------------------------------------------------
 
392
//  apply_sample_rate_changes - if there is a
 
393
//  pending sample rate change, apply it now
 
394
//-------------------------------------------------
 
395
 
 
396
void sound_stream::apply_sample_rate_changes()
 
397
{
 
398
        // skip if nothing to do
 
399
        if (m_new_sample_rate == 0)
 
400
                return;
 
401
 
 
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;
 
406
 
 
407
        // recompute all the data
 
408
        recompute_sample_rate_data();
 
409
 
 
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;
 
414
 
 
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]));
 
418
}
 
419
 
 
420
 
 
421
//-------------------------------------------------
 
422
//  device_stream_update_stub - stub callback for
 
423
//  passing through to modern devices
 
424
//-------------------------------------------------
 
425
 
 
426
STREAM_UPDATE( sound_stream::device_stream_update_stub )
 
427
{
 
428
        device_sound_interface *sound = reinterpret_cast<device_sound_interface *>(param);
 
429
        sound->sound_stream_update(*stream, inputs, outputs, samples);
 
430
}
 
431
 
 
432
 
 
433
//-------------------------------------------------
 
434
//  recompute_sample_rate_data - recompute sample
 
435
//  rate data, and all streams that are affected
 
436
//  by this stream
 
437
//-------------------------------------------------
 
438
 
 
439
void sound_stream::recompute_sample_rate_data()
 
440
{
 
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;
 
445
 
 
446
        // update resample and output buffer sizes
 
447
        allocate_resample_buffers();
 
448
        allocate_output_buffers();
 
449
 
 
450
        // iterate over each input
 
451
        for (int inputnum = 0; inputnum < m_inputs; inputnum++)
 
452
        {
 
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)
 
456
                {
 
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);
 
461
 
 
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;
 
466
 
 
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)
 
469
                                latency = 0;
 
470
 
 
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);
 
475
                }
 
476
        }
 
477
}
 
478
 
 
479
 
 
480
//-------------------------------------------------
 
481
//  allocate_resample_buffers - recompute the
 
482
//  resample buffer sizes and expand if necessary
 
483
//-------------------------------------------------
 
484
 
 
485
void sound_stream::allocate_resample_buffers()
 
486
{
 
487
        // compute the target number of samples
 
488
        INT32 bufsize = 2 * m_max_samples_per_update;
 
489
 
 
490
        // if we don't have enough room, allocate more
 
491
        if (m_resample_bufalloc < bufsize)
 
492
        {
 
493
                // this becomes the new allocation size
 
494
                int oldsize = m_resample_bufalloc;
 
495
                m_resample_bufalloc = bufsize;
 
496
 
 
497
                // iterate over outputs and realloc their buffers
 
498
                for (int inputnum = 0; inputnum < m_inputs; inputnum++)
 
499
                {
 
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;
 
505
                }
 
506
        }
 
507
}
 
508
 
 
509
 
 
510
//-------------------------------------------------
 
511
//  allocate_output_buffers - recompute the
 
512
//  output buffer sizes and expand if necessary
 
513
//-------------------------------------------------
 
514
 
 
515
void sound_stream::allocate_output_buffers()
 
516
{
 
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)
 
520
        {
 
521
                // this becomes the new allocation size
 
522
                int oldsize = m_output_bufalloc;
 
523
                m_output_bufalloc = bufsize;
 
524
 
 
525
                // iterate over outputs and realloc their buffers
 
526
                for (int outputnum = 0; outputnum < m_outputs; outputnum++)
 
527
                {
 
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;
 
534
                }
 
535
        }
 
536
}
 
537
 
 
538
 
 
539
//-------------------------------------------------
 
540
//  postload - save/restore callback
 
541
//-------------------------------------------------
 
542
 
 
543
void sound_stream::postload()
 
544
{
 
545
        // recompute the same rate information
 
546
        recompute_sample_rate_data();
 
547
 
 
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]));
 
551
 
 
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;
 
556
}
 
557
 
 
558
 
 
559
//-------------------------------------------------
 
560
//  generate_samples - generate the requested
 
561
//  number of samples for a stream, making sure
 
562
//  all inputs have the appropriate number of
 
563
//  samples generated
 
564
//-------------------------------------------------
 
565
 
 
566
void sound_stream::generate_samples(int samples)
 
567
{
 
568
        // if we're already there, skip it
 
569
        if (samples <= 0)
 
570
                return;
 
571
 
 
572
        VPRINTF(("generate_samples(%p, %d)\n", this, samples));
 
573
 
 
574
        // ensure all inputs are up to date and generate resampled data
 
575
        for (int inputnum = 0; inputnum < m_inputs; inputnum++)
 
576
        {
 
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();
 
581
 
 
582
                // generate the resampled data
 
583
                m_input_array[inputnum] = generate_resampled_data(input, samples);
 
584
        }
 
585
 
 
586
        // loop over all outputs and compute the output pointer
 
587
        for (int outputnum = 0; outputnum < m_outputs; outputnum++)
 
588
        {
 
589
                stream_output &output = m_output[outputnum];
 
590
                m_output_array[outputnum] = output.m_buffer + (m_output_sampindex - m_output_base_sampindex);
 
591
        }
 
592
 
 
593
        // run the callback
 
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"));
 
597
}
 
598
 
 
599
 
 
600
//-------------------------------------------------
 
601
//  generate_resampled_data - generate the
 
602
//  resample buffer for a given input
 
603
//-------------------------------------------------
 
604
 
 
605
stream_sample_t *sound_stream::generate_resampled_data(stream_input &input, UINT32 numsamples)
 
606
{
 
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)
 
610
        {
 
611
                memset(dest, 0, numsamples * sizeof(*dest));
 
612
                return input.m_resample;
 
613
        }
 
614
 
 
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;
 
619
 
 
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;
 
623
 
 
624
        // now convert that time into a sample in the input stream
 
625
        INT32 basesample;
 
626
        if (basetime >= 0)
 
627
                basesample = basetime / input_stream.m_attoseconds_per_sample;
 
628
        else
 
629
                basesample = -(-basetime / input_stream.m_attoseconds_per_sample) - 1;
 
630
 
 
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);
 
634
 
 
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);
 
639
 
 
640
        // compute the stepping fraction
 
641
        UINT32 step = ((UINT64)input_stream.m_sample_rate << FRAC_BITS) / m_sample_rate;
 
642
 
 
643
        // if we have equal sample rates, we just need to copy
 
644
        if (step == FRAC_ONE)
 
645
        {
 
646
                while (numsamples--)
 
647
                {
 
648
                        // compute the sample
 
649
                        stream_sample_t sample = *source++;
 
650
                        *dest++ = (sample * gain) >> 8;
 
651
                }
 
652
        }
 
653
 
 
654
        // input is undersampled: point sample except where our sample period covers a boundary
 
655
        else if (step < FRAC_ONE)
 
656
        {
 
657
                while (numsamples != 0)
 
658
                {
 
659
                        // fill in with point samples until we hit a boundary
 
660
                        int nextfrac;
 
661
                        while ((nextfrac = basefrac + step) < FRAC_ONE && numsamples--)
 
662
                        {
 
663
                                *dest++ = (source[0] * gain) >> 8;
 
664
                                basefrac = nextfrac;
 
665
                        }
 
666
 
 
667
                        // if we're done, we're done
 
668
                        if ((INT32)numsamples-- < 0)
 
669
                                break;
 
670
 
 
671
                        // compute starting and ending fractional positions
 
672
                        int startfrac = basefrac >> (FRAC_BITS - 12);
 
673
                        int endfrac = nextfrac >> (FRAC_BITS - 12);
 
674
 
 
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;
 
678
 
 
679
                        // advance
 
680
                        basefrac = nextfrac & FRAC_MASK;
 
681
                        source++;
 
682
                }
 
683
        }
 
684
 
 
685
        // input is oversampled: sum the energy
 
686
        else
 
687
        {
 
688
                // use 8 bits to allow some extra headroom
 
689
                int smallstep = step >> (FRAC_BITS - 8);
 
690
                while (numsamples--)
 
691
                {
 
692
                        int remainder = smallstep;
 
693
                        int tpos = 0;
 
694
 
 
695
                        // compute the sample
 
696
                        int scale = (FRAC_ONE - basefrac) >> (FRAC_BITS - 8);
 
697
                        stream_sample_t sample = source[tpos++] * scale;
 
698
                        remainder -= scale;
 
699
                        while (remainder > 0x100)
 
700
                        {
 
701
                                sample += source[tpos++] * 0x100;
 
702
                                remainder -= 0x100;
 
703
                        }
 
704
                        sample += source[tpos] * remainder;
 
705
                        sample /= smallstep;
 
706
 
 
707
                        *dest++ = (sample * gain) >> 8;
 
708
 
 
709
                        // advance
 
710
                        basefrac += step;
 
711
                        source += basefrac >> FRAC_BITS;
 
712
                        basefrac &= FRAC_MASK;
 
713
                }
 
714
        }
 
715
 
 
716
        return input.m_resample;
 
717
}
 
718
 
 
719
 
 
720
 
 
721
//**************************************************************************
 
722
//  STREAM INPUT
 
723
//**************************************************************************
 
724
 
 
725
//-------------------------------------------------
 
726
//  stream_input - constructor
 
727
//-------------------------------------------------
 
728
 
 
729
sound_stream::stream_input::stream_input()
 
730
        : m_source(NULL),
 
731
          m_resample(NULL),
 
732
          m_bufsize(0),
 
733
          m_bufalloc(0),
 
734
          m_latency_attoseconds(0),
 
735
          m_gain(0x100),
 
736
          m_initial_gain(0x100)
 
737
{
 
738
}
 
739
 
 
740
 
 
741
 
 
742
//**************************************************************************
 
743
//  STREAM OUTPUT
 
744
//**************************************************************************
 
745
 
 
746
//-------------------------------------------------
 
747
//  stream_output - constructor
 
748
//-------------------------------------------------
 
749
 
 
750
sound_stream::stream_output::stream_output()
 
751
        : m_buffer(NULL),
 
752
          m_dependents(0),
 
753
          m_gain(0x100)
 
754
{
 
755
}
 
756
 
 
757
 
 
758
 
 
759
//**************************************************************************
 
760
//  SOUND MANAGER
 
761
//**************************************************************************
 
762
 
 
763
//-------------------------------------------------
 
764
//  sound_manager - constructor
 
765
//-------------------------------------------------
 
766
 
 
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),
 
771
          m_finalmix(NULL),
 
772
          m_leftmix(NULL),
 
773
          m_rightmix(NULL),
 
774
          m_muted(0),
 
775
          m_attenuation(0),
 
776
          m_nosound_mode(!machine.options().sound()),
 
777
          m_wavfile(NULL),
 
778
          m_stream_list(machine.respool()),
 
779
          m_update_attoseconds(STREAMS_UPDATE_ATTOTIME.attoseconds),
 
780
          m_last_update(attotime::zero)
 
781
{
 
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();
 
785
 
 
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;
 
789
 
 
790
        // count the speakers
 
791
        VPRINTF(("total speakers = %d\n", machine.m_devicelist.count(SPEAKER)));
 
792
 
 
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());
 
797
 
 
798
        // open the output WAV file if specified
 
799
        if (wavfile[0] != 0)
 
800
                m_wavfile = wav_open(wavfile, machine.sample_rate(), 2);
 
801
 
 
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);
 
807
 
 
808
        // register global states
 
809
        state_save_register_global(machine, m_last_update);
 
810
 
 
811
        // set the starting attenuation
 
812
        set_attenuation(machine.options().volume());
 
813
 
 
814
        // start the periodic update flushing timer
 
815
        m_update_timer->adjust(STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME);
 
816
}
 
817
 
 
818
 
 
819
//-------------------------------------------------
 
820
//  sound_manager - destructor
 
821
//-------------------------------------------------
 
822
 
 
823
sound_manager::~sound_manager()
 
824
{
 
825
        // close any open WAV file
 
826
        if (m_wavfile != NULL)
 
827
                wav_close(m_wavfile);
 
828
        m_wavfile = NULL;
 
829
}
 
830
 
 
831
 
 
832
//-------------------------------------------------
 
833
//  stream_alloc - allocate a new stream
 
834
//-------------------------------------------------
 
835
 
 
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)
 
837
{
 
838
        if (callback != NULL)
 
839
                return &m_stream_list.append(*auto_alloc(device.machine(), sound_stream(device, inputs, outputs, sample_rate, param, callback)));
 
840
        else
 
841
                return &m_stream_list.append(*auto_alloc(device.machine(), sound_stream(device, inputs, outputs, sample_rate)));
 
842
}
 
843
 
 
844
 
 
845
//-------------------------------------------------
 
846
//  set_attenuation - set the global volume
 
847
//-------------------------------------------------
 
848
 
 
849
void sound_manager::set_attenuation(int attenuation)
 
850
{
 
851
        m_attenuation = attenuation;
 
852
        m_machine.osd().set_mastervolume(m_muted ? -32 : m_attenuation);
 
853
}
 
854
 
 
855
 
 
856
//-------------------------------------------------
 
857
//  indexed_speaker_input - return the speaker
 
858
//  device and input index of the global speaker
 
859
//  input
 
860
//-------------------------------------------------
 
861
 
 
862
bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const
97
863
{
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())
100
866
        {
101
 
                if (index < speaker->inputs())
 
867
                if (index < info.speaker->inputs())
102
868
                {
103
 
                        input = index;
104
 
                        return speaker;
 
869
                        info.stream = info.speaker->input_to_stream_input(index, info.inputnum);
 
870
                        assert(info.stream != NULL);
 
871
                        return true;
105
872
                }
106
 
                index -= speaker->inputs();
 
873
                index -= info.speaker->inputs();
107
874
        }
108
875
 
109
 
        // index out of range
110
 
        return NULL;
111
 
}
112
 
 
113
 
 
114
 
 
115
 
/***************************************************************************
116
 
    INITIALIZATION
117
 
***************************************************************************/
118
 
 
119
 
/*-------------------------------------------------
120
 
    sound_init - start up the sound system
121
 
-------------------------------------------------*/
122
 
 
123
 
void sound_init(running_machine *machine)
124
 
{
125
 
        sound_private *global;
126
 
        const char *filename;
127
 
        const char *filenameavi;
128
 
 
129
 
        machine->sound_data = global = auto_alloc_clear(machine, sound_private);
130
 
 
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);
134
 
 
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;
139
 
 
140
 
        /* count the speakers */
141
 
        VPRINTF(("total speakers = %d\n", speaker_output_count(machine->config)));
142
 
 
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);
147
 
 
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);
151
 
 
152
 
        /* open the output WAV file if specified */
153
 
        if (filename[0] != 0)
154
 
                global->wavfile = wav_open(filename, machine->sample_rate, 2);
155
 
 
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));
160
 
 
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);
167
 
}
168
 
 
169
 
 
170
 
/*-------------------------------------------------
171
 
    sound_exit - clean up after ourselves
172
 
-------------------------------------------------*/
173
 
 
174
 
static void sound_exit(running_machine &machine)
175
 
{
176
 
        sound_private *global = machine.sound_data;
177
 
 
178
 
        /* close any open WAV file */
179
 
        if (global->wavfile != NULL)
180
 
                wav_close(global->wavfile);
181
 
        global->wavfile = NULL;
182
 
 
183
 
        /* reset variables */
184
 
        global->totalsnd = 0;
185
 
}
186
 
 
187
 
 
188
 
 
189
 
/***************************************************************************
190
 
    GLOBAL STATE MANAGEMENT
191
 
***************************************************************************/
192
 
 
193
 
/*-------------------------------------------------
194
 
    sound_reset - reset all sound chips
195
 
-------------------------------------------------*/
196
 
 
197
 
static void sound_reset(running_machine &machine)
198
 
{
 
876
        // didn't locate
 
877
        return false;
 
878
}
 
879
 
 
880
 
 
881
//-------------------------------------------------
 
882
//  mute - mute sound output
 
883
//-------------------------------------------------
 
884
 
 
885
void sound_manager::mute(bool mute, UINT8 reason)
 
886
{
 
887
        if (mute)
 
888
                m_muted |= reason;
 
889
        else
 
890
                m_muted &= ~reason;
 
891
        set_attenuation(m_attenuation);
 
892
}
 
893
 
 
894
 
 
895
//-------------------------------------------------
 
896
//  reset - reset all sound chips
 
897
//-------------------------------------------------
 
898
 
 
899
void sound_manager::reset(running_machine &machine)
 
900
{
 
901
        // reset all the sound chips
199
902
        device_sound_interface *sound = NULL;
200
 
 
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();
204
905
}
205
906
 
206
907
 
207
 
/*-------------------------------------------------
208
 
    sound_pause - pause sound output
209
 
-------------------------------------------------*/
210
 
 
211
 
static void sound_pause(running_machine &machine)
212
 
{
213
 
        sound_private *global = machine.sound_data;
214
 
        global->muted |= 0x02;
215
 
        machine.osd().set_mastervolume(global->muted ? -32 : global->attenuation);
216
 
}
217
 
 
218
 
static void sound_resume(running_machine &machine)
219
 
{
220
 
        sound_private *global = machine.sound_data;
221
 
        global->muted &= ~0x02;
222
 
        machine.osd().set_mastervolume(global->muted ? -32 : global->attenuation);
223
 
}
224
 
 
225
 
 
226
 
/*-------------------------------------------------
227
 
    sound_mute - mute sound output
228
 
-------------------------------------------------*/
229
 
 
230
 
void sound_mute(running_machine *machine, int mute)
231
 
{
232
 
        sound_private *global = machine->sound_data;
233
 
 
234
 
        if (mute)
235
 
                global->muted |= 0x01;
236
 
        else
237
 
                global->muted &= ~0x01;
238
 
        machine->osd().set_mastervolume(global->muted ? -32 : global->attenuation);
239
 
}
240
 
 
241
 
 
242
 
/*-------------------------------------------------
243
 
    sound_set_attenuation - set the global volume
244
 
-------------------------------------------------*/
245
 
 
246
 
void sound_set_attenuation(running_machine *machine, int attenuation)
247
 
{
248
 
        sound_private *global = machine->sound_data;
249
 
        global->attenuation = attenuation;
250
 
        machine->osd().set_mastervolume(global->muted ? -32 : global->attenuation);
251
 
}
252
 
 
253
 
 
254
 
/*-------------------------------------------------
255
 
    sound_get_attenuation - return the global
256
 
    volume
257
 
-------------------------------------------------*/
258
 
 
259
 
int sound_get_attenuation(running_machine *machine)
260
 
{
261
 
        sound_private *global = machine->sound_data;
262
 
        return global->attenuation;
263
 
}
264
 
 
265
 
 
266
 
/*-------------------------------------------------
267
 
    sound_global_enable - enable/disable sound
268
 
    globally
269
 
-------------------------------------------------*/
270
 
 
271
 
void sound_global_enable(running_machine *machine, int enable)
272
 
{
273
 
        sound_private *global = machine->sound_data;
274
 
        global->enabled = enable;
275
 
}
276
 
 
277
 
 
278
 
 
279
 
/***************************************************************************
280
 
    SOUND SAVE/LOAD
281
 
***************************************************************************/
282
 
 
283
 
/*-------------------------------------------------
284
 
    sound_load - read and apply data from the
285
 
    configuration file
286
 
-------------------------------------------------*/
287
 
 
288
 
static void sound_load(running_machine *machine, int config_type, xml_data_node *parentnode)
289
 
{
290
 
        xml_data_node *channelnode;
291
 
        int mixernum;
292
 
 
293
 
        /* we only care about game files */
 
908
//-------------------------------------------------
 
909
//  pause - pause sound output
 
910
//-------------------------------------------------
 
911
 
 
912
void sound_manager::pause(running_machine &machine)
 
913
{
 
914
        machine.sound().mute(true, MUTE_REASON_PAUSE);
 
915
}
 
916
 
 
917
 
 
918
//-------------------------------------------------
 
919
//  resume - resume sound output
 
920
//-------------------------------------------------
 
921
 
 
922
void sound_manager::resume(running_machine &machine)
 
923
{
 
924
        machine.sound().mute(false, MUTE_REASON_PAUSE);
 
925
}
 
926
 
 
927
 
 
928
//-------------------------------------------------
 
929
//  config_load - read and apply data from the
 
930
//  configuration file
 
931
//-------------------------------------------------
 
932
 
 
933
void sound_manager::config_load(running_machine &machine, int config_type, xml_data_node *parentnode)
 
934
{
 
935
        // we only care about game files
294
936
        if (config_type != CONFIG_TYPE_GAME)
295
937
                return;
296
938
 
297
 
        /* might not have any data */
 
939
        // might not have any data
298
940
        if (parentnode == NULL)
299
941
                return;
300
942
 
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"))
303
945
        {
304
 
                mixernum = xml_get_attribute_int(channelnode, "index", -1);
305
 
                if (mixernum >= 0 && mixernum < MAX_MIXER_CHANNELS)
 
946
                speaker_input info;
 
947
                if (machine.sound().indexed_speaker_input(xml_get_attribute_int(channelnode, "index", -1), info))
306
948
                {
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);
311
953
                }
312
954
        }
313
955
}
314
956
 
315
957
 
316
 
/*-------------------------------------------------
317
 
    sound_save - save data to the configuration
318
 
    file
319
 
-------------------------------------------------*/
 
958
//-------------------------------------------------
 
959
//  config_save - save data to the configuration
 
960
//  file
 
961
//-------------------------------------------------
320
962
 
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)
322
964
{
323
 
        int mixernum;
324
 
 
325
 
        /* we only care about game files */
 
965
        // we only care about game files
326
966
        if (config_type != CONFIG_TYPE_GAME)
327
967
                return;
328
968
 
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++)
332
972
                {
333
 
                        float defvol = sound_get_default_gain(machine, mixernum);
334
 
                        float newvol = sound_get_user_gain(machine, mixernum);
 
973
                        speaker_input info;
 
974
                        if (!machine.sound().indexed_speaker_input(mixernum, info))
 
975
                                break;
 
976
                        float defvol = info.stream->initial_input_gain(info.inputnum);
 
977
                        float newvol = info.stream->input_gain(info.inputnum);
335
978
 
336
979
                        if (defvol != newvol)
337
980
                        {
347
990
}
348
991
 
349
992
 
350
 
 
351
 
/***************************************************************************
352
 
    MIXING STAGE
353
 
***************************************************************************/
354
 
 
355
 
/*-------------------------------------------------
356
 
    sound_update - mix everything down to
357
 
    its final form and send it to the OSD layer
358
 
-------------------------------------------------*/
359
 
 
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
//-------------------------------------------------
 
997
 
 
998
void sound_manager::update()
361
999
{
362
 
        UINT32 finalmix_step, finalmix_offset;
 
1000
        VPRINTF(("sound_update\n"));
 
1001
 
 
1002
        g_profiler.start(PROFILER_SOUND);
 
1003
 
 
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));
 
1008
 
 
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;
364
1013
        int sample;
365
 
        sound_private *global = machine->sound_data;
366
 
        INT16 *finalmix;
367
 
        INT32 *leftmix, *rightmix;
368
 
 
369
 
        VPRINTF(("sound_update\n"));
370
 
 
371
 
        g_profiler.start(PROFILER_SOUND);
372
 
 
373
 
        leftmix = global->leftmix;
374
 
        rightmix = global->rightmix;
375
 
        finalmix = global->finalmix;
376
 
 
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);
380
 
 
381
 
        /* now downmix the final result */
382
 
        finalmix_step = machine->video().speed_factor();
383
 
        finalmix_offset = 0;
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)
385
1015
        {
386
1016
                int sampindex = sample / 100;
387
 
                INT32 samp;
388
1017
 
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)
392
1021
                        samp = -32768;
393
1022
                else if (samp > 32767)
394
1023
                        samp = 32767;
395
1024
                finalmix[finalmix_offset++] = samp;
396
1025
 
397
 
                /* clamp the right side */
398
 
                samp = rightmix[sampindex];
 
1026
                // clamp the right side
 
1027
                samp = m_rightmix[sampindex];
399
1028
                if (samp < -32768)
400
1029
                        samp = -32768;
401
1030
                else if (samp > 32767)
402
1031
                        samp = 32767;
403
1032
                finalmix[finalmix_offset++] = samp;
404
1033
        }
405
 
        global->finalmix_leftover = sample - samples_this_update * 100;
 
1034
        m_finalmix_leftover = sample - samples_this_update * 100;
406
1035
 
407
 
        /* play the result */
 
1036
        // play the result
408
1037
        if (finalmix_offset > 0)
409
1038
        {
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);
415
 
        }
416
 
 
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);
 
1044
        }
 
1045
 
 
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)
 
1050
        {
 
1051
                assert(curtime.seconds == m_last_update.seconds + 1);
 
1052
                second_tick = true;
 
1053
        }
 
1054
 
 
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);
 
1058
 
 
1059
        // remember the update time
 
1060
        m_last_update = curtime;
 
1061
 
 
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();
419
1065
 
420
1066
        g_profiler.stop();
421
1067
}
422
 
 
423
 
 
424
 
 
425
 
//**************************************************************************
426
 
//  SPEAKER DEVICE CONFIGURATION
427
 
//**************************************************************************
428
 
 
429
 
//-------------------------------------------------
430
 
//  speaker_device_config - constructor
431
 
//-------------------------------------------------
432
 
 
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),
435
 
          m_x(0.0),
436
 
          m_y(0.0),
437
 
          m_z(0.0)
438
 
{
439
 
}
440
 
 
441
 
 
442
 
//-------------------------------------------------
443
 
//  static_alloc_device_config - allocate a new
444
 
//  configuration object
445
 
//-------------------------------------------------
446
 
 
447
 
device_config *speaker_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
448
 
{
449
 
        return global_alloc(speaker_device_config(mconfig, tag, owner, clock));
450
 
}
451
 
 
452
 
 
453
 
//-------------------------------------------------
454
 
//  alloc_device - allocate a new device object
455
 
//-------------------------------------------------
456
 
 
457
 
device_t *speaker_device_config::alloc_device(running_machine &machine) const
458
 
{
459
 
        return auto_alloc(&machine, speaker_device(machine, *this));
460
 
}
461
 
 
462
 
 
463
 
//-------------------------------------------------
464
 
//  static_set_position - configuration helper to
465
 
//  set the speaker position
466
 
//-------------------------------------------------
467
 
 
468
 
void speaker_device_config::static_set_position(device_config *device, double x, double y, double z)
469
 
{
470
 
        speaker_device_config *speaker = downcast<speaker_device_config *>(device);
471
 
        speaker->m_x = x;
472
 
        speaker->m_y = y;
473
 
        speaker->m_z = z;
474
 
}
475
 
 
476
 
 
477
 
 
478
 
//**************************************************************************
479
 
//  LIVE SPEAKER DEVICE
480
 
//**************************************************************************
481
 
 
482
 
//-------------------------------------------------
483
 
//  speaker_device - constructor
484
 
//-------------------------------------------------
485
 
 
486
 
speaker_device::speaker_device(running_machine &_machine, const speaker_device_config &config)
487
 
        : device_t(_machine, config),
488
 
          m_config(config),
489
 
          m_mixer_stream(NULL),
490
 
          m_inputs(0),
491
 
          m_input(NULL)
492
 
#ifdef MAME_DEBUG
493
 
        ,
494
 
          m_max_sample(0),
495
 
          m_clipped_samples(0),
496
 
          m_total_samples(0)
497
 
#endif
498
 
{
499
 
}
500
 
 
501
 
 
502
 
//-------------------------------------------------
503
 
//  ~speaker_device - destructor
504
 
//-------------------------------------------------
505
 
 
506
 
speaker_device::~speaker_device()
507
 
{
508
 
#ifdef MAME_DEBUG
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 */
513
 
}
514
 
 
515
 
 
516
 
//-------------------------------------------------
517
 
//  device_start - perform device-specific
518
 
//  startup
519
 
//-------------------------------------------------
520
 
 
521
 
void speaker_device::device_start()
522
 
{
523
 
        // scan all the sound devices and count our inputs
524
 
        int inputs = 0;
525
 
        device_sound_interface *sound = NULL;
526
 
        for (bool gotone = machine->m_devicelist.first(sound); gotone; gotone = sound->next(sound))
527
 
        {
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)
530
 
                {
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)
534
 
                        {
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();
538
 
 
539
 
                                // accumulate inputs
540
 
                                inputs += (route->m_output == ALL_OUTPUTS) ? stream_get_device_outputs(*sound) : 1;
541
 
                        }
542
 
                }
543
 
        }
544
 
 
545
 
        // no inputs? that's weird
546
 
        if (inputs == 0)
547
 
        {
548
 
                logerror("Warning: speaker \"%s\" has no inputs\n", tag());
549
 
                return;
550
 
        }
551
 
 
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);
555
 
        m_inputs = 0;
556
 
 
557
 
        // iterate again over all the sound devices
558
 
        for (bool gotone = machine->m_devicelist.first(sound); gotone; gotone = sound->next(sound))
559
 
        {
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)
562
 
                {
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)
566
 
                        {
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)
571
 
                                        {
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());
576
 
                                                if (numoutputs > 1)
577
 
                                                        m_input[m_inputs].m_name.catprintf(" Ch.%d", outputnum);
578
 
 
579
 
                                                // connect the output to the input
580
 
                                                sound_stream *stream;
581
 
                                                int streamoutput;
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);
584
 
                                        }
585
 
                        }
586
 
                }
587
 
        }
588
 
}
589
 
 
590
 
 
591
 
//-------------------------------------------------
592
 
//  device_post_load - after we load a save state
593
 
//  be sure to update the mixer stream's output
594
 
//  sample rate
595
 
//-------------------------------------------------
596
 
 
597
 
void speaker_device::device_post_load()
598
 
{
599
 
        stream_set_sample_rate(m_mixer_stream, machine->sample_rate);
600
 
}
601
 
 
602
 
 
603
 
//-------------------------------------------------
604
 
//  mixer_update - mix all inputs to one output
605
 
//-------------------------------------------------
606
 
 
607
 
void speaker_device::mixer_update(stream_sample_t **inputs, stream_sample_t **outputs, int samples)
608
 
{
609
 
        VPRINTF(("Mixer_update(%d)\n", samples));
610
 
 
611
 
        // loop over samples
612
 
        for (int pos = 0; pos < samples; pos++)
613
 
        {
614
 
                INT32 sample = inputs[0][pos];
615
 
                int inp;
616
 
 
617
 
                // add up all the inputs
618
 
                for (inp = 1; inp < m_inputs; inp++)
619
 
                        sample += inputs[inp][pos];
620
 
                outputs[0][pos] = sample;
621
 
        }
622
 
}
623
 
 
624
 
 
625
 
//-------------------------------------------------
626
 
//  mix - mix in samples from the speaker's stream
627
 
//-------------------------------------------------
628
 
 
629
 
void speaker_device::mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress)
630
 
{
631
 
        // skip if no stream
632
 
        if (m_mixer_stream == NULL)
633
 
                return;
634
 
 
635
 
        // update the stream, getting the start/end pointers around the operation
636
 
        int numsamples;
637
 
        const stream_sample_t *stream_buf = stream_get_output_since_last_update(m_mixer_stream, 0, &numsamples);
638
 
 
639
 
        // set or assert that all streams have the same count
640
 
        if (samples_this_update == 0)
641
 
        {
642
 
                samples_this_update = numsamples;
643
 
 
644
 
                /* reset the mixing streams */
645
 
                memset(leftmix, 0, samples_this_update * sizeof(*leftmix));
646
 
                memset(rightmix, 0, samples_this_update * sizeof(*rightmix));
647
 
        }
648
 
        assert(samples_this_update == numsamples);
649
 
 
650
 
#ifdef MAME_DEBUG
651
 
        // debug version: keep track of the maximum sample
652
 
        for (int sample = 0; sample < samples_this_update; sample++)
653
 
        {
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)
659
 
                        m_clipped_samples++;
660
 
                m_total_samples++;
661
 
        }
662
 
#endif
663
 
 
664
 
        // mix if sound is enabled
665
 
        if (!suppress)
666
 
        {
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++)
670
 
                        {
671
 
                                leftmix[sample] += stream_buf[sample];
672
 
                                rightmix[sample] += stream_buf[sample];
673
 
                        }
674
 
 
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];
679
 
 
680
 
                // if the speaker is to the right, send only to the right
681
 
                else
682
 
                        for (int sample = 0; sample < samples_this_update; sample++)
683
 
                                rightmix[sample] += stream_buf[sample];
684
 
        }
685
 
}
686
 
 
687
 
 
688
 
//-------------------------------------------------
689
 
//  set_input_gain - set the gain on a given
690
 
//  input
691
 
//-------------------------------------------------
692
 
 
693
 
void speaker_device::set_input_gain(int inputnum, float gain)
694
 
{
695
 
        m_input[inputnum].m_gain = gain;
696
 
        stream_set_input_gain(m_mixer_stream, inputnum, gain);
697
 
}
698
 
 
699
 
 
700
 
 
701
 
/***************************************************************************
702
 
    MISCELLANEOUS HELPERS
703
 
***************************************************************************/
704
 
 
705
 
/*-------------------------------------------------
706
 
    sound_set_output_gain - set the gain of a
707
 
    particular output
708
 
-------------------------------------------------*/
709
 
 
710
 
void sound_set_output_gain(device_t *device, int output, float gain)
711
 
{
712
 
        sound_stream *stream;
713
 
        int outputnum;
714
 
 
715
 
        if (stream_device_output_to_stream_output(device, output, &stream, &outputnum))
716
 
                stream_set_output_gain(stream, outputnum, gain);
717
 
}
718
 
 
719
 
 
720
 
 
721
 
/***************************************************************************
722
 
    USER GAIN CONTROLS
723
 
***************************************************************************/
724
 
 
725
 
/*-------------------------------------------------
726
 
    sound_get_user_gain_count - return the number
727
 
    of user-controllable gain parameters
728
 
-------------------------------------------------*/
729
 
 
730
 
int sound_get_user_gain_count(running_machine *machine)
731
 
{
732
 
        // count up the number of speaker inputs
733
 
        int count = 0;
734
 
        for (speaker_device *speaker = speaker_first(*machine); speaker != NULL; speaker = speaker_next(speaker))
735
 
                count += speaker->inputs();
736
 
 
737
 
        return count;
738
 
}
739
 
 
740
 
 
741
 
/*-------------------------------------------------
742
 
    sound_set_user_gain - set the nth user gain
743
 
    value
744
 
-------------------------------------------------*/
745
 
 
746
 
void sound_set_user_gain(running_machine *machine, int index, float gain)
747
 
{
748
 
        int inputnum;
749
 
        speaker_device *speaker = index_to_input(machine, index, inputnum);
750
 
 
751
 
        if (speaker != NULL)
752
 
                speaker->set_input_gain(inputnum, gain);
753
 
}
754
 
 
755
 
 
756
 
/*-------------------------------------------------
757
 
    sound_get_user_gain - get the nth user gain
758
 
    value
759
 
-------------------------------------------------*/
760
 
 
761
 
float sound_get_user_gain(running_machine *machine, int index)
762
 
{
763
 
        int inputnum;
764
 
        speaker_device *speaker = index_to_input(machine, index, inputnum);
765
 
        return (speaker != NULL) ? speaker->input_gain(inputnum) : 0;
766
 
}
767
 
 
768
 
 
769
 
/*-------------------------------------------------
770
 
    sound_get_default_gain - return the default
771
 
    gain of the nth user value
772
 
-------------------------------------------------*/
773
 
 
774
 
float sound_get_default_gain(running_machine *machine, int index)
775
 
{
776
 
        int inputnum;
777
 
        speaker_device *speaker = index_to_input(machine, index, inputnum);
778
 
        return (speaker != NULL) ? speaker->input_default_gain(inputnum) : 0;
779
 
}
780
 
 
781
 
 
782
 
/*-------------------------------------------------
783
 
    sound_get_user_gain_name - return the name
784
 
    of the nth user value
785
 
-------------------------------------------------*/
786
 
 
787
 
const char *sound_get_user_gain_name(running_machine *machine, int index)
788
 
{
789
 
        int inputnum;
790
 
        speaker_device *speaker = index_to_input(machine, index, inputnum);
791
 
        return (speaker != NULL) ? speaker->input_name(inputnum) : 0;
792
 
}