1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
#ifndef MAME_SOUND_CEM3394_H
#define MAME_SOUND_CEM3394_H
#pragma once
#include "sound/va_vcf.h"
class cem3394_device : public device_t, public device_sound_interface
{
public:
// inputs
// Each of these CV inputs can either be specified with `set_voltage()`, or
// provided via a sound stream.
enum
{
AUDIO_INPUT = 0, // not valid for set_voltage()
VCO_FREQUENCY,
MODULATION_AMOUNT,
WAVE_SELECT,
PULSE_WIDTH,
MIXER_BALANCE,
FILTER_RESONANCE,
FILTER_FREQUENCY,
FINAL_GAIN,
INPUT_COUNT
};
cem3394_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0) ATTR_COLD;
// The constructor will initialize components values to those recommended
// in the datasheet. configure() can be used to change those.
// r_vco: Pin 1 - Resistor to VEE. Sets reference current for the VCO internals.
// c_vco: Pin 4 - VCO timing capacitor.
// c_vcf: Pin 12 (or 13, or 14, they should be equal) - VCF capacitor.
// c_ac: Pin 17 - AC-coupling capacitor on the VCF output.
cem3394_device &configure(double r_vco, double c_vco, double c_vcf, double c_ac) ATTR_COLD;
protected:
// device-level overrides
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream) override;
public:
// Set the voltage going to a particular parameter
void set_voltage(int input, double voltage);
// Requesting a streaming voltage will force a stream update.
double get_voltage(int input);
// Get the translated parameter associated with the given input as follows:
// VCO_FREQUENCY: frequency in Hz
// MODULATION_AMOUNT: scale factor, 0.0 to 2.0
// WAVE_SELECT: voltage from this line
// PULSE_WIDTH: width fraction, from 0.0 to 1.0
// MIXER_BALANCE: balance, from -1.0 to 1.0
// FILTER_RESONANCE: resonance, from 0.0 to 1.0
// FILTER_FREQUENCY: frequency, in Hz
// FINAL_GAIN: gain, in dB
// Requesting a parameter associated with a streaming input will force a
// stream update.
double get_parameter(int input);
private:
double compute_db(double voltage);
sound_stream::sample_t compute_db_volume(double voltage);
void set_voltage_internal(int input, double voltage);
double hpf(double input);
required_device<va_lpf4_device> m_vcf;
// device configuration, not needed in save state
sound_stream *m_stream; // our stream
double m_inv_sample_rate; // 1/current sample rate
double m_vco_zero_freq; // frequency of VCO at 0.0V
double m_filter_zero_freq; // frequency of filter at 0.0V
double m_hpf_k; // RC filter coefficient for AC coupling
// device state
double m_values[INPUT_COUNT]; // raw values of registers
u8 m_wave_select; // flags which waveforms are enabled
double m_volume; // linear overall volume (0-1)
double m_mixer_internal; // linear internal volume (0-1)
double m_mixer_external; // linear external volume (0-1)
double m_vco_position; // current VCO frequency position (always < 1.0)
double m_vco_step; // per-sample VCO step
double m_filter_frequency; // baseline filter frequency
double m_filter_modulation; // depth of modulation (up to 1.0)
double m_filter_resonance; // depth of modulation (up to 1.0)
double m_pulse_width; // fractional pulse width
double m_hpf_mem; // AC coupling filter memory
};
DECLARE_DEVICE_TYPE(CEM3394, cem3394_device)
#endif // MAME_SOUND_CEM3394_H
|