void speaker_device::mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress) { // skip if no stream if (m_mixer_stream == NULL) return; // update the stream, getting the start/end pointers around the operation int numsamples; const stream_sample_t *stream_buf = stream_get_output_since_last_update(m_mixer_stream, 0, &numsamples); // set or assert that all streams have the same count if (samples_this_update == 0) { samples_this_update = numsamples; /* reset the mixing streams */ memset(leftmix, 0, samples_this_update * sizeof(*leftmix)); memset(rightmix, 0, samples_this_update * sizeof(*rightmix)); } assert(samples_this_update == numsamples); #ifdef MAME_DEBUG // debug version: keep track of the maximum sample for (int sample = 0; sample < samples_this_update; sample++) { if (stream_buf[sample] > m_max_sample) m_max_sample = stream_buf[sample]; else if (-stream_buf[sample] > m_max_sample) m_max_sample = -stream_buf[sample]; if (stream_buf[sample] > 32767 || stream_buf[sample] < -32768) m_clipped_samples++; m_total_samples++; } #endif // mix if sound is enabled if (!suppress) { // if the speaker is centered, send to both left and right if (m_config.m_x == 0) for (int sample = 0; sample < samples_this_update; sample++) { leftmix[sample] += stream_buf[sample]; rightmix[sample] += stream_buf[sample]; } // if the speaker is to the left, send only to the left else if (m_config.m_x < 0) for (int sample = 0; sample < samples_this_update; sample++) leftmix[sample] += stream_buf[sample]; // if the speaker is to the right, send only to the right else for (int sample = 0; sample < samples_this_update; sample++) rightmix[sample] += stream_buf[sample]; } }
static TIMER_CALLBACK( sound_update ) { UINT32 finalmix_step, finalmix_offset; int samples_this_update = 0; int sample, spknum; VPRINTF(("sound_update\n")); profiler_mark(PROFILER_SOUND); /* force all the speaker streams to generate the proper number of samples */ for (spknum = 0; spknum < totalspeakers; spknum++) { speaker_info *spk = &speaker[spknum]; const stream_sample_t *stream_buf; /* get the output buffer */ if (spk->mixer_stream != NULL) { int numsamples; /* update the stream, getting the start/end pointers around the operation */ stream_buf = stream_get_output_since_last_update(spk->mixer_stream, 0, &numsamples); /* set or assert that all streams have the same count */ if (samples_this_update == 0) { samples_this_update = numsamples; /* reset the mixing streams */ memset(leftmix, 0, samples_this_update * sizeof(*leftmix)); memset(rightmix, 0, samples_this_update * sizeof(*rightmix)); } assert(samples_this_update == numsamples); #ifdef MAME_DEBUG /* debug version: keep track of the maximum sample */ for (sample = 0; sample < samples_this_update; sample++) { if (stream_buf[sample] > spk->max_sample) spk->max_sample = stream_buf[sample]; else if (-stream_buf[sample] > spk->max_sample) spk->max_sample = -stream_buf[sample]; if (stream_buf[sample] > 32767 || stream_buf[sample] < -32768) spk->clipped_samples++; spk->total_samples++; } #endif /* mix if sound is enabled */ if (global_sound_enabled && !nosound_mode) { /* if the speaker is centered, send to both left and right */ if (spk->speaker->x == 0) for (sample = 0; sample < samples_this_update; sample++) { leftmix[sample] += stream_buf[sample]; rightmix[sample] += stream_buf[sample]; } /* if the speaker is to the left, send only to the left */ else if (spk->speaker->x < 0) for (sample = 0; sample < samples_this_update; sample++) leftmix[sample] += stream_buf[sample]; /* if the speaker is to the right, send only to the right */ else for (sample = 0; sample < samples_this_update; sample++) rightmix[sample] += stream_buf[sample]; } } } /* now downmix the final result */ finalmix_step = video_get_speed_factor(); finalmix_offset = 0; for (sample = finalmix_leftover; sample < samples_this_update * 100; sample += finalmix_step) { int sampindex = sample / 100; INT32 samp; /* clamp the left side */ samp = leftmix[sampindex]; if (samp < -32768) samp = -32768; else if (samp > 32767) samp = 32767; finalmix[finalmix_offset++] = samp; /* clamp the right side */ samp = rightmix[sampindex]; if (samp < -32768) samp = -32768; else if (samp > 32767) samp = 32767; finalmix[finalmix_offset++] = samp; } finalmix_leftover = sample - samples_this_update * 100; /* play the result */ if (finalmix_offset > 0) { osd_update_audio_stream(finalmix, finalmix_offset / 2); if (wavfile != NULL) wav_add_data_16(wavfile, finalmix, finalmix_offset); } /* update the streamer */ streams_update(machine); profiler_mark(PROFILER_END); }