voice.cpp
1 // --------------------------------------------------------------------------- 2 // This file is part of reSID, a MOS6581 SID emulator engine. 3 // Copyright (C) 2004 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 #define __VOICE_CC__ 21 #include "voice.h" 22 23 RESID_NAMESPACE_START 24 25 // ---------------------------------------------------------------------------- 26 // Constructor. 27 // ---------------------------------------------------------------------------- 28 Voice::Voice() 29 : muted(false) 30 { 31 //set_chip_model(MOS6581); 32 {//instead: 33 wave_zero = 0x380; 34 voice_DC = 0x800*0xff; 35 } 36 } 37 38 // ---------------------------------------------------------------------------- 39 // Set chip model. 40 // ---------------------------------------------------------------------------- 41 /* 42 void Voice::set_chip_model(chip_model model) 43 { 44 wave.set_chip_model(model); 45 46 if (model == MOS6581) { 47 // The waveform D/A converter introduces a DC offset in the signal 48 // to the envelope multiplying D/A converter. The "zero" level of 49 // the waveform D/A converter can be found as follows: 50 // 51 // Measure the "zero" voltage of voice 3 on the SID audio output 52 // pin, routing only voice 3 to the mixer ($d417 = $0b, $d418 = 53 // $0f, all other registers zeroed). 54 // 55 // Then set the sustain level for voice 3 to maximum and search for 56 // the waveform output value yielding the same voltage as found 57 // above. This is done by trying out different waveform output 58 // values until the correct value is found, e.g. with the following 59 // program: 60 // 61 // lda #$08 62 // sta $d412 63 // lda #$0b 64 // sta $d417 65 // lda #$0f 66 // sta $d418 67 // lda #$f0 68 // sta $d414 69 // lda #$21 70 // sta $d412 71 // lda #$01 72 // sta $d40e 73 // 74 // ldx #$00 75 // lda #$38 ; Tweak this to find the "zero" level 76 //l cmp $d41b 77 // bne l 78 // stx $d40e ; Stop frequency counter - freeze waveform output 79 // brk 80 // 81 // The waveform output range is 0x000 to 0xfff, so the "zero" 82 // level should ideally have been 0x800. In the measured chip, the 83 // waveform output "zero" level was found to be 0x380 (i.e. $d41b 84 // = 0x38) at 5.94V. 85 86 wave_zero = 0x380; 87 88 // The envelope multiplying D/A converter introduces another DC 89 // offset. This is isolated by the following measurements: 90 // 91 // * The "zero" output level of the mixer at full volume is 5.44V. 92 // * Routing one voice to the mixer at full volume yields 93 // 6.75V at maximum voice output (wave = 0xfff, sustain = 0xf) 94 // 5.94V at "zero" voice output (wave = any, sustain = 0x0) 95 // 5.70V at minimum voice output (wave = 0x000, sustain = 0xf) 96 // * The DC offset of one voice is (5.94V - 5.44V) = 0.50V 97 // * The dynamic range of one voice is |6.75V - 5.70V| = 1.05V 98 // * The DC offset is thus 0.50V/1.05V ~ 1/2 of the dynamic range. 99 // 100 // Note that by removing the DC offset, we get the following ranges for 101 // one voice: 102 // y > 0: (6.75V - 5.44V) - 0.50V = 0.81V 103 // y < 0: (5.70V - 5.44V) - 0.50V = -0.24V 104 // The scaling of the voice amplitude is not symmetric about y = 0; 105 // this follows from the DC level in the waveform output. 106 107 voice_DC = 0x800*0xff; 108 } 109 else { 110 // No DC offsets in the MOS8580. 111 wave_zero = 0x800; 112 voice_DC = 0; 113 } 114 } 115 */ 116 // ---------------------------------------------------------------------------- 117 // Set sync source. 118 // ---------------------------------------------------------------------------- 119 void Voice::set_sync_source(Voice* source) 120 { 121 wave.set_sync_source(&source->wave); 122 } 123 124 // ---------------------------------------------------------------------------- 125 // Register functions. 126 // ---------------------------------------------------------------------------- 127 void Voice::writeCONTROL_REG(reg8 control) 128 { 129 wave.writeCONTROL_REG(control); 130 envelope.writeCONTROL_REG(control); 131 } 132 133 // ---------------------------------------------------------------------------- 134 // SID reset. 135 // ---------------------------------------------------------------------------- 136 void Voice::reset() 137 { 138 wave.reset(); 139 envelope.reset(); 140 } 141 142 143 // ---------------------------------------------------------------------------- 144 // Voice mute. 145 // ---------------------------------------------------------------------------- 146 void Voice::mute(bool enable) 147 { 148 // enable = true (means voice is muted) 149 muted = enable; 150 } 151 152 RESID_NAMESPACE_STOP