diff options
Diffstat (limited to 'src/devices/sound/sn76477.cpp')
-rw-r--r-- | src/devices/sound/sn76477.cpp | 141 |
1 files changed, 79 insertions, 62 deletions
diff --git a/src/devices/sound/sn76477.cpp b/src/devices/sound/sn76477.cpp index c259b3cb0ed..ec855769be6 100644 --- a/src/devices/sound/sn76477.cpp +++ b/src/devices/sound/sn76477.cpp @@ -49,7 +49,8 @@ * *****************************************************************************/ -#define VERBOSE 1 +#define VERBOSE (0) +#include "logmacro.h" /* if 1, create a .wav file of the sound produced */ #define LOG_WAV 0 @@ -75,8 +76,6 @@ #define LOG_WAV_FILE_NAME "sn76477_%s.wav" -#define LOG(n,...) do { if (VERBOSE >= (n)) logerror(__VA_ARGS__); } while (0) - #define CHECK_BOOLEAN assert((state & 0x01) == state) #define CHECK_POSITIVE assert(data >= 0.0) #define CHECK_VOLTAGE assert((data >= 0.0) && (data <= 5.0)) @@ -203,7 +202,7 @@ sn76477_device::sn76477_device(const machine_config &mconfig, const char *tag, d void sn76477_device::device_start() { - m_channel = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); + m_channel = stream_alloc(0, 1, machine().sample_rate()); if (clock() > 0) { @@ -627,7 +626,7 @@ void sn76477_device::log_enable_line() "Enabled", "Inhibited" }; - LOG(1, "SN76477: Enable line (9): %d [%s]\n", m_enable, desc[m_enable]); + LOG("Enable line (9): %d [%s]\n", m_enable, desc[m_enable]); } @@ -639,7 +638,7 @@ void sn76477_device::log_mixer_mode() "SLF/Noise", "SLF/VCO/Noise", "SLF/VCO", "Inhibit" }; - LOG(1, "SN76477: Mixer mode (25-27): %d [%s]\n", m_mixer_mode, desc[m_mixer_mode]); + LOG("Mixer mode (25-27): %d [%s]\n", m_mixer_mode, desc[m_mixer_mode]); } @@ -650,7 +649,7 @@ void sn76477_device::log_envelope_mode() "VCO", "One-Shot", "Mixer Only", "VCO with Alternating Polarity" }; - LOG(1, "SN76477: Envelope mode (1,28): %d [%s]\n", m_envelope_mode, desc[m_envelope_mode]); + LOG("Envelope mode (1,28): %d [%s]\n", m_envelope_mode, desc[m_envelope_mode]); } @@ -661,7 +660,7 @@ void sn76477_device::log_vco_mode() "External (Pin 16)", "Internal (SLF)" }; - LOG(1, "SN76477: VCO mode (22): %d [%s]\n", m_vco_mode, desc[m_vco_mode]); + LOG("VCO mode (22): %d [%s]\n", m_vco_mode, desc[m_vco_mode]); } @@ -671,16 +670,16 @@ void sn76477_device::log_one_shot_time() { if (compute_one_shot_cap_charging_rate() > 0) { - LOG(1, "SN76477: One-shot time (23,24): %.4f sec\n", ONE_SHOT_CAP_VOLTAGE_RANGE * (1 / compute_one_shot_cap_charging_rate())); + LOG("One-shot time (23,24): %.4f sec\n", ONE_SHOT_CAP_VOLTAGE_RANGE * (1 / compute_one_shot_cap_charging_rate())); } else { - LOG(1, "SN76477: One-shot time (23,24): N/A\n"); + LOG("One-shot time (23,24): N/A\n"); } } else { - LOG(1, "SN76477: One-shot time (23,24): External (cap = %.2fV)\n", m_one_shot_cap_voltage); + LOG("One-shot time (23,24): External (cap = %.2fV)\n", m_one_shot_cap_voltage); } } @@ -694,29 +693,29 @@ void sn76477_device::log_slf_freq() double charging_time = (1 / compute_slf_cap_charging_rate()) * SLF_CAP_VOLTAGE_RANGE; double discharging_time = (1 / compute_slf_cap_discharging_rate()) * SLF_CAP_VOLTAGE_RANGE; - LOG(1, "SN76477: SLF frequency (20,21): %.2f Hz\n", 1 / (charging_time + discharging_time)); + LOG("SLF frequency (20,21): %.2f Hz\n", 1 / (charging_time + discharging_time)); } else { - LOG(1, "SN76477: SLF frequency (20,21): N/A\n"); + LOG("SLF frequency (20,21): N/A\n"); } } else { - LOG(1, "SN76477: SLF frequency (20,21): External (cap = %.2fV)\n", m_slf_cap_voltage); + LOG("SLF frequency (20,21): External (cap = %.2fV)\n", m_slf_cap_voltage); } } void sn76477_device::log_vco_pitch_voltage() { - LOG(1, "SN76477: VCO pitch voltage (19): %.2fV\n", m_pitch_voltage); + LOG("VCO pitch voltage (19): %.2fV\n", m_pitch_voltage); } void sn76477_device::log_vco_duty_cycle() { - LOG(1, "SN76477: VCO duty cycle (16,19): %.0f%%\n", compute_vco_duty_cycle() * 100.0); + LOG("VCO duty cycle (16,19): %.0f%%\n", compute_vco_duty_cycle() * 100.0); } @@ -729,16 +728,16 @@ void sn76477_device::log_vco_freq() double min_freq = compute_vco_cap_charging_discharging_rate() / (2 * VCO_CAP_VOLTAGE_RANGE); double max_freq = compute_vco_cap_charging_discharging_rate() / (2 * VCO_TO_SLF_VOLTAGE_DIFF); - LOG(1, "SN76477: VCO frequency (17,18): %.2f Hz - %.1f Hz\n", min_freq, max_freq); + LOG("VCO frequency (17,18): %.2f Hz - %.1f Hz\n", min_freq, max_freq); } else { - LOG(1, "SN76477: VCO frequency (17,18): N/A\n"); + LOG("VCO frequency (17,18): N/A\n"); } } else { - LOG(1, "SN76477: VCO frequency (17,18): External (cap = %.2fV)\n", m_vco_cap_voltage); + LOG("VCO frequency (17,18): External (cap = %.2fV)\n", m_vco_cap_voltage); } } @@ -750,13 +749,13 @@ void sn76477_device::log_vco_ext_voltage() double min_freq = compute_vco_cap_charging_discharging_rate() / (2 * VCO_CAP_VOLTAGE_RANGE); double max_freq = compute_vco_cap_charging_discharging_rate() / (2 * VCO_TO_SLF_VOLTAGE_DIFF); - LOG(1, "SN76477: VCO ext. voltage (16): %.2fV (%.2f Hz)\n", + LOG("VCO ext. voltage (16): %.2fV (%.2f Hz)\n", m_vco_voltage, min_freq + ((max_freq - min_freq) * m_vco_voltage / VCO_MAX_EXT_VOLTAGE)); } else { - LOG(1, "SN76477: VCO ext. voltage (16): %.2fV (saturated, no output)\n", m_vco_voltage); + LOG("VCO ext. voltage (16): %.2fV (saturated, no output)\n", m_vco_voltage); } } @@ -765,17 +764,17 @@ void sn76477_device::log_noise_gen_freq() { if (m_noise_clock_ext) { - LOG(1, "SN76477: Noise gen frequency (4): External\n"); + LOG("Noise gen frequency (4): External\n"); } else { if (compute_noise_gen_freq() > 0) { - LOG(1, "SN76477: Noise gen frequency (4): %d Hz\n", compute_noise_gen_freq()); + LOG("Noise gen frequency (4): %d Hz\n", compute_noise_gen_freq()); } else { - LOG(1, "SN76477: Noise gen frequency (4): N/A\n"); + LOG("Noise gen frequency (4): N/A\n"); } } } @@ -794,21 +793,21 @@ void sn76477_device::log_noise_filter_freq() double charging_time = (1 / charging_rate) * NOISE_CAP_VOLTAGE_RANGE; double discharging_time = (1 / charging_rate) * NOISE_CAP_VOLTAGE_RANGE; - LOG(1, "SN76477: Noise filter frequency (5,6): %.0f Hz\n", 1 / (charging_time + discharging_time)); + LOG("Noise filter frequency (5,6): %.0f Hz\n", 1 / (charging_time + discharging_time)); } else { - LOG(1, "SN76477: Noise filter frequency (5,6): Very Large (Filtering Disabled)\n"); + LOG("Noise filter frequency (5,6): Very Large (Filtering Disabled)\n"); } } else { - LOG(1, "SN76477: Noise filter frequency (5,6): N/A\n"); + LOG("Noise filter frequency (5,6): N/A\n"); } } else { - LOG(1, "SN76477: Noise filter frequency (5,6): External (cap = %.2fV)\n", m_noise_filter_cap); + LOG("Noise filter frequency (5,6): External (cap = %.2fV)\n", m_noise_filter_cap); } } @@ -819,16 +818,16 @@ void sn76477_device::log_attack_time() { if (compute_attack_decay_cap_charging_rate() > 0) { - LOG(1, "SN76477: Attack time (8,10): %.4f sec\n", AD_CAP_VOLTAGE_RANGE * (1 / compute_attack_decay_cap_charging_rate())); + LOG("Attack time (8,10): %.4f sec\n", AD_CAP_VOLTAGE_RANGE * (1 / compute_attack_decay_cap_charging_rate())); } else { - LOG(1, "SN76477: Attack time (8,10): N/A\n"); + LOG("Attack time (8,10): N/A\n"); } } else { - LOG(1, "SN76477: Attack time (8,10): External (cap = %.2fV)\n", m_attack_decay_cap_voltage); + LOG("Attack time (8,10): External (cap = %.2fV)\n", m_attack_decay_cap_voltage); } } @@ -839,23 +838,23 @@ void sn76477_device::log_decay_time() { if (compute_attack_decay_cap_discharging_rate() > 0) { - LOG(1, "SN76477: Decay time (7,8): %.4f sec\n", AD_CAP_VOLTAGE_RANGE * (1 / compute_attack_decay_cap_discharging_rate())); + LOG("Decay time (7,8): %.4f sec\n", AD_CAP_VOLTAGE_RANGE * (1 / compute_attack_decay_cap_discharging_rate())); } else { - LOG(1, "SN76477: Decay time (8,10): N/A\n"); + LOG("Decay time (8,10): N/A\n"); } } else { - LOG(1, "SN76477: Decay time (7, 8): External (cap = %.2fV)\n", m_attack_decay_cap_voltage); + LOG("Decay time (7, 8): External (cap = %.2fV)\n", m_attack_decay_cap_voltage); } } void sn76477_device::log_voltage_out() { - LOG(1, "SN76477: Voltage OUT range (11,12): %.2fV - %.2fV (clips above %.2fV)\n", + LOG("Voltage OUT range (11,12): %.2fV - %.2fV (clips above %.2fV)\n", OUT_CENTER_LEVEL_VOLTAGE + compute_center_to_peak_voltage_out() * out_neg_gain[(int)(AD_CAP_VOLTAGE_MAX * 10)], OUT_CENTER_LEVEL_VOLTAGE + compute_center_to_peak_voltage_out() * out_pos_gain[(int)(AD_CAP_VOLTAGE_MAX * 10)], OUT_HIGH_CLIP_THRESHOLD); @@ -892,24 +891,26 @@ void sn76477_device::log_complete_state() void sn76477_device::open_wav_file() { - char wav_file_name[30]; + std::string s = tag(); + std::replace(s.begin(), s.end(), ':', '_'); + + const std::string wav_file_name = util::string_format(LOG_WAV_FILE_NAME, s); - sprintf(wav_file_name, LOG_WAV_FILE_NAME, tag()); - m_file = wav_open(wav_file_name, m_our_sample_rate, 2); + m_file = util::wav_open(wav_file_name, m_our_sample_rate, 2); - LOG(1, "SN76477: Logging output: %s\n", wav_file_name); + LOG("Logging output: %s\n", wav_file_name); } void sn76477_device::close_wav_file() { - wav_close(m_file); + m_file.reset(); } void sn76477_device::add_wav_data(int16_t data_l, int16_t data_r) { - wav_add_data_16lr(m_file, &data_l, &data_r, 1); + util::wav_add_data_16lr(*m_file, &data_l, &data_r, 1); } @@ -949,7 +950,7 @@ inline uint32_t sn76477_device::generate_next_real_noise_bit() * *****************************************************************************/ -WRITE_LINE_MEMBER(sn76477_device::enable_w) +void sn76477_device::enable_w(int state) { CHECK_BOOLEAN; @@ -981,7 +982,7 @@ WRITE_LINE_MEMBER(sn76477_device::enable_w) * *****************************************************************************/ -WRITE_LINE_MEMBER( sn76477_device::mixer_a_w ) +void sn76477_device::mixer_a_w(int state) { CHECK_BOOLEAN; @@ -995,7 +996,7 @@ WRITE_LINE_MEMBER( sn76477_device::mixer_a_w ) } } -WRITE_LINE_MEMBER( sn76477_device::mixer_b_w ) +void sn76477_device::mixer_b_w(int state) { CHECK_BOOLEAN; @@ -1009,7 +1010,7 @@ WRITE_LINE_MEMBER( sn76477_device::mixer_b_w ) } } -WRITE_LINE_MEMBER( sn76477_device::mixer_c_w ) +void sn76477_device::mixer_c_w(int state) { CHECK_BOOLEAN; @@ -1029,7 +1030,7 @@ WRITE_LINE_MEMBER( sn76477_device::mixer_c_w ) * *****************************************************************************/ -WRITE_LINE_MEMBER( sn76477_device::envelope_1_w ) +void sn76477_device::envelope_1_w(int state) { CHECK_BOOLEAN; @@ -1043,7 +1044,7 @@ WRITE_LINE_MEMBER( sn76477_device::envelope_1_w ) } } -WRITE_LINE_MEMBER( sn76477_device::envelope_2_w ) +void sn76477_device::envelope_2_w(int state) { CHECK_BOOLEAN; @@ -1063,7 +1064,7 @@ WRITE_LINE_MEMBER( sn76477_device::envelope_2_w ) * *****************************************************************************/ -WRITE_LINE_MEMBER( sn76477_device::vco_w ) +void sn76477_device::vco_w(int state) { CHECK_BOOLEAN; @@ -1361,7 +1362,7 @@ void sn76477_device::pitch_voltage_w(double data) * *****************************************************************************/ -WRITE_LINE_MEMBER( sn76477_device::noise_clock_w ) +void sn76477_device::noise_clock_w(int state) { CHECK_BOOLEAN; @@ -1699,7 +1700,7 @@ void sn76477_device::state_save_register() // sound_stream_update - handle a stream update //------------------------------------------------- -void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void sn76477_device::sound_stream_update(sound_stream &stream) { double one_shot_cap_charging_step; double one_shot_cap_discharging_step; @@ -1718,8 +1719,6 @@ void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t * double voltage_out; double center_to_peak_voltage_out; - stream_sample_t *buffer = outputs[0]; - /* compute charging values, doing it here ensures that we always use the latest values */ one_shot_cap_charging_step = compute_one_shot_cap_charging_rate() / m_our_sample_rate; one_shot_cap_discharging_step = compute_one_shot_cap_discharging_rate() / m_our_sample_rate; @@ -1742,7 +1741,7 @@ void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t * /* process 'samples' number of samples */ - while (samples--) + for (int sampindex = 0; sampindex < stream.samples(); sampindex++) { /* update the one-shot cap voltage */ if (!m_one_shot_cap_voltage_ext) @@ -1991,12 +1990,12 @@ void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t * 32767 = 2 * OUT_CENTER_LEVEL_VOLTAGE + OUT_LOW_CLIP_THRESHOLD / Vout - Vmin \ - sample = | ----------- - 1 | * 32767 + sample = | ----------- - 1 | \ Vcen - Vmin / */ - *buffer++ = (((voltage_out - OUT_LOW_CLIP_THRESHOLD) / (OUT_CENTER_LEVEL_VOLTAGE - OUT_LOW_CLIP_THRESHOLD)) - 1) * 32767; + stream.put(0, sampindex, ((voltage_out - OUT_LOW_CLIP_THRESHOLD) / (OUT_CENTER_LEVEL_VOLTAGE - OUT_LOW_CLIP_THRESHOLD)) - 1); - if (LOG_WAV && LOG_WAV_ENABLED_ONLY && !m_enable) + if (LOG_WAV && (!m_enable || !LOG_WAV_ENABLED_ONLY)) { int16_t log_data_l; int16_t log_data_r; @@ -2005,30 +2004,48 @@ void sn76477_device::sound_stream_update(sound_stream &stream, stream_sample_t * { case 0: log_data_l = LOG_WAV_GAIN_FACTOR * voltage_out; - log_data_r = LOG_WAV_GAIN_FACTOR * voltage_out; break; case 1: log_data_l = LOG_WAV_GAIN_FACTOR * m_enable; - log_data_r = LOG_WAV_GAIN_FACTOR * m_enable; break; case 2: log_data_l = LOG_WAV_GAIN_FACTOR * m_one_shot_cap_voltage; - log_data_r = LOG_WAV_GAIN_FACTOR * m_one_shot_cap_voltage; break; case 3: log_data_l = LOG_WAV_GAIN_FACTOR * m_attack_decay_cap_voltage; - log_data_r = LOG_WAV_GAIN_FACTOR * m_attack_decay_cap_voltage; break; case 4: log_data_l = LOG_WAV_GAIN_FACTOR * m_slf_cap_voltage; - log_data_r = LOG_WAV_GAIN_FACTOR * m_slf_cap_voltage; break; case 5: log_data_l = LOG_WAV_GAIN_FACTOR * m_vco_cap_voltage; - log_data_r = LOG_WAV_GAIN_FACTOR * m_vco_cap_voltage; break; case 6: log_data_l = LOG_WAV_GAIN_FACTOR * m_noise_filter_cap_voltage; + break; + } + + switch (LOG_WAV_VALUE_R) + { + case 0: + log_data_r = LOG_WAV_GAIN_FACTOR * voltage_out; + break; + case 1: + log_data_r = LOG_WAV_GAIN_FACTOR * m_enable; + break; + case 2: + log_data_r = LOG_WAV_GAIN_FACTOR * m_one_shot_cap_voltage; + break; + case 3: + log_data_r = LOG_WAV_GAIN_FACTOR * m_attack_decay_cap_voltage; + break; + case 4: + log_data_r = LOG_WAV_GAIN_FACTOR * m_slf_cap_voltage; + break; + case 5: + log_data_r = LOG_WAV_GAIN_FACTOR * m_vco_cap_voltage; + break; + case 6: log_data_r = LOG_WAV_GAIN_FACTOR * m_noise_filter_cap_voltage; break; } |