libsidplayfp  2.0.2
voice.h
1 // ---------------------------------------------------------------------------
2 // This file is part of reSID, a MOS6581 SID emulator engine.
3 // Copyright (C) 2010 Dag Lem <resid@nimrod.no>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // ---------------------------------------------------------------------------
19 
20 #ifndef RESID_VOICE_H
21 #define RESID_VOICE_H
22 
23 #include "resid-config.h"
24 #include "wave.h"
25 #include "envelope.h"
26 
27 namespace reSID
28 {
29 
30 class Voice
31 {
32 public:
33  Voice();
34 
35  void set_chip_model(chip_model model);
36  void set_sync_source(Voice*);
37  void reset();
38 
39  void writeCONTROL_REG(reg8);
40 
41  // Amplitude modulated waveform output.
42  // Range [-2048*255, 2047*255].
43  int output();
44 
45  WaveformGenerator wave;
46  EnvelopeGenerator envelope;
47 
48 protected:
49  // Waveform D/A zero level.
50  short wave_zero;
51 
52 friend class SID;
53 };
54 
55 
56 // ----------------------------------------------------------------------------
57 // Inline functions.
58 // The following function is defined inline because it is called every
59 // time a sample is calculated.
60 // ----------------------------------------------------------------------------
61 
62 #if RESID_INLINING || defined(RESID_VOICE_CC)
63 
64 // ----------------------------------------------------------------------------
65 // Amplitude modulated waveform output (20 bits).
66 // Ideal range [-2048*255, 2047*255].
67 // ----------------------------------------------------------------------------
68 
69 // The output for a voice is produced by a multiplying DAC, where the
70 // waveform output modulates the envelope output.
71 //
72 // As noted by Bob Yannes: "The 8-bit output of the Envelope Generator was then
73 // sent to the Multiplying D/A converter to modulate the amplitude of the
74 // selected Oscillator Waveform (to be technically accurate, actually the
75 // waveform was modulating the output of the Envelope Generator, but the result
76 // is the same)".
77 //
78 // 7 6 5 4 3 2 1 0 VGND
79 // | | | | | | | | | Missing
80 // 2R 2R 2R 2R 2R 2R 2R 2R 2R termination
81 // | | | | | | | | |
82 // --R---R---R---R---R---R---R-- ---
83 // | _____
84 // __|__ __|__ |
85 // ----- ===== |
86 // | | | | |
87 // 12V --- ----- ------- GND
88 // |
89 // vout
90 //
91 // Bit on: wout (see figure in wave.h)
92 // Bit off: 5V (VGND)
93 //
94 // As is the case with all MOS 6581 DACs, the termination to (virtual) ground
95 // at bit 0 is missing. The MOS 8580 has correct termination.
96 //
97 
98 RESID_INLINE
99 int Voice::output()
100 {
101  // Multiply oscillator output with envelope output.
102  return (wave.output() - wave_zero)*envelope.output();
103 }
104 
105 #endif // RESID_INLINING || defined(RESID_VOICE_CC)
106 
107 } // namespace reSID
108 
109 #endif // not RESID_VOICE_H
reSID::SID
Definition: sid.h:39
reSID::EnvelopeGenerator
Definition: envelope.h:38
reSID::Voice
Definition: voice.h:31
reSID::WaveformGenerator
Definition: wave.h:37