diff options
Diffstat (limited to 'src/emu/speaker.cpp')
-rw-r--r-- | src/emu/speaker.cpp | 235 |
1 files changed, 53 insertions, 182 deletions
diff --git a/src/emu/speaker.cpp b/src/emu/speaker.cpp index 33b1e8d329a..d57f9119c24 100644 --- a/src/emu/speaker.cpp +++ b/src/emu/speaker.cpp @@ -5,6 +5,7 @@ speaker.cpp Speaker output sound device. + Microphone input sound device. ***************************************************************************/ @@ -14,210 +15,80 @@ -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -// device type definition DEFINE_DEVICE_TYPE(SPEAKER, speaker_device, "speaker", "Speaker") - - - -//************************************************************************** -// LIVE SPEAKER DEVICE -//************************************************************************** - -//------------------------------------------------- -// speaker_device - constructor -//------------------------------------------------- - -speaker_device::speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, SPEAKER, tag, owner, clock) - , device_mixer_interface(mconfig, *this) - , m_x(0.0) - , m_y(0.0) - , m_z(0.0) - , m_pan(0.0) - , m_defpan(0.0) - , m_current_max(0) - , m_samples_this_bucket(0) +DEFINE_DEVICE_TYPE(MICROPHONE, microphone_device, "microphone", "Microphone") + +const sound_io_device::position_name_mapping sound_io_device::position_name_mappings[] = { + { 0.0, 0.0, 1.0, "Front center" }, + { -0.2, 0.0, 1.0, "Front left" }, + { 0.0, -0.5, 1.0, "Front floor" }, + { 0.2, 0.0, 1.0, "Front right" }, + { 0.0, 0.0, -0.5, "Rear center" }, + { -0.2, 0.0, -0.5, "Rear left" }, + { 0.2, 0.0, -0.5, "Read right" }, + { 0.0, 0.0, -0.1, "Headrest center" }, + { -0.1, 0.0, -0.1, "Headrest left" }, + { 0.1, 0.0, -0.1, "Headrest right" }, + { 0.0, -0.5, 0.0, "Seat" }, + { 0.0, -0.2, 0.1, "Backrest" }, + { } +}; + +std::string sound_io_device::get_position_name(u32 channel) const { + for(unsigned int i = 0; position_name_mappings[i].m_name; i++) + if(m_positions[channel][0] == position_name_mappings[i].m_x && m_positions[channel][1] == position_name_mappings[i].m_y && m_positions[channel][2] == position_name_mappings[i].m_z) + return position_name_mappings[i].m_name; + return util::string_format("#%d", channel); } - -//------------------------------------------------- -// ~speaker_device - destructor -//------------------------------------------------- - -speaker_device::~speaker_device() +sound_io_device &sound_io_device::set_position(u32 channel, double x, double y, double z) { + if(channel >= m_positions.size()) + fatalerror("%s: Requested channel %d on %d channel device\n", tag(), channel, m_positions.size()); + m_positions[channel][0] = x; + m_positions[channel][1] = y; + m_positions[channel][2] = z; + return *this; } - -//------------------------------------------------- -// set_position - set speaker position -//------------------------------------------------- - -speaker_device &speaker_device::set_position(double x, double y, double z) +sound_io_device::sound_io_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 channels) : + device_t(mconfig, type, tag, owner, 0), + device_sound_interface(mconfig, *this), + m_positions(channels ? channels : 1) { - // as mentioned in the header file, y and z params currently have no effect - m_x = x; - m_y = y; - m_z = z; - - // hard pan to left - if (m_x < 0.0) - set_pan(-1.0f); - - // hard pan to right - else if (m_x > 0.0) - set_pan(1.0f); - - // center (mono) - else - set_pan(0.0f); - - m_defpan = m_pan; - return *this; } -//------------------------------------------------- -// mix - mix in samples from the speaker's stream -//------------------------------------------------- +sound_io_device::~sound_io_device() +{ +} -void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample_t *rightmix, attotime start, attotime end, int expected_samples, bool suppress) +speaker_device::~speaker_device() { - // skip if no stream - if (m_mixer_stream == nullptr) - return; - - // skip if invalid range - if (start > end) - return; - - // 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 < expected_samples; 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.0f; - m_samples_this_bucket = 0; - } - } - } - - // mix if sound is enabled - if (!suppress) - { - // if the speaker is hard panned to the left, send only to the left - if (m_pan == -1.0f) - for (int sample = 0; sample < expected_samples; sample++) - leftmix[sample] += view.get(sample); - - // if the speaker is hard panned to the right, send only to the right - else if (m_pan == 1.0f) - for (int sample = 0; sample < expected_samples; sample++) - rightmix[sample] += view.get(sample); - - // otherwise, send to both - else - { - const float leftpan = (m_pan <= 0.0f) ? 1.0f : 1.0f - m_pan; - const float rightpan = (m_pan >= 0.0f) ? 1.0f : 1.0f + m_pan; - - for (int sample = 0; sample < expected_samples; sample++) - { - stream_buffer::sample_t cursample = view.get(sample); - leftmix[sample] += cursample * leftpan; - rightmix[sample] += cursample * rightpan; - } - } - } } +microphone_device::~microphone_device() +{ +} -//------------------------------------------------- -// device_start - handle device startup -//------------------------------------------------- void speaker_device::device_start() { + m_stream = stream_alloc(m_positions.size(), 0, machine().sample_rate()); } +void microphone_device::device_start() +{ + m_stream = stream_alloc(0, m_positions.size(), machine().sample_rate()); +} -//------------------------------------------------- -// device_stop - cleanup and report -//------------------------------------------------- +void speaker_device::sound_stream_update(sound_stream &stream) +{ + machine().sound().output_push(m_id, stream); +} -void speaker_device::device_stop() +void microphone_device::sound_stream_update(sound_stream &stream) { - // level 1: just report if there was any clipping - // level 2: report the overall maximum, even if no clipping - // level 3: print a detailed list of all the times there was clipping - // level 4: print a detailed list of every bucket - int report = machine().options().speaker_report(); - if (report != 0) - { - m_max_sample.push_back(m_current_max); - - // determine overall maximum and number of clipped buckets - stream_buffer::sample_t overallmax = 0; - u32 clipped = 0; - for (auto &curmax : m_max_sample) - { - overallmax = std::max(overallmax, curmax); - 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 = %.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 > 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); - } - } - } + machine().sound().input_get(m_id, stream); } |