summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/speaker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/speaker.cpp')
-rw-r--r--src/emu/speaker.cpp76
1 files changed, 47 insertions, 29 deletions
diff --git a/src/emu/speaker.cpp b/src/emu/speaker.cpp
index f5f507d242b..3cbb14355a4 100644
--- a/src/emu/speaker.cpp
+++ b/src/emu/speaker.cpp
@@ -56,38 +56,31 @@ speaker_device::~speaker_device()
// mix - mix in samples from the speaker's stream
//-------------------------------------------------
-void speaker_device::mix(s32 *leftmix, s32 *rightmix, int &samples_this_update, bool suppress)
+void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, attotime start, attotime end, int expected_samples, bool suppress)
{
// skip if no stream
if (m_mixer_stream == nullptr)
return;
- // update the stream, getting the start/end pointers around the operation
- int numsamples;
- const stream_sample_t *stream_buf = m_mixer_stream->output_since_last_update(0, numsamples);
-
- // set or assert that all streams have the same count
- if (samples_this_update == 0)
- {
- samples_this_update = numsamples;
+ // skip if invalid range
+ if (start > end)
+ return;
- // reset the mixing streams
- std::fill_n(leftmix, samples_this_update, 0);
- std::fill_n(rightmix, samples_this_update, 0);
- }
- assert(samples_this_update == numsamples);
+ // get a view on the desired range
+ read_stream_view view = m_mixer_stream->update_view(start, end);
+ sound_assert(view.samples() >= expected_samples);
// track maximum sample value for each 0.1s bucket
if (machine().options().speaker_report() != 0)
{
u32 samples_per_bucket = m_mixer_stream->sample_rate() / BUCKETS_PER_SECOND;
- for (int sample = 0; sample < samples_this_update; sample++)
+ for (int sample = 0; sample < expected_samples; sample++)
{
- m_current_max = std::max(m_current_max, abs(stream_buf[sample]));
+ m_current_max = std::max(m_current_max, fabsf(view.get(sample)));
if (++m_samples_this_bucket >= samples_per_bucket)
{
m_max_sample.push_back(m_current_max);
- m_current_max = 0;
+ m_current_max = 0.0f;
m_samples_this_bucket = 0;
}
}
@@ -98,21 +91,22 @@ void speaker_device::mix(s32 *leftmix, s32 *rightmix, int &samples_this_update,
{
// if the speaker is centered, send to both left and right
if (m_x == 0)
- for (int sample = 0; sample < samples_this_update; sample++)
+ for (int sample = 0; sample < expected_samples; sample++)
{
- leftmix[sample] += stream_buf[sample];
- rightmix[sample] += stream_buf[sample];
+ stream_buffer::sample_t cursample = view.get(sample);
+ leftmix[sample] += cursample;
+ rightmix[sample] += cursample;
}
// if the speaker is to the left, send only to the left
else if (m_x < 0)
- for (int sample = 0; sample < samples_this_update; sample++)
- leftmix[sample] += stream_buf[sample];
+ for (int sample = 0; sample < expected_samples; sample++)
+ leftmix[sample] += view.get(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];
+ for (int sample = 0; sample < expected_samples; sample++)
+ rightmix[sample] += view.get(sample);
}
}
@@ -143,27 +137,51 @@ void speaker_device::device_stop()
m_max_sample.push_back(m_current_max);
// determine overall maximum and number of clipped buckets
- s32 overallmax = 0;
+ stream_buffer::sample_t overallmax = 0;
u32 clipped = 0;
for (auto &curmax : m_max_sample)
{
overallmax = std::max(overallmax, curmax);
- if (curmax > 32767)
+ if (curmax > stream_buffer::sample_t(1.0))
clipped++;
}
// levels 1 and 2 just get a summary
if (clipped != 0 || report == 2 || report == 4)
- osd_printf_info("Speaker \"%s\" - max = %d (gain *= %.3f) - clipped in %d/%d (%d%%) buckets\n", tag(), overallmax, 32767.0 / (overallmax ? overallmax : 1), clipped, m_max_sample.size(), clipped * 100 / m_max_sample.size());
+ osd_printf_info("Speaker \"%s\" - max = %.5f (gain *= %.3f) - clipped in %d/%d (%d%%) buckets\n", tag(), overallmax, 1 / (overallmax ? overallmax : 1), clipped, m_max_sample.size(), clipped * 100 / m_max_sample.size());
// levels 3 and 4 get a full dump
if (report >= 3)
{
+ static char const * const s_stars = "************************************************************";
+ static char const * const s_spaces = " ";
+ int totalstars = strlen(s_stars);
double t = 0;
+ if (overallmax < 1.0)
+ overallmax = 1.0;
+ int leftstars = totalstars / overallmax;
for (auto &curmax : m_max_sample)
{
- if (curmax > 32767 || report == 4)
- osd_printf_info(" t=%5.1f max=%6d\n", t, curmax);
+ if (curmax > stream_buffer::sample_t(1.0) || report == 4)
+ {
+ osd_printf_info("%6.1f: %9.5f |", t, curmax);
+ if (curmax == 0)
+ osd_printf_info("%.*s|\n", leftstars, s_spaces);
+ else if (curmax <= 1.0)
+ {
+ int stars = std::max(1, std::min(leftstars, int(curmax * totalstars / overallmax)));
+ osd_printf_info("%.*s", stars, s_stars);
+ int spaces = leftstars - stars;
+ if (spaces != 0)
+ osd_printf_info("%.*s", spaces, s_spaces);
+ osd_printf_info("|\n");
+ }
+ else
+ {
+ int rightstars = std::max(1, std::min(totalstars, int(curmax * totalstars / overallmax)) - leftstars);
+ osd_printf_info("%.*s|%.*s\n", leftstars, s_stars, rightstars, s_stars);
+ }
+ }
t += 1.0 / double(BUCKETS_PER_SECOND);
}
}