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
|
// license:BSD-3-Clause
// copyright-holders:m1macrophage
#ifndef MAME_SOUND_CEM3340_H
#define MAME_SOUND_CEM3340_H
#pragma once
DECLARE_DEVICE_TYPE(CEM3340, cem3340_device)
// A CEM3340 voltage-controlled oscillator.
//
// TODO:
// - Hard and soft sync inputs.
// - Linear FM input.
// - High frequency tracking input.
// - Hardcoded a lot of external components to the recommended values.
class cem3340_device : public device_t, public device_sound_interface
{
public:
enum input
{
INPUT_FREQ = 0,
INPUT_PW
};
enum output
{
OUTPUT_TRIANGLE = 0,
OUTPUT_RAMP,
OUTPUT_PULSE
};
// cf - timing capacitor between pin 11 and GND.
// rr - reference current resistor between pin 13 and V+.
cem3340_device(const machine_config &mconfig, const char *tag, device_t *owner, float cf, float rr) ATTR_COLD;
cem3340_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) ATTR_COLD;
cem3340_device &set_freq_cc(float freq_cc); // Frequency control current.
cem3340_device &set_pw_cv(float pw_cv); // Pulse width control voltage.
float freq(); // in Hz
u32 sample_rate() const { return m_stream->sample_rate(); }
// Returns the time remaining for the ramp waveform to cross the specified
// voltage, in an upwards direction. Also works for 0V.
attotime ramp_time_to_thresh(float threshold);
protected:
void device_start() override ATTR_COLD;
void sound_stream_update(sound_stream &stream) override;
private:
void set_freq_cc_internal(float freq_cc);
void set_pw_cv_internal(float pw_cv);
float poly_blep(float phase) const;
float poly_blamp(float phase) const;
// configuration
const float m_cf;
const float m_rr;
sound_stream *m_stream;
// state
float m_freq_cc;
float m_freq;
float m_pw_cv;
float m_pw;
float m_step;
float m_phase; // 0-1
};
#endif // MAME_SOUND_CEM3340_H
|