├── TODO ├── .gitignore ├── tests ├── data │ ├── envelope_output.dat │ ├── mod.rs │ ├── spline_output.rs │ └── sid_output.rs ├── sid_test.rs ├── external_filter_test.rs ├── spline_test.rs ├── envelope_test.rs ├── wave_test.rs └── filter_test.rs ├── benches ├── main.rs ├── sid_bench.rs └── sampler_bench.rs ├── .travis.yml ├── Cargo.toml ├── src ├── lib.rs ├── data │ ├── mod.rs │ ├── spline6581_f0.rs │ └── spline8580_f0.rs ├── voice.rs ├── external_filter.rs ├── math.rs ├── synth.rs ├── spline.rs ├── sid.rs ├── wave.rs ├── envelope.rs ├── filter.rs └── sampler.rs └── README.md /TODO: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | target 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /tests/data/envelope_output.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binaryfields/resid-rs/HEAD/tests/data/envelope_output.dat -------------------------------------------------------------------------------- /tests/data/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod sid_output; 2 | pub mod spline_output; 3 | pub mod wave_delta_output; 4 | pub mod wave_output; 5 | -------------------------------------------------------------------------------- /benches/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate criterion; 3 | 4 | mod sampler_bench; 5 | mod sid_bench; 6 | 7 | criterion_group!( 8 | benches, 9 | sid_bench::bench_sid, 10 | sampler_bench::bench_compute_convolution_fir 11 | ); 12 | 13 | criterion_main!(benches); 14 | -------------------------------------------------------------------------------- /benches/sid_bench.rs: -------------------------------------------------------------------------------- 1 | use criterion::Criterion; 2 | use resid::{ChipModel, Sid}; 3 | 4 | pub fn bench_sid(c: &mut Criterion) { 5 | c.bench_function("clock_delta", |b| { 6 | let mut sid = Sid::new(ChipModel::Mos6581); 7 | sid.write(0x05, 0x09); // AD1 8 | sid.write(0x06, 0x00); // SR1 9 | sid.write(0x18, 0x0f); // MODVOL 10 | sid.write(0x01, 25); // FREQHI1 11 | sid.write(0x00, 177); // FREQLO1 12 | sid.write(0x00, 0x21); // CR1 13 | b.iter(|| sid.clock_delta(22)) 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | matrix: 5 | include: 6 | - rust: stable 7 | env: DESCRIPTION="stable Rust" 8 | 9 | - rust: beta 10 | env: DESCRIPTION="Rust with no_std" 11 | script: 12 | - cargo test --lib --no-default-features 13 | - cargo test --tests --no-default-features 14 | 15 | before_install: 16 | - set -e 17 | - rustup self update 18 | 19 | script: 20 | - cargo test --lib 21 | - cargo test --tests 22 | 23 | after_script: 24 | - set +e 25 | 26 | cache: cargo 27 | before_cache: 28 | - chmod -R a+r $HOME/.cargo 29 | 30 | notifications: 31 | email: 32 | on_success: never 33 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "resid-rs" 3 | version = "1.1.1" 4 | edition = "2018" 5 | authors = ["Sebastian Jastrzebski "] 6 | description = "Port of reSID, a MOS6581 SID emulator engine, to Rust" 7 | license = "GPL-3.0+" 8 | repository = "https://github.com/binaryfields/resid-rs" 9 | readme = "README.md" 10 | keywords = ["c64", "commodore", "emulator", "resid", "sid"] 11 | categories = ["emulators"] 12 | 13 | [lib] 14 | name = "resid" 15 | 16 | [features] 17 | default = ["std"] 18 | std = ["alloc"] 19 | alloc = [] 20 | 21 | [dependencies] 22 | bit_field = "0.10" 23 | libm = { version = "0.2.0", optional = true } 24 | 25 | [dev-dependencies] 26 | criterion = "0.2" 27 | 28 | [[bench]] 29 | name = "main" 30 | harness = false 31 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![no_std] 7 | 8 | #[cfg(all(feature = "alloc", not(feature = "std")))] 9 | extern crate alloc; 10 | #[cfg(all(feature = "alloc", feature = "std"))] 11 | extern crate std as alloc; 12 | 13 | mod data; 14 | pub mod envelope; 15 | pub mod external_filter; 16 | pub mod filter; 17 | pub mod sampler; 18 | mod sid; 19 | pub mod spline; 20 | pub mod synth; 21 | pub mod voice; 22 | pub mod wave; 23 | 24 | #[cfg(not(feature = "std"))] 25 | mod math; 26 | 27 | #[derive(Clone, Copy)] 28 | pub enum ChipModel { 29 | Mos6581, 30 | Mos8580, 31 | } 32 | 33 | pub use self::sampler::SamplingMethod; 34 | pub use self::sid::Sid; 35 | -------------------------------------------------------------------------------- /src/data/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2018 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | mod spline6581_f0; 7 | mod spline8580_f0; 8 | mod wave6581_ps; 9 | mod wave6581_pst; 10 | mod wave6581_pt; 11 | mod wave6581_st; 12 | mod wave8580_ps; 13 | mod wave8580_pst; 14 | mod wave8580_pt; 15 | mod wave8580_st; 16 | 17 | pub use self::spline6581_f0::SPLINE6581_F0; 18 | pub use self::spline8580_f0::SPLINE8580_F0; 19 | pub use self::wave6581_ps::WAVE6581_PS; 20 | pub use self::wave6581_pst::WAVE6581_PST; 21 | pub use self::wave6581_pt::WAVE6581_PT; 22 | pub use self::wave6581_st::WAVE6581_ST; 23 | pub use self::wave8580_ps::WAVE8580_PS; 24 | pub use self::wave8580_pst::WAVE8580_PST; 25 | pub use self::wave8580_pt::WAVE8580_PT; 26 | pub use self::wave8580_st::WAVE8580_ST; 27 | -------------------------------------------------------------------------------- /tests/sid_test.rs: -------------------------------------------------------------------------------- 1 | mod data; 2 | 3 | use resid::{ChipModel, Sid}; 4 | 5 | #[rustfmt::skip] 6 | static SID_DATA: [u16; 51] = [ 7 | 25, 177, 250, 28, 214, 250, 8 | 25, 177, 250, 25, 177, 250, 9 | 25, 177, 125, 28, 214, 125, 10 | 32, 94, 750, 25, 177, 250, 11 | 28, 214, 250, 19, 63, 250, 12 | 19, 63, 250, 19, 63, 250, 13 | 21, 154, 63, 24, 63, 63, 14 | 25, 177, 250, 24, 63, 125, 15 | 19, 63, 250, 16 | ]; 17 | 18 | #[test] 19 | fn clock_delta() { 20 | let mut sid = Sid::new(ChipModel::Mos6581); 21 | sid.write(0x05, 0x09); // AD1 22 | sid.write(0x06, 0x00); // SR1 23 | sid.write(0x18, 0x0f); // MODVOL 24 | let mut i = 0; 25 | let mut index = 0usize; 26 | while i < SID_DATA.len() { 27 | sid.write(0x01, SID_DATA[i + 0] as u8); // FREQHI1 28 | sid.write(0x00, SID_DATA[i + 1] as u8); // FREQLO1 29 | sid.write(0x00, 0x21); // CR1 30 | for _j in 0..SID_DATA[i + 2] { 31 | sid.clock_delta(22); 32 | assert_eq!(sid.output(), data::sid_output::RESID_OUTPUT[index]); 33 | index += 1; 34 | } 35 | sid.write(0x00, 0x20); // CR1 36 | for _j in 0..50 { 37 | sid.clock_delta(22); 38 | assert_eq!(sid.output(), data::sid_output::RESID_OUTPUT[index]); 39 | index += 1; 40 | } 41 | i += 3; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /benches/sampler_bench.rs: -------------------------------------------------------------------------------- 1 | use criterion::Criterion; 2 | use resid::sampler::Sampler; 3 | use resid::synth::Synth; 4 | use resid::ChipModel; 5 | 6 | pub fn bench_compute_convolution_fir(c: &mut Criterion) { 7 | c.bench_function("convolution_fir", |b| { 8 | let sampler = Sampler::new(Synth::new(ChipModel::Mos6581)); 9 | let samples = [2i16; 1024]; 10 | let fir = [5i16; 1024]; 11 | b.iter(|| sampler.compute_convolution_fir(&samples[..], &fir[..])) 12 | }); 13 | c.bench_function("convolution_fir_avx2", |b| { 14 | let sampler = Sampler::new(Synth::new(ChipModel::Mos6581)); 15 | let samples = [2i16; 1024]; 16 | let fir = [5i16; 1024]; 17 | b.iter(|| unsafe { sampler.compute_convolution_fir_avx2(&samples[..], &fir[..]) }) 18 | }); 19 | c.bench_function("convolution_fir_sse", |b| { 20 | let sampler = Sampler::new(Synth::new(ChipModel::Mos6581)); 21 | let samples = [2i16; 1024]; 22 | let fir = [5i16; 1024]; 23 | b.iter(|| unsafe { sampler.compute_convolution_fir_sse(&samples[..], &fir[..]) }) 24 | }); 25 | c.bench_function("convolution_fir_fallback", |b| { 26 | let sampler = Sampler::new(Synth::new(ChipModel::Mos6581)); 27 | let samples = [2i16; 1024]; 28 | let fir = [5i16; 1024]; 29 | b.iter(|| sampler.compute_convolution_fir_fallback(&samples[..], &fir[..])) 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /tests/external_filter_test.rs: -------------------------------------------------------------------------------- 1 | use resid::external_filter::ExternalFilter; 2 | use resid::ChipModel; 3 | 4 | #[rustfmt::skip] 5 | static RESID_OUTPUT: [i32; 41] = [ 6 | 0, -100, -184, -255, -314, -362, -400, -429, 7 | -450, -464, -471, -472, -468, -460, -447, -431, 8 | -411, -388, -362, -334, -303, -270, -236, -200, 9 | -162, -123, -83, -42, 0, 42, 85, 129, 10 | 173, 218, 263, 309, 355, 402, 449, 496, 11 | 544 12 | ]; 13 | 14 | #[rustfmt::skip] 15 | static RESID_DELTA_OUTPUT: [i32; 41] = [ 16 | -989, -927, -864, -801, -738, -675, -612, -549, 17 | -486, -423, -360, -297, -234, -171, -108, -45, 18 | 8, 58, 108, 158, 208, 258, 308, 358, 19 | 408, 458, 508, 558, 608, 658, 708, 758, 20 | 808, 858, 908, 958, 1008, 1058, 1108, 1158, 21 | 1208 22 | ]; 23 | 24 | #[test] 25 | fn clock() { 26 | let mut ext_filter = ExternalFilter::new(ChipModel::Mos6581); 27 | let mut index = 0usize; 28 | let mut vi = -1000; 29 | while vi <= 1000 { 30 | ext_filter.clock(vi); 31 | let output = ext_filter.output(); 32 | assert_eq!(output, RESID_OUTPUT[index]); 33 | vi += 50; 34 | index += 1; 35 | } 36 | } 37 | 38 | #[test] 39 | fn clock_delta() { 40 | let mut ext_filter = ExternalFilter::new(ChipModel::Mos6581); 41 | let mut index = 0usize; 42 | let mut vi = -1000; 43 | while vi <= 1000 { 44 | ext_filter.clock_delta(100, vi); 45 | let output = ext_filter.output(); 46 | assert_eq!(output, RESID_DELTA_OUTPUT[index]); 47 | vi += 50; 48 | index += 1; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/spline_test.rs: -------------------------------------------------------------------------------- 1 | mod data; 2 | 3 | use resid::spline; 4 | 5 | static FO_POINTS_6581: [(i32, i32); 31] = [ 6 | // FC f FCHI FCLO 7 | // ---------------------------- 8 | (0, 220), // 0x00 - repeated end point 9 | (0, 220), // 0x00 10 | (128, 230), // 0x10 11 | (256, 250), // 0x20 12 | (384, 300), // 0x30 13 | (512, 420), // 0x40 14 | (640, 780), // 0x50 15 | (768, 1600), // 0x60 16 | (832, 2300), // 0x68 17 | (896, 3200), // 0x70 18 | (960, 4300), // 0x78 19 | (992, 5000), // 0x7c 20 | (1008, 5400), // 0x7e 21 | (1016, 5700), // 0x7f 22 | (1023, 6000), // 0x7f 0x07 23 | (1023, 6000), // 0x7f 0x07 - discontinuity 24 | (1024, 4600), // 0x80 - 25 | (1024, 4600), // 0x80 26 | (1032, 4800), // 0x81 27 | (1056, 5300), // 0x84 28 | (1088, 6000), // 0x88 29 | (1120, 6600), // 0x8c 30 | (1152, 7200), // 0x90 31 | (1280, 9500), // 0xa0 32 | (1408, 12000), // 0xb0 33 | (1536, 14500), // 0xc0 34 | (1664, 16000), // 0xd0 35 | (1792, 17100), // 0xe0 36 | (1920, 17700), // 0xf0 37 | (2047, 18000), // 0xff 0x07 38 | (2047, 18000), // 0xff 0x07 - repeated end point 39 | ]; 40 | 41 | fn set_f0(f0: &mut [i32; 2048]) { 42 | let points = FO_POINTS_6581 43 | .iter() 44 | .map(|&pt| spline::Point { 45 | x: pt.0 as f64, 46 | y: pt.1 as f64, 47 | }) 48 | .collect::>(); 49 | let mut plotter = spline::PointPlotter::new(f0); 50 | spline::interpolate(&points, &mut plotter, 1.0); 51 | } 52 | 53 | #[test] 54 | fn interpolate() { 55 | let mut f0 = [0i32; 2048]; 56 | set_f0(&mut f0); 57 | for i in 0..2048usize { 58 | assert_eq!(f0[i], data::spline_output::RESID_OUTPUT[i]); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # resid-rs 2 | 3 | [![Build Status](https://travis-ci.org/binaryfields/resid-rs.svg?branch=master)](https://travis-ci.org/binaryfields/resid-rs) 4 | [![Crates.io](https://img.shields.io/crates/v/resid-rs.svg?maxAge=2592000)](https://crates.io/crates/resid-rs) 5 | 6 | ### Overview 7 | 8 | Port of reSID, a MOS6581 SID emulator engine, to Rust. 9 | 10 | ### Story 11 | 12 | This project originated from zinc64, a Commodore 64 emulator, around Jan 2017. 13 | It evolved to the point where it can be useful to others working on C64 sound/emulation 14 | so it is packaged and shipped as a standalone crate. 15 | 16 | ### Usage 17 | 18 | Once SID register read/writes are wired up to resid, all that is left to do 19 | is to generate audio samples and push them to audio output buffer. 20 | 21 | while delta > 0 { 22 | let (samples, next_delta) = self.resid.sample(delta, &mut buffer[..], 1); 23 | let mut output = self.sound_buffer.lock().unwrap(); 24 | for i in 0..samples { 25 | output.write(buffer[i]); 26 | } 27 | delta = next_delta; 28 | } 29 | 30 | ### Components 31 | 32 | | Component | Status | 33 | |-------------------|-------------| 34 | | Envelope | Done | 35 | | ExternalFilter | Done | 36 | | Filter | Done | 37 | | Sampler | Done | 38 | | Spline | Done | 39 | | Wave | Done | 40 | | Sid | Done | 41 | 42 | ### Changelog 43 | 44 | - 0.3 - compliance with the original resid 45 | - 0.4 - full sampler support 46 | - 0.5 - closed performance gap largely due to resampling 47 | - 0.6 - SIMD optimization 48 | - 0.7 - continuous integration and GPLv3 49 | - 0.8 - documentation and api refinements/internal cleanup 50 | - 0.9 - migration to Rust 2018 51 | - 1.0 - no_std support 52 | - 1.1 - more idiomatic implementation, removes interior mutability and improves support for async rust 53 | 54 | ## Credits 55 | 56 | - Thanks to Dag Lem for his reSID implementation 57 | - Thanks to Daniel Collin for motivating me to put this out and helping out with code optimization 58 | - Commodore folks for building an iconic 8-bit machine 59 | - Rust developers for providing an incredible language to develop in 60 | -------------------------------------------------------------------------------- /src/voice.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | 8 | use super::envelope::EnvelopeGenerator; 9 | use super::wave::{Syncable, WaveformGenerator}; 10 | use super::ChipModel; 11 | 12 | /// The waveform output range is 0x000 to 0xfff, so the "zero" 13 | /// level should ideally have been 0x800. In the measured chip, the 14 | /// waveform output "zero" level was found to be 0x380 (i.e. $d41b 15 | /// = 0x38) at 5.94V. 16 | const WAVE_ZERO: i32 = 0x0380; 17 | 18 | /// The envelope multiplying D/A converter introduces another DC 19 | /// offset. This is isolated by the following measurements: 20 | /// 21 | /// * The "zero" output level of the mixer at full volume is 5.44V. 22 | /// * Routing one voice to the mixer at full volume yields 23 | /// 6.75V at maximum voice output (wave = 0xfff, sustain = 0xf) 24 | /// 5.94V at "zero" voice output (wave = any, sustain = 0x0) 25 | /// 5.70V at minimum voice output (wave = 0x000, sustain = 0xf) 26 | /// * The DC offset of one voice is (5.94V - 5.44V) = 0.50V 27 | /// * The dynamic range of one voice is |6.75V - 5.70V| = 1.05V 28 | /// * The DC offset is thus 0.50V/1.05V ~ 1/2 of the dynamic range. 29 | /// 30 | /// Note that by removing the DC offset, we get the following ranges for 31 | /// one voice: 32 | /// y > 0: (6.75V - 5.44V) - 0.50V = 0.81V 33 | /// y < 0: (5.70V - 5.44V) - 0.50V = -0.24V 34 | /// The scaling of the voice amplitude is not symmetric about y = 0; 35 | /// this follows from the DC level in the waveform output. 36 | const VOICE_DC: i32 = 0x800 * 0xff; 37 | 38 | #[derive(Clone, Copy)] 39 | pub struct Voice { 40 | // Configuration 41 | wave_zero: i32, 42 | voice_dc: i32, 43 | // Generators 44 | pub envelope: EnvelopeGenerator, 45 | pub wave: WaveformGenerator, 46 | } 47 | 48 | impl Voice { 49 | pub fn new(chip_model: ChipModel) -> Self { 50 | match chip_model { 51 | ChipModel::Mos6581 => Voice { 52 | wave_zero: WAVE_ZERO, 53 | voice_dc: VOICE_DC, 54 | envelope: EnvelopeGenerator::default(), 55 | wave: WaveformGenerator::new(chip_model), 56 | }, 57 | ChipModel::Mos8580 => Voice { 58 | // No DC offsets in the MOS8580. 59 | wave_zero: 0x800, 60 | voice_dc: 0, 61 | envelope: EnvelopeGenerator::default(), 62 | wave: WaveformGenerator::new(chip_model), 63 | }, 64 | } 65 | } 66 | 67 | pub fn set_control(&mut self, value: u8) { 68 | self.envelope.set_control(value); 69 | self.wave.set_control(value); 70 | } 71 | 72 | /// Amplitude modulated 20-bit waveform output. 73 | /// Range [-2048*255, 2047*255]. 74 | #[inline] 75 | pub fn output(&self, sync_source: Option<&WaveformGenerator>) -> i32 { 76 | // Multiply oscillator output with envelope output. 77 | (self.wave.output(sync_source) as i32 - self.wave_zero) * self.envelope.output() as i32 78 | + self.voice_dc 79 | } 80 | 81 | pub fn reset(&mut self) { 82 | self.envelope.reset(); 83 | self.wave.reset(); 84 | } 85 | } 86 | 87 | impl Syncable<&'_ Voice> { 88 | pub fn output(&self) -> i32 { 89 | self.main.output(Some(&self.sync_source.wave)) 90 | } 91 | } 92 | 93 | impl<'a> Syncable<&'a Voice> { 94 | pub fn wave(self) -> Syncable<&'a WaveformGenerator> { 95 | Syncable { 96 | main: &self.main.wave, 97 | sync_dest: &self.sync_dest.wave, 98 | sync_source: &self.sync_source.wave, 99 | } 100 | } 101 | } 102 | 103 | impl<'a> Syncable<&'a mut Voice> { 104 | pub fn wave(self) -> Syncable<&'a mut WaveformGenerator> { 105 | Syncable { 106 | main: &mut self.main.wave, 107 | sync_dest: &mut self.sync_dest.wave, 108 | sync_source: &mut self.sync_source.wave, 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/external_filter.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | use super::ChipModel; 7 | 8 | /// Maximum mixer DC output level; to be removed if the external 9 | /// filter is turned off: ((wave DC + voice DC)*voices + mixer DC)*volume 10 | /// See voice.cc and filter.cc for an explanation of the values. 11 | const MIXER_DC_6581: i32 = ((((0x800 - 0x380) + 0x800) * 0xff * 3 - 0xfff * 0xff / 18) >> 7) * 0x0f; 12 | 13 | /// Low-pass: R = 10kOhm, C = 1000pF; w0l = 1/RC = 1/(1e4*1e-9) = 100000 14 | /// High-pass: R = 1kOhm, C = 10uF; w0h = 1/RC = 1/(1e3*1e-5) = 100 15 | /// Multiply with 1.048576 to facilitate division by 1 000 000 by right- 16 | /// shifting 20 times (2 ^ 20 = 1048576). 17 | const W0_LP: i32 = 104_858; 18 | const W0_HP: i32 = 105; 19 | 20 | /// The audio output stage in a Commodore 64 consists of two STC networks, 21 | /// a low-pass filter with 3-dB frequency 16kHz followed by a high-pass 22 | /// filter with 3-dB frequency 16Hz (the latter provided an audio equipment 23 | /// input impedance of 1kOhm). 24 | /// The STC networks are connected with a BJT supposedly meant to act as 25 | /// a unity gain buffer, which is not really how it works. A more elaborate 26 | /// model would include the BJT, however DC circuit analysis yields BJT 27 | /// base-emitter and emitter-base impedances sufficiently low to produce 28 | /// additional low-pass and high-pass 3dB-frequencies in the order of hundreds 29 | /// of kHz. This calls for a sampling frequency of several MHz, which is far 30 | /// too high for practical use. 31 | #[derive(Clone, Copy)] 32 | pub struct ExternalFilter { 33 | // Configuration 34 | enabled: bool, 35 | mixer_dc: i32, 36 | w0_lp: i32, 37 | w0_hp: i32, 38 | // Runtime State 39 | vlp: i32, 40 | vhp: i32, 41 | vo: i32, 42 | } 43 | 44 | impl ExternalFilter { 45 | pub fn new(chip_model: ChipModel) -> Self { 46 | let mixer_dc = match chip_model { 47 | ChipModel::Mos6581 => MIXER_DC_6581, 48 | ChipModel::Mos8580 => 0, 49 | }; 50 | let mut filter = ExternalFilter { 51 | enabled: true, 52 | mixer_dc, 53 | w0_lp: W0_LP, 54 | w0_hp: W0_HP, 55 | vlp: 0, 56 | vhp: 0, 57 | vo: 0, 58 | }; 59 | filter.reset(); 60 | filter 61 | } 62 | 63 | pub fn set_enabled(&mut self, enabled: bool) { 64 | self.enabled = enabled; 65 | } 66 | 67 | #[inline] 68 | pub fn clock(&mut self, vi: i32) { 69 | // delta_t is converted to seconds given a 1MHz clock by dividing 70 | // with 1 000 000. 71 | // Calculate filter outputs. 72 | // Vo = Vlp - Vhp; 73 | // Vlp = Vlp + w0lp*(Vi - Vlp)*delta_t; 74 | // Vhp = Vhp + w0hp*(Vlp - Vhp)*delta_t; 75 | if self.enabled { 76 | let dvlp = ((self.w0_lp >> 8) * (vi - self.vlp)) >> 12; 77 | let dvhp = (self.w0_hp * (self.vlp - self.vhp)) >> 20; 78 | self.vo = self.vlp - self.vhp; 79 | self.vlp += dvlp; 80 | self.vhp += dvhp; 81 | } else { 82 | self.vlp = 0; 83 | self.vhp = 0; 84 | self.vo = vi - self.mixer_dc; 85 | } 86 | } 87 | 88 | #[inline] 89 | pub fn clock_delta(&mut self, mut delta: u32, vi: i32) { 90 | if self.enabled { 91 | // Maximum delta cycles for the external filter to work satisfactorily 92 | // is approximately 8. 93 | let mut delta_flt: u32 = 8; 94 | while delta != 0 { 95 | if delta < delta_flt { 96 | delta_flt = delta; 97 | } 98 | // delta_t is converted to seconds given a 1MHz clock by dividing 99 | // with 1 000 000. 100 | // Calculate filter outputs. 101 | // Vo = Vlp - Vhp; 102 | // Vlp = Vlp + w0lp*(Vi - Vlp)*delta_t; 103 | // Vhp = Vhp + w0hp*(Vlp - Vhp)*delta_t; 104 | let dvlp = (((self.w0_lp * delta_flt as i32) >> 8) * (vi - self.vlp)) >> 12; 105 | let dvhp = (self.w0_hp * delta_flt as i32 * (self.vlp - self.vhp)) >> 20; 106 | self.vo = self.vlp - self.vhp; 107 | self.vlp += dvlp; 108 | self.vhp += dvhp; 109 | delta -= delta_flt; 110 | } 111 | } else { 112 | self.vlp = 0; 113 | self.vhp = 0; 114 | self.vo = vi - self.mixer_dc; 115 | } 116 | } 117 | 118 | #[inline] 119 | pub fn output(&self) -> i32 { 120 | self.vo 121 | } 122 | 123 | pub fn reset(&mut self) { 124 | self.vlp = 0; 125 | self.vhp = 0; 126 | self.vo = 0; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /tests/envelope_test.rs: -------------------------------------------------------------------------------- 1 | use resid::envelope::EnvelopeGenerator; 2 | 3 | static RESID_OUTPUT: &'static [u8] = include_bytes!("data/envelope_output.dat"); 4 | 5 | #[test] 6 | fn clock() { 7 | let mut envelope = EnvelopeGenerator::default(); 8 | let mut cycles = 0u32; 9 | // setup 10 | envelope.set_attack_decay(0x02 << 4 | 0x00); 11 | envelope.set_sustain_release(0x02 << 4 | 0x01); 12 | envelope.set_control(0x01); 13 | let attack_cycles = 63u16; 14 | let decay_cycles = 9u16; 15 | let sustain_level = 0x22u8; 16 | let release_cycles = 32u16; 17 | let mut last_output = 0u8; 18 | let mut exp_counter = 0u8; 19 | let mut exp_period = 1u8; 20 | // test attack 21 | for _j in 0..0xff { 22 | for _i in 0..attack_cycles { 23 | envelope.clock(); 24 | cycles += 1; 25 | } 26 | let output = envelope.output(); 27 | assert_eq!(output, last_output + 1); 28 | last_output = output; 29 | } 30 | // test decay 31 | last_output = envelope.output(); 32 | while last_output != sustain_level { 33 | for _i in 0..decay_cycles { 34 | envelope.clock(); 35 | cycles += 1; 36 | } 37 | exp_counter += 1; 38 | if exp_counter == exp_period { 39 | exp_counter = 0; 40 | let output = envelope.output(); 41 | assert_eq!(output, last_output - 1); 42 | last_output = output; 43 | exp_period = match output { 44 | 0xff => 1, 45 | 0x5d => 2, 46 | 0x36 => 4, 47 | 0x1a => 8, 48 | 0x0e => 16, 49 | 0x06 => 30, 50 | 0x00 => 1, 51 | _ => exp_period, 52 | } 53 | } 54 | } 55 | // test sustain 56 | for _i in 0..2 { 57 | for _i in 0..decay_cycles { 58 | envelope.clock(); 59 | cycles += 1; 60 | } 61 | exp_counter += 1; 62 | if exp_counter == exp_period { 63 | exp_counter = 0; 64 | let output = envelope.output(); 65 | assert_eq!(output, last_output); 66 | } 67 | } 68 | // test release 69 | assert_eq!(cycles, 18963); 70 | envelope.set_control(0x00); 71 | while last_output != 0x00 { 72 | for _i in 0..release_cycles { 73 | envelope.clock(); 74 | cycles += 1; 75 | } 76 | exp_counter += 1; 77 | if exp_counter == exp_period { 78 | exp_counter = 0; 79 | let output = envelope.output(); 80 | assert_eq!(output, last_output - 1); 81 | last_output = output; 82 | exp_period = match output { 83 | 0xff => 1, 84 | 0x5d => 2, 85 | 0x36 => 4, 86 | 0x1a => 8, 87 | 0x0e => 16, 88 | 0x06 => 30, 89 | 0x00 => 1, 90 | _ => exp_period, 91 | } 92 | } 93 | } 94 | // test hold zero 95 | for _i in 0..2 { 96 | for _i in 0..release_cycles { 97 | envelope.clock(); 98 | cycles += 1; 99 | } 100 | exp_counter += 1; 101 | if exp_counter == exp_period { 102 | exp_counter = 0; 103 | let output = envelope.output(); 104 | assert_eq!(output, 0x00); 105 | } 106 | } 107 | // verify cycle count 108 | assert_eq!(cycles, 32915); 109 | } 110 | 111 | fn clock_delta() { 112 | let mut envelope = EnvelopeGenerator::default(); 113 | envelope.set_attack_decay(0x02 << 4 | 0x00); 114 | envelope.set_sustain_release(0x02 << 4 | 0x01); 115 | envelope.set_control(0x01); 116 | let mut envelope2 = EnvelopeGenerator::default(); 117 | envelope2.set_attack_decay(0x02 << 4 | 0x00); 118 | envelope2.set_sustain_release(0x02 << 4 | 0x01); 119 | envelope2.set_control(0x01); 120 | for i in 0..33000 { 121 | if i == 19000 { 122 | envelope.set_control(0x00); 123 | envelope2.set_control(0x00); 124 | } 125 | envelope.clock(); 126 | if i % 100 == 0 { 127 | envelope2.clock_delta(100); 128 | assert_eq!(envelope2.output(), envelope.output()); 129 | } 130 | } 131 | } 132 | 133 | #[test] 134 | fn resid_output() { 135 | let mut envelope = EnvelopeGenerator::default(); 136 | envelope.reset(); 137 | // setup 138 | envelope.set_attack_decay(0x02 << 4 | 0x00); 139 | envelope.set_sustain_release(0x02 << 4 | 0x01); 140 | envelope.set_control(0x01); 141 | // generate 142 | let mut buffer: Vec = Vec::new(); 143 | let mut i = 0; 144 | while i < 18963 { 145 | envelope.clock(); 146 | buffer.push(envelope.output()); 147 | i += 1; 148 | } 149 | envelope.set_control(0x00); 150 | while i < 32914 { 151 | envelope.clock(); 152 | buffer.push(envelope.output()); 153 | i += 1; 154 | } 155 | // validate 156 | assert_eq!(buffer.len(), RESID_OUTPUT.len()); 157 | assert_eq!(&*buffer, RESID_OUTPUT); 158 | } 159 | -------------------------------------------------------------------------------- /tests/wave_test.rs: -------------------------------------------------------------------------------- 1 | mod data; 2 | 3 | use resid::wave::WaveformGenerator; 4 | use resid::ChipModel; 5 | 6 | fn setup(wave: &mut WaveformGenerator, waveform: u8, freq: u16, pw: u16) { 7 | wave.set_control((waveform & 0x0f) << 4 | 0x00); 8 | wave.set_frequency_hi((freq >> 8) as u8); 9 | wave.set_frequency_lo((freq & 0xff) as u8); 10 | wave.set_pulse_width_hi((pw >> 8) as u8); 11 | wave.set_pulse_width_lo((pw & 0xff) as u8); 12 | } 13 | 14 | #[test] 15 | fn waveform_1() { 16 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 17 | setup(&mut wave, 1, 32000, 100); 18 | for i in 0..500 { 19 | wave.clock(); 20 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE1_OUTPUT[i]); 21 | } 22 | } 23 | 24 | #[test] 25 | fn waveform_2() { 26 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 27 | setup(&mut wave, 2, 16000, 100); 28 | for i in 0..500 { 29 | wave.clock(); 30 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE2_OUTPUT[i]); 31 | } 32 | } 33 | 34 | #[test] 35 | fn waveform_3() { 36 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 37 | setup(&mut wave, 3, 32000, 100); 38 | for i in 0..500 { 39 | wave.clock(); 40 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE3_OUTPUT[i]); 41 | } 42 | } 43 | 44 | #[test] 45 | fn waveform_4() { 46 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 47 | setup(&mut wave, 4, 16000, 1000); 48 | for i in 0..1500 { 49 | wave.clock(); 50 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE4_OUTPUT[i]); 51 | } 52 | } 53 | 54 | #[test] 55 | fn waveform_5() { 56 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 57 | setup(&mut wave, 5, 16000, 1000); 58 | for i in 0..1500 { 59 | wave.clock(); 60 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE5_OUTPUT[i]); 61 | } 62 | } 63 | 64 | #[test] 65 | fn waveform_6() { 66 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 67 | setup(&mut wave, 6, 16000, 1000); 68 | for i in 0..1500 { 69 | wave.clock(); 70 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE6_OUTPUT[i]); 71 | } 72 | } 73 | 74 | #[test] 75 | fn waveform_7() { 76 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 77 | setup(&mut wave, 7, 16000, 1000); 78 | for i in 0..1500 { 79 | wave.clock(); 80 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE7_OUTPUT[i]); 81 | } 82 | } 83 | 84 | #[test] 85 | fn waveform_8() { 86 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 87 | setup(&mut wave, 8, 16000, 1000); 88 | for i in 0..1500 { 89 | wave.clock(); 90 | assert_eq!(wave.output(None), data::wave_output::RESID_WAVE8_OUTPUT[i]); 91 | } 92 | } 93 | 94 | #[test] 95 | fn waveform_delta_1() { 96 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 97 | setup(&mut wave, 1, 32000, 100); 98 | for i in 0..500 { 99 | wave.clock_delta(25); 100 | assert_eq!( 101 | wave.output(None), 102 | data::wave_delta_output::RESID_WAVE1_OUTPUT[i] 103 | ); 104 | } 105 | } 106 | 107 | #[test] 108 | fn waveform_delta_2() { 109 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 110 | setup(&mut wave, 2, 16000, 100); 111 | for i in 0..500 { 112 | wave.clock_delta(25); 113 | assert_eq!( 114 | wave.output(None), 115 | data::wave_delta_output::RESID_WAVE2_OUTPUT[i] 116 | ); 117 | } 118 | } 119 | 120 | #[test] 121 | fn waveform_delta_3() { 122 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 123 | setup(&mut wave, 3, 32000, 100); 124 | for i in 0..500 { 125 | wave.clock_delta(25); 126 | assert_eq!( 127 | wave.output(None), 128 | data::wave_delta_output::RESID_WAVE3_OUTPUT[i] 129 | ); 130 | } 131 | } 132 | 133 | #[test] 134 | fn waveform_delta_4() { 135 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 136 | setup(&mut wave, 4, 16000, 1000); 137 | for i in 0..1500 { 138 | wave.clock_delta(25); 139 | assert_eq!( 140 | wave.output(None), 141 | data::wave_delta_output::RESID_WAVE4_OUTPUT[i] 142 | ); 143 | } 144 | } 145 | 146 | #[test] 147 | fn waveform_delta_5() { 148 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 149 | setup(&mut wave, 5, 16000, 1000); 150 | for i in 0..1500 { 151 | wave.clock_delta(25); 152 | assert_eq!( 153 | wave.output(None), 154 | data::wave_delta_output::RESID_WAVE5_OUTPUT[i] 155 | ); 156 | } 157 | } 158 | 159 | #[test] 160 | fn waveform_delta_6() { 161 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 162 | setup(&mut wave, 6, 16000, 1000); 163 | for i in 0..1500 { 164 | wave.clock_delta(25); 165 | assert_eq!( 166 | wave.output(None), 167 | data::wave_delta_output::RESID_WAVE6_OUTPUT[i] 168 | ); 169 | } 170 | } 171 | 172 | #[test] 173 | fn waveform_delta_7() { 174 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 175 | setup(&mut wave, 7, 16000, 1000); 176 | for i in 0..1500 { 177 | wave.clock_delta(25); 178 | assert_eq!( 179 | wave.output(None), 180 | data::wave_delta_output::RESID_WAVE7_OUTPUT[i] 181 | ); 182 | } 183 | } 184 | 185 | #[test] 186 | fn waveform_delta_8() { 187 | let mut wave = WaveformGenerator::new(ChipModel::Mos6581); 188 | setup(&mut wave, 8, 16000, 1000); 189 | for i in 0..1500 { 190 | wave.clock_delta(25); 191 | assert_eq!( 192 | wave.output(None), 193 | data::wave_delta_output::RESID_WAVE8_OUTPUT[i] 194 | ); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/math.rs: -------------------------------------------------------------------------------- 1 | /* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */ 2 | /* 3 | * ==================================================== 4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5 | * 6 | * Developed at SunSoft, a Sun Microsystems, Inc. business. 7 | * Permission to use, copy, modify, and distribute this 8 | * software is freely granted, provided that this notice 9 | * is preserved. 10 | * ==================================================== 11 | */ 12 | /* sqrt(x) 13 | * Return correctly rounded sqrt. 14 | * ------------------------------------------ 15 | * | Use the hardware sqrt if you have one | 16 | * ------------------------------------------ 17 | * Method: 18 | * Bit by bit method using integer arithmetic. (Slow, but portable) 19 | * 1. Normalization 20 | * Scale x to y in [1,4) with even powers of 2: 21 | * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then 22 | * sqrt(x) = 2^k * sqrt(y) 23 | * 2. Bit by bit computation 24 | * Let q = sqrt(y) truncated to i bit after binary point (q = 1), 25 | * i 0 26 | * i+1 2 27 | * s = 2*q , and y = 2 * ( y - q ). (1) 28 | * i i i i 29 | * 30 | * To compute q from q , one checks whether 31 | * i+1 i 32 | * 33 | * -(i+1) 2 34 | * (q + 2 ) <= y. (2) 35 | * i 36 | * -(i+1) 37 | * If (2) is false, then q = q ; otherwise q = q + 2 . 38 | * i+1 i i+1 i 39 | * 40 | * With some algebric manipulation, it is not difficult to see 41 | * that (2) is equivalent to 42 | * -(i+1) 43 | * s + 2 <= y (3) 44 | * i i 45 | * 46 | * The advantage of (3) is that s and y can be computed by 47 | * i i 48 | * the following recurrence formula: 49 | * if (3) is false 50 | * 51 | * s = s , y = y ; (4) 52 | * i+1 i i+1 i 53 | * 54 | * otherwise, 55 | * -i -(i+1) 56 | * s = s + 2 , y = y - s - 2 (5) 57 | * i+1 i i+1 i i 58 | * 59 | * One may easily use induction to prove (4) and (5). 60 | * Note. Since the left hand side of (3) contain only i+2 bits, 61 | * it does not necessary to do a full (53-bit) comparison 62 | * in (3). 63 | * 3. Final rounding 64 | * After generating the 53 bits result, we compute one more bit. 65 | * Together with the remainder, we can decide whether the 66 | * result is exact, bigger than 1/2ulp, or less than 1/2ulp 67 | * (it will never equal to 1/2ulp). 68 | * The rounding mode can be detected by checking whether 69 | * huge + tiny is equal to huge, and whether huge - tiny is 70 | * equal to huge for some floating point number "huge" and "tiny". 71 | * 72 | * Special cases: 73 | * sqrt(+-0) = +-0 ... exact 74 | * sqrt(inf) = inf 75 | * sqrt(-ve) = NaN ... with invalid signal 76 | * sqrt(NaN) = NaN ... with invalid signal for signaling NaN 77 | */ 78 | 79 | use core::f64; 80 | 81 | const TINY: f64 = 1.0e-300; 82 | 83 | #[inline] 84 | pub fn sqrt(x: f64) -> f64 { 85 | let mut z: f64; 86 | let sign: u32 = 0x80000000; 87 | let mut ix0: i32; 88 | let mut s0: i32; 89 | let mut q: i32; 90 | let mut m: i32; 91 | let mut t: i32; 92 | let mut i: i32; 93 | let mut r: u32; 94 | let mut t1: u32; 95 | let mut s1: u32; 96 | let mut ix1: u32; 97 | let mut q1: u32; 98 | 99 | ix0 = (x.to_bits() >> 32) as i32; 100 | ix1 = x.to_bits() as u32; 101 | 102 | /* take care of Inf and NaN */ 103 | if (ix0 & 0x7ff00000) == 0x7ff00000 { 104 | return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ 105 | } 106 | /* take care of zero */ 107 | if ix0 <= 0 { 108 | if ((ix0 & !(sign as i32)) | ix1 as i32) == 0 { 109 | return x; /* sqrt(+-0) = +-0 */ 110 | } 111 | if ix0 < 0 { 112 | return (x - x) / (x - x); /* sqrt(-ve) = sNaN */ 113 | } 114 | } 115 | /* normalize x */ 116 | m = ix0 >> 20; 117 | if m == 0 { 118 | /* subnormal x */ 119 | while ix0 == 0 { 120 | m -= 21; 121 | ix0 |= (ix1 >> 11) as i32; 122 | ix1 <<= 21; 123 | } 124 | i = 0; 125 | while (ix0 & 0x00100000) == 0 { 126 | i += 1; 127 | ix0 <<= 1; 128 | } 129 | m -= i - 1; 130 | ix0 |= (ix1 >> (32 - i)) as i32; 131 | ix1 <<= i; 132 | } 133 | m -= 1023; /* unbias exponent */ 134 | ix0 = (ix0 & 0x000fffff) | 0x00100000; 135 | if (m & 1) == 1 { 136 | /* odd m, double x to make it even */ 137 | ix0 += ix0 + ((ix1 & sign) >> 31) as i32; 138 | ix1 = ix1.wrapping_add(ix1); 139 | } 140 | m >>= 1; /* m = [m/2] */ 141 | 142 | /* generate sqrt(x) bit by bit */ 143 | ix0 += ix0 + ((ix1 & sign) >> 31) as i32; 144 | ix1 = ix1.wrapping_add(ix1); 145 | q = 0; /* [q,q1] = sqrt(x) */ 146 | q1 = 0; 147 | s0 = 0; 148 | s1 = 0; 149 | r = 0x00200000; /* r = moving bit from right to left */ 150 | 151 | while r != 0 { 152 | t = s0 + r as i32; 153 | if t <= ix0 { 154 | s0 = t + r as i32; 155 | ix0 -= t; 156 | q += r as i32; 157 | } 158 | ix0 += ix0 + ((ix1 & sign) >> 31) as i32; 159 | ix1 = ix1.wrapping_add(ix1); 160 | r >>= 1; 161 | } 162 | 163 | r = sign; 164 | while r != 0 { 165 | t1 = s1 + r; 166 | t = s0; 167 | if t < ix0 || (t == ix0 && t1 <= ix1) { 168 | s1 = t1.wrapping_add(r); 169 | if (t1 & sign) == sign && (s1 & sign) == 0 { 170 | s0 += 1; 171 | } 172 | ix0 -= t; 173 | if ix1 < t1 { 174 | ix0 -= 1; 175 | } 176 | ix1 = ix1.wrapping_sub(t1); 177 | q1 += r; 178 | } 179 | ix0 += ix0 + ((ix1 & sign) >> 31) as i32; 180 | ix1 = ix1.wrapping_add(ix1); 181 | r >>= 1; 182 | } 183 | 184 | /* use floating add to find out rounding direction */ 185 | if (ix0 as u32 | ix1) != 0 { 186 | z = 1.0 - TINY; /* raise inexact flag */ 187 | if z >= 1.0 { 188 | z = 1.0 + TINY; 189 | if q1 == 0xffffffff { 190 | q1 = 0; 191 | q += 1; 192 | } else if z > 1.0 { 193 | if q1 == 0xfffffffe { 194 | q += 1; 195 | } 196 | q1 += 2; 197 | } else { 198 | q1 += q1 & 1; 199 | } 200 | } 201 | } 202 | ix0 = (q >> 1) + 0x3fe00000; 203 | ix1 = q1 >> 1; 204 | if (q & 1) == 1 { 205 | ix1 |= sign; 206 | } 207 | ix0 += m << 20; 208 | f64::from_bits((ix0 as u64) << 32 | ix1 as u64) 209 | } 210 | -------------------------------------------------------------------------------- /src/synth.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | 8 | use super::external_filter::ExternalFilter; 9 | use super::filter::Filter; 10 | use super::sid::reg; 11 | use super::voice::Voice; 12 | use super::wave::Syncable; 13 | use super::ChipModel; 14 | 15 | const OUTPUT_RANGE: u32 = 1 << 16; 16 | const OUTPUT_HALF: i32 = (OUTPUT_RANGE >> 1) as i32; 17 | const SAMPLES_PER_OUTPUT: u32 = ((4095 * 255) >> 7) * 3 * 15 * 2 / OUTPUT_RANGE; 18 | 19 | #[derive(Clone, Copy)] 20 | pub struct Synth { 21 | pub ext_filter: ExternalFilter, 22 | pub filter: Filter, 23 | pub voices: [Voice; 3], 24 | pub ext_in: i32, 25 | } 26 | 27 | // slice::rotate_left is inefficient for small arrays: 28 | // https://github.com/rust-lang/rust/issues/89714 29 | fn rotate3([a, b, c]: [T; 3], i: usize) -> [T; 3] { 30 | match i { 31 | 0 => [a, b, c], 32 | 1 => [b, c, a], 33 | 2 => [c, a, b], 34 | _ => panic!("index out of bounds"), 35 | } 36 | } 37 | 38 | impl Synth { 39 | pub fn new(chip_model: ChipModel) -> Self { 40 | Synth { 41 | ext_filter: ExternalFilter::new(chip_model), 42 | filter: Filter::new(chip_model), 43 | voices: [Voice::new(chip_model); 3], 44 | ext_in: 0, 45 | } 46 | } 47 | 48 | pub fn syncable_voice(&self, i: usize) -> Syncable<&'_ Voice> { 49 | let [a, b, c] = &self.voices; 50 | let [main, sync_dest, sync_source] = rotate3([a, b, c], i); 51 | Syncable { 52 | main, 53 | sync_dest, 54 | sync_source, 55 | } 56 | } 57 | 58 | pub fn syncable_voice_mut(&mut self, i: usize) -> Syncable<&'_ mut Voice> { 59 | let [a, b, c] = &mut self.voices; 60 | let [main, sync_dest, sync_source] = rotate3([a, b, c], i); 61 | Syncable { 62 | main, 63 | sync_dest, 64 | sync_source, 65 | } 66 | } 67 | 68 | pub fn clock(&mut self) { 69 | // Clock amplitude modulators. 70 | for i in 0..3 { 71 | self.voices[i].envelope.clock(); 72 | } 73 | // Clock oscillators. 74 | for i in 0..3 { 75 | self.voices[i].wave.clock(); 76 | } 77 | // Synchronize oscillators. 78 | for i in 0..3 { 79 | self.syncable_voice_mut(i).wave().synchronize(); 80 | } 81 | // Clock filter. 82 | self.filter.clock( 83 | self.syncable_voice(0).output(), 84 | self.syncable_voice(1).output(), 85 | self.syncable_voice(2).output(), 86 | self.ext_in, 87 | ); 88 | // Clock external filter. 89 | self.ext_filter.clock(self.filter.output()); 90 | } 91 | 92 | pub fn clock_delta(&mut self, delta: u32) { 93 | // Clock amplitude modulators. 94 | for i in 0..3 { 95 | self.voices[i].envelope.clock_delta(delta); 96 | } 97 | let mut delta_osc = delta; 98 | while delta_osc != 0 { 99 | // Find minimum number of cycles to an oscillator accumulator MSB toggle. 100 | // We have to clock on each MSB on / MSB off for hard sync to operate 101 | // correctly. 102 | let mut delta_min = delta_osc; 103 | for i in 0..3 { 104 | let wave = self.syncable_voice(i).wave(); 105 | // It is only necessary to clock on the MSB of an oscillator that is 106 | // a sync source and has freq != 0. 107 | if !(wave.sync_dest.get_sync() && wave.main.get_frequency() != 0) { 108 | continue; 109 | } 110 | let freq = wave.main.get_frequency() as u32; 111 | let acc = wave.main.get_acc(); 112 | // Clock on MSB off if MSB is on, clock on MSB on if MSB is off. 113 | let delta_acc = if acc & 0x0080_0000 != 0 { 114 | 0x0100_0000 - acc 115 | } else { 116 | 0x0080_0000 - acc 117 | }; 118 | let mut delta_next = delta_acc / freq; 119 | if delta_acc % freq != 0 { 120 | delta_next += 1; 121 | } 122 | if delta_next < delta_min { 123 | delta_min = delta_next; 124 | } 125 | } 126 | // Clock oscillators. 127 | for i in 0..3 { 128 | self.voices[i].wave.clock_delta(delta_min); 129 | } 130 | // Synchronize oscillators. 131 | for i in 0..3 { 132 | self.syncable_voice_mut(i).wave().synchronize(); 133 | } 134 | delta_osc -= delta_min; 135 | } 136 | // Clock filter. 137 | self.filter.clock_delta( 138 | delta, 139 | self.syncable_voice(0).output(), 140 | self.syncable_voice(1).output(), 141 | self.syncable_voice(2).output(), 142 | self.ext_in, 143 | ); 144 | // Clock external filter. 145 | self.ext_filter.clock_delta(delta, self.filter.output()); 146 | } 147 | 148 | pub fn output(&self) -> i16 { 149 | // Read sample from audio output. 150 | let sample = self.ext_filter.output() / SAMPLES_PER_OUTPUT as i32; 151 | if sample >= OUTPUT_HALF { 152 | (OUTPUT_HALF - 1) as i16 153 | } else if sample < -OUTPUT_HALF { 154 | (-OUTPUT_HALF) as i16 155 | } else { 156 | sample as i16 157 | } 158 | } 159 | 160 | pub fn reset(&mut self) { 161 | self.ext_filter.reset(); 162 | self.filter.reset(); 163 | for i in 0..3 { 164 | self.voices[i].reset(); 165 | } 166 | self.ext_in = 0; 167 | } 168 | 169 | pub fn read(&self, reg: u8, bus_value: u8) -> u8 { 170 | match reg { 171 | reg::POTX => 0xff, 172 | reg::POTY => 0xff, 173 | reg::OSC3 => self.syncable_voice(2).wave().read_osc(), 174 | reg::ENV3 => self.voices[2].envelope.read_env(), 175 | _ => bus_value, 176 | } 177 | } 178 | 179 | pub fn write(&mut self, reg: u8, value: u8) { 180 | match reg { 181 | reg::FREQLO1 => self.voices[0].wave.set_frequency_lo(value), 182 | reg::FREQHI1 => self.voices[0].wave.set_frequency_hi(value), 183 | reg::PWLO1 => self.voices[0].wave.set_pulse_width_lo(value), 184 | reg::PWHI1 => self.voices[0].wave.set_pulse_width_hi(value), 185 | reg::CR1 => self.voices[0].set_control(value), 186 | reg::AD1 => self.voices[0].envelope.set_attack_decay(value), 187 | reg::SR1 => self.voices[0].envelope.set_sustain_release(value), 188 | reg::FREQLO2 => self.voices[1].wave.set_frequency_lo(value), 189 | reg::FREQHI2 => self.voices[1].wave.set_frequency_hi(value), 190 | reg::PWLO2 => self.voices[1].wave.set_pulse_width_lo(value), 191 | reg::PWHI2 => self.voices[1].wave.set_pulse_width_hi(value), 192 | reg::CR2 => self.voices[1].set_control(value), 193 | reg::AD2 => self.voices[1].envelope.set_attack_decay(value), 194 | reg::SR2 => self.voices[1].envelope.set_sustain_release(value), 195 | reg::FREQLO3 => self.voices[2].wave.set_frequency_lo(value), 196 | reg::FREQHI3 => self.voices[2].wave.set_frequency_hi(value), 197 | reg::PWLO3 => self.voices[2].wave.set_pulse_width_lo(value), 198 | reg::PWHI3 => self.voices[2].wave.set_pulse_width_hi(value), 199 | reg::CR3 => self.voices[2].set_control(value), 200 | reg::AD3 => self.voices[2].envelope.set_attack_decay(value), 201 | reg::SR3 => self.voices[2].envelope.set_sustain_release(value), 202 | reg::FCLO => self.filter.set_fc_lo(value), 203 | reg::FCHI => self.filter.set_fc_hi(value), 204 | reg::RESFILT => self.filter.set_res_filt(value), 205 | reg::MODVOL => self.filter.set_mode_vol(value), 206 | _ => {} 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/spline.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | //! Our objective is to construct a smooth interpolating single-valued function 7 | //! y = f(x). 8 | //! 9 | //! Catmull-Rom splines are widely used for interpolation, however these are 10 | //! parametric curves [x(t) y(t) ...] and can not be used to directly calculate 11 | //! y = f(x). 12 | //! For a discussion of Catmull-Rom splines see Catmull, E., and R. Rom, 13 | //! "A Class of Local Interpolating Splines", Computer Aided Geometric Design. 14 | //! 15 | //! Natural cubic splines are single-valued functions, and have been used in 16 | //! several applications e.g. to specify gamma curves for image display. 17 | //! These splines do not afford local control, and a set of linear equations 18 | //! including all interpolation points must be solved before any point on the 19 | //! curve can be calculated. The lack of local control makes the splines 20 | //! more difficult to handle than e.g. Catmull-Rom splines, and real-time 21 | //! interpolation of a stream of data points is not possible. 22 | //! For a discussion of natural cubic splines, see e.g. Kreyszig, E., "Advanced 23 | //! Engineering Mathematics". 24 | //! 25 | //! Our approach is to approximate the properties of Catmull-Rom splines for 26 | //! piecewice cubic polynomials f(x) = ax^3 + bx^2 + cx + d as follows: 27 | //! Each curve segment is specified by four interpolation points, 28 | //! p0, p1, p2, p3. 29 | //! The curve between p1 and p2 must interpolate both p1 and p2, and in addition 30 | //! f'(p1.x) = k1 = (p2.y - p0.y)/(p2.x - p0.x) and 31 | //! f'(p2.x) = k2 = (p3.y - p1.y)/(p3.x - p1.x). 32 | //! 33 | //! The constraints are expressed by the following system of linear equations 34 | //! ``` ignore, 35 | //! [ 1 xi xi^2 xi^3 ] [ d ] [ yi ] 36 | //! [ 1 2*xi 3*xi^2 ] * [ c ] = [ ki ] 37 | //! [ 1 xj xj^2 xj^3 ] [ b ] [ yj ] 38 | //! [ 1 2*xj 3*xj^2 ] [ a ] [ kj ] 39 | //! ``` 40 | //! Solving using Gaussian elimination and back substitution, setting 41 | //! dy = yj - yi, dx = xj - xi, we get 42 | //! ``` ignore, 43 | //! a = ((ki + kj) - 2*dy/dx)/(dx*dx); 44 | //! b = ((kj - ki)/dx - 3*(xi + xj)*a)/2; 45 | //! c = ki - (3*xi*a + 2*b)*xi; 46 | //! d = yi - ((xi*a + b)*xi + c)*xi; 47 | //! ``` 48 | //! Having calculated the coefficients of the cubic polynomial we have the 49 | //! choice of evaluation by brute force 50 | //! ``` ignore, 51 | //! for (x = x1; x <= x2; x += res) { 52 | //! y = ((a*x + b)*x + c)*x + d; 53 | //! plot(x, y); 54 | //! } 55 | //! ``` 56 | //! or by forward differencing 57 | //! ``` ignore, 58 | //! y = ((a*x1 + b)*x1 + c)*x1 + d; 59 | //! dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res; 60 | //! d2y = (6*a*(x1 + res) + 2*b)*res*res; 61 | //! d3y = 6*a*res*res*res; 62 | //! 63 | //! for (x = x1; x <= x2; x += res) { 64 | //! plot(x, y); 65 | //! y += dy; dy += d2y; d2y += d3y; 66 | //! } 67 | //! ``` 68 | //! See Foley, Van Dam, Feiner, Hughes, "Computer Graphics, Principles and 69 | //! Practice" for a discussion of forward differencing. 70 | //! 71 | //! If we have a set of interpolation points p0, ..., pn, we may specify 72 | //! curve segments between p0 and p1, and between pn-1 and pn by using the 73 | //! following constraints: 74 | //! f''(p0.x) = 0 and 75 | //! f''(pn.x) = 0. 76 | //! 77 | //! Substituting the results for a and b in 78 | //! 79 | //! 2*b + 6*a*xi = 0 80 | //! 81 | //! we get 82 | //! 83 | //! ki = (3*dy/dx - kj)/2; 84 | //! 85 | //! or by substituting the results for a and b in 86 | //! 87 | //! 2*b + 6*a*xj = 0 88 | //! 89 | //! we get 90 | //! 91 | //! kj = (3*dy/dx - ki)/2; 92 | //! 93 | //! Finally, if we have only two interpolation points, the cubic polynomial 94 | //! will degenerate to a straight line if we set 95 | //! 96 | //! ki = kj = dy/dx; 97 | //! 98 | 99 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp))] 100 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] 101 | 102 | #[derive(Clone, Copy, PartialEq)] 103 | pub struct Point { 104 | pub x: f64, 105 | pub y: f64, 106 | } 107 | 108 | impl From<(i32, i32)> for Point { 109 | fn from((x, y): (i32, i32)) -> Point { 110 | Point { 111 | x: x as f64, 112 | y: y as f64, 113 | } 114 | } 115 | } 116 | 117 | pub struct PointPlotter<'a> { 118 | output: &'a mut [i32], 119 | } 120 | 121 | impl<'a> PointPlotter<'a> { 122 | pub fn new(output: &'a mut [i32]) -> Self { 123 | PointPlotter { output } 124 | } 125 | 126 | pub fn plot(&mut self, x: f64, y: f64) { 127 | let value = if y > 0.0 { y as i32 } else { 0 }; 128 | self.output[x as usize] = value; 129 | } 130 | } 131 | 132 | /// Calculation of coefficients. 133 | fn cubic_coefficients( 134 | x1: f64, 135 | y1: f64, 136 | x2: f64, 137 | y2: f64, 138 | k1: f64, 139 | k2: f64, 140 | ) -> (f64, f64, f64, f64) { 141 | let dx = x2 - x1; 142 | let dy = y2 - y1; 143 | let a = ((k1 + k2) - 2.0 * dy / dx) / (dx * dx); 144 | let b = ((k2 - k1) / dx - 3.0 * (x1 + x2) * a) / 2.0; 145 | let c = k1 - (3.0 * x1 * a + 2.0 * b) * x1; 146 | let d = y1 - ((x1 * a + b) * x1 + c) * x1; 147 | (a, b, c, d) 148 | } 149 | 150 | /// Evaluation of cubic polynomial by brute force. 151 | #[allow(dead_code)] 152 | fn interpolate_brute_force( 153 | x1: f64, 154 | y1: f64, 155 | x2: f64, 156 | y2: f64, 157 | k1: f64, 158 | k2: f64, 159 | plotter: &mut PointPlotter, 160 | res: f64, 161 | ) { 162 | let (a, b, c, d) = cubic_coefficients(x1, y1, x2, y2, k1, k2); 163 | // Calculate each point. 164 | let mut xi = x1; 165 | while xi <= x2 { 166 | let yi = ((a * xi + b) * xi + c) * xi + d; 167 | plotter.plot(xi, yi); 168 | xi += res; 169 | } 170 | } 171 | 172 | /// Evaluation of cubic polynomial by forward differencing. 173 | fn interpolate_forward_difference( 174 | x1: f64, 175 | y1: f64, 176 | x2: f64, 177 | y2: f64, 178 | k1: f64, 179 | k2: f64, 180 | plotter: &mut PointPlotter, 181 | res: f64, 182 | ) { 183 | let (a, b, c, d) = cubic_coefficients(x1, y1, x2, y2, k1, k2); 184 | let mut yi = ((a * x1 + b) * x1 + c) * x1 + d; 185 | let mut dy = (3.0 * a * (x1 + res) + 2.0 * b) * x1 * res + ((a * res + b) * res + c) * res; 186 | let mut d2y = (6.0 * a * (x1 + res) + 2.0 * b) * res * res; 187 | let d3y = 6.0 * a * res * res * res; 188 | // Calculate each point. 189 | let mut xi = x1; 190 | while xi <= x2 { 191 | plotter.plot(xi, yi); 192 | yi += dy; 193 | dy += d2y; 194 | d2y += d3y; 195 | xi += res; 196 | } 197 | } 198 | 199 | /// Evaluation of complete interpolating function. 200 | /// Note that since each curve segment is controlled by four points, the 201 | /// end points will not be interpolated. If extra control points are not 202 | /// desirable, the end points can simply be repeated to ensure interpolation. 203 | /// Note also that points of non-differentiability and discontinuity can be 204 | /// introduced by repeating points. 205 | pub fn interpolate + Copy>(points: &[P], plotter: &mut PointPlotter, res: f64) { 206 | let last_index = points.len() - 4; 207 | let mut i = 0; 208 | while i <= last_index { 209 | let p0 = points[i].into(); 210 | let p1 = points[i + 1].into(); 211 | let p2 = points[i + 2].into(); 212 | let p3 = points[i + 3].into(); 213 | // p1 and p2 equal; single point. 214 | if p1.x != p2.x { 215 | let k1; 216 | let k2; 217 | if p0.x == p1.x && p2.x == p3.x { 218 | // Both end points repeated; straight line. 219 | k1 = (p2.y - p1.y) / (p2.x - p1.x); 220 | k2 = k1; 221 | } else if p0.x == p1.x { 222 | // p0 and p1 equal; use f''(x1) = 0. 223 | k2 = (p3.y - p1.y) / (p3.x - p1.x); 224 | k1 = (3.0 * (p2.y - p1.y) / (p2.x - p1.x) - k2) / 2.0; 225 | } else if p2.x == p3.x { 226 | // p2 and p3 equal; use f''(x2) = 0. 227 | k1 = (p2.y - p0.y) / (p2.x - p0.x); 228 | k2 = (3.0 * (p2.y - p1.y) / (p2.x - p1.x) - k1) / 2.0; 229 | } else { 230 | // Normal curve. 231 | k1 = (p2.y - p0.y) / (p2.x - p0.x); 232 | k2 = (p3.y - p1.y) / (p3.x - p1.x); 233 | } 234 | interpolate_forward_difference(p1.x, p1.y, p2.x, p2.y, k1, k2, plotter, res); 235 | } 236 | i += 1; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/sid.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | use super::envelope::State as EnvState; 7 | use super::sampler::{Sampler, SamplingMethod}; 8 | use super::synth::Synth; 9 | use super::ChipModel; 10 | 11 | pub mod reg { 12 | pub const FREQLO1: u8 = 0x00; 13 | pub const FREQHI1: u8 = 0x01; 14 | pub const PWLO1: u8 = 0x02; 15 | pub const PWHI1: u8 = 0x03; 16 | pub const CR1: u8 = 0x04; 17 | pub const AD1: u8 = 0x05; 18 | pub const SR1: u8 = 0x06; 19 | pub const FREQLO2: u8 = 0x07; 20 | pub const FREQHI2: u8 = 0x08; 21 | pub const PWLO2: u8 = 0x09; 22 | pub const PWHI2: u8 = 0x0a; 23 | pub const CR2: u8 = 0x0b; 24 | pub const AD2: u8 = 0x0c; 25 | pub const SR2: u8 = 0x0d; 26 | pub const FREQLO3: u8 = 0x0e; 27 | pub const FREQHI3: u8 = 0x0f; 28 | pub const PWLO3: u8 = 0x10; 29 | pub const PWHI3: u8 = 0x11; 30 | pub const CR3: u8 = 0x12; 31 | pub const AD3: u8 = 0x13; 32 | pub const SR3: u8 = 0x14; 33 | pub const FCLO: u8 = 0x15; 34 | pub const FCHI: u8 = 0x16; 35 | pub const RESFILT: u8 = 0x17; 36 | pub const MODVOL: u8 = 0x18; 37 | pub const POTX: u8 = 0x19; 38 | pub const POTY: u8 = 0x1a; 39 | pub const OSC3: u8 = 0x1b; 40 | pub const ENV3: u8 = 0x1c; 41 | } 42 | 43 | #[derive(Debug)] 44 | pub struct State { 45 | // Sid 46 | pub sid_register: [u8; 32], 47 | pub bus_value: u8, 48 | pub bus_value_ttl: u32, 49 | pub ext_in: i32, 50 | // Wave 51 | pub accumulator: [u32; 3], 52 | pub shift_register: [u32; 3], 53 | // Envelope 54 | pub envelope_state: [u8; 3], 55 | pub envelope_counter: [u8; 3], 56 | pub exponential_counter: [u8; 3], 57 | pub exponential_counter_period: [u8; 3], 58 | pub hold_zero: [u8; 3], 59 | pub rate_counter: [u16; 3], 60 | pub rate_counter_period: [u16; 3], 61 | } 62 | 63 | #[derive(Clone)] 64 | pub struct Sid { 65 | // Functional Units 66 | sampler: Sampler, 67 | // Runtime State 68 | bus_value: u8, 69 | bus_value_ttl: u32, 70 | } 71 | 72 | impl Sid { 73 | pub fn new(chip_model: ChipModel) -> Self { 74 | let synth = Synth::new(chip_model); 75 | let mut sid = Sid { 76 | sampler: Sampler::new(synth), 77 | bus_value: 0, 78 | bus_value_ttl: 0, 79 | }; 80 | sid.set_sampling_parameters(SamplingMethod::Fast, 985_248, 44100); 81 | sid 82 | } 83 | 84 | pub fn set_sampling_parameters( 85 | &mut self, 86 | method: SamplingMethod, 87 | clock_freq: u32, 88 | sample_freq: u32, 89 | ) { 90 | self.sampler.set_parameters(method, clock_freq, sample_freq); 91 | } 92 | 93 | pub fn clock(&mut self) { 94 | // Age bus value. 95 | if self.bus_value_ttl > 0 { 96 | self.bus_value_ttl -= 1; 97 | if self.bus_value_ttl == 0 { 98 | self.bus_value = 0; 99 | } 100 | } 101 | // Clock synthesizer. 102 | self.sampler.synth.clock(); 103 | } 104 | 105 | pub fn clock_delta(&mut self, delta: u32) { 106 | // Age bus value. 107 | if self.bus_value_ttl >= delta { 108 | self.bus_value_ttl -= delta; 109 | } else { 110 | self.bus_value_ttl = 0; 111 | } 112 | if self.bus_value_ttl == 0 { 113 | self.bus_value = 0; 114 | } 115 | // Clock synthesizer. 116 | self.sampler.synth.clock_delta(delta); 117 | } 118 | 119 | pub fn enable_external_filter(&mut self, enabled: bool) { 120 | self.sampler.synth.ext_filter.set_enabled(enabled); 121 | } 122 | 123 | pub fn enable_filter(&mut self, enabled: bool) { 124 | self.sampler.synth.filter.set_enabled(enabled); 125 | } 126 | 127 | pub fn input(&mut self, sample: i32) { 128 | // Voice outputs are 20 bits. Scale up to match three voices in order 129 | // to facilitate simulation of the MOS8580 "digi boost" hardware hack. 130 | self.sampler.synth.ext_in = (sample << 4) * 3; 131 | } 132 | 133 | pub fn output(&self) -> i16 { 134 | self.sampler.synth.output() 135 | } 136 | 137 | pub fn reset(&mut self) { 138 | self.sampler.reset(); 139 | self.bus_value = 0; 140 | self.bus_value_ttl = 0; 141 | } 142 | 143 | /// SID clocking with audio sampling. 144 | /// Fixpoint arithmetics is used. 145 | /// 146 | /// The example below shows how to clock the SID a specified amount of cycles 147 | /// while producing audio output: 148 | /// ``` ignore, 149 | /// let mut buffer = [0i16; 8192]; 150 | /// while delta > 0 { 151 | /// let (samples, next_delta) = self.resid.sample(delta, &mut buffer[..], 1); 152 | /// let mut output = self.sound_buffer.lock().unwrap(); 153 | /// for i in 0..samples { 154 | /// output.write(buffer[i]); 155 | /// } 156 | /// delta = next_delta; 157 | /// } 158 | /// ``` 159 | pub fn sample(&mut self, delta: u32, buffer: &mut [i16], interleave: usize) -> (usize, u32) { 160 | self.sampler.clock(delta, buffer, interleave) 161 | } 162 | 163 | // -- Device I/O 164 | 165 | pub fn read(&self, reg: u8) -> u8 { 166 | self.sampler.synth.read(reg, self.bus_value) 167 | } 168 | 169 | pub fn write(&mut self, reg: u8, value: u8) { 170 | self.bus_value = value; 171 | self.bus_value_ttl = 0x2000; 172 | self.sampler.synth.write(reg, value); 173 | } 174 | 175 | // -- State 176 | 177 | pub fn read_state(&self) -> State { 178 | let mut state = State { 179 | sid_register: [0; 32], 180 | bus_value: 0, 181 | bus_value_ttl: 0, 182 | ext_in: 0, 183 | accumulator: [0; 3], 184 | shift_register: [0; 3], 185 | envelope_state: [0; 3], 186 | envelope_counter: [0; 3], 187 | exponential_counter: [0; 3], 188 | exponential_counter_period: [0; 3], 189 | hold_zero: [0; 3], 190 | rate_counter: [0; 3], 191 | rate_counter_period: [0; 3], 192 | }; 193 | for i in 0..3 { 194 | let j = i * 7; 195 | let wave = &self.sampler.synth.voices[i].wave; 196 | let envelope = &self.sampler.synth.voices[i].envelope; 197 | state.sid_register[j] = wave.get_frequency_lo(); 198 | state.sid_register[j + 1] = wave.get_frequency_hi(); 199 | state.sid_register[j + 2] = wave.get_pulse_width_lo(); 200 | state.sid_register[j + 3] = wave.get_pulse_width_hi(); 201 | state.sid_register[j + 4] = wave.get_control() | envelope.get_control(); 202 | state.sid_register[j + 5] = envelope.get_attack_decay(); 203 | state.sid_register[j + 6] = envelope.get_sustain_release(); 204 | } 205 | let filter = &self.sampler.synth.filter; 206 | state.sid_register[0x15] = filter.get_fc_lo(); 207 | state.sid_register[0x16] = filter.get_fc_hi(); 208 | state.sid_register[0x17] = filter.get_res_filt(); 209 | state.sid_register[0x18] = filter.get_mode_vol(); 210 | for i in 0x19..0x1d { 211 | state.sid_register[i] = self.read(i as u8); 212 | } 213 | for i in 0x1d..0x20 { 214 | state.sid_register[i] = 0; 215 | } 216 | state.bus_value = self.bus_value; 217 | state.bus_value_ttl = self.bus_value_ttl; 218 | state.ext_in = self.sampler.synth.ext_in; 219 | for i in 0..3 { 220 | let wave = &self.sampler.synth.voices[i].wave; 221 | let envelope = &self.sampler.synth.voices[i].envelope; 222 | state.accumulator[i] = wave.get_acc(); 223 | state.shift_register[i] = wave.get_shift(); 224 | state.envelope_state[i] = envelope.state as u8; 225 | state.envelope_counter[i] = envelope.envelope_counter; 226 | state.exponential_counter[i] = envelope.exponential_counter; 227 | state.exponential_counter_period[i] = envelope.exponential_counter_period; 228 | state.hold_zero[i] = if envelope.hold_zero { 1 } else { 0 }; 229 | state.rate_counter[i] = envelope.rate_counter; 230 | state.rate_counter_period[i] = envelope.rate_counter_period; 231 | } 232 | state 233 | } 234 | 235 | pub fn write_state(&mut self, state: &State) { 236 | for i in 0..0x19 { 237 | self.write(i, state.sid_register[i as usize]); 238 | } 239 | self.bus_value = state.bus_value; 240 | self.bus_value_ttl = state.bus_value_ttl; 241 | self.sampler.synth.ext_in = state.ext_in; 242 | for i in 0..3 { 243 | let envelope = &mut self.sampler.synth.voices[i].envelope; 244 | self.sampler.synth.voices[i].wave.acc = state.accumulator[i]; 245 | self.sampler.synth.voices[i].wave.shift = state.shift_register[i]; 246 | envelope.state = match state.envelope_state[i] { 247 | 0 => EnvState::Attack, 248 | 1 => EnvState::DecaySustain, 249 | 2 => EnvState::Release, 250 | _ => panic!("invalid envelope state"), 251 | }; 252 | envelope.envelope_counter = state.envelope_counter[i]; 253 | envelope.exponential_counter = state.exponential_counter[i]; 254 | envelope.exponential_counter_period = state.exponential_counter_period[i]; 255 | envelope.hold_zero = state.hold_zero[i] != 0; 256 | envelope.rate_counter = state.rate_counter[i]; 257 | envelope.rate_counter_period = state.rate_counter_period[i]; 258 | } 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/data/spline6581_f0.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | pub static SPLINE6581_F0: [i16; 2048] = [ 3 | 220, 220, 220, 220, 220, 220, 220, 220, 4 | 220, 220, 220, 220, 220, 220, 220, 220, 5 | 220, 221, 221, 221, 221, 221, 221, 221, 6 | 221, 221, 221, 221, 221, 221, 221, 221, 7 | 221, 221, 222, 222, 222, 222, 222, 222, 8 | 222, 222, 222, 222, 222, 222, 222, 222, 9 | 222, 223, 223, 223, 223, 223, 223, 223, 10 | 223, 223, 223, 223, 223, 223, 223, 223, 11 | 224, 224, 224, 224, 224, 224, 224, 224, 12 | 224, 224, 224, 224, 224, 225, 225, 225, 13 | 225, 225, 225, 225, 225, 225, 225, 225, 14 | 225, 226, 226, 226, 226, 226, 226, 226, 15 | 226, 226, 226, 226, 227, 227, 227, 227, 16 | 227, 227, 227, 227, 227, 227, 228, 228, 17 | 228, 228, 228, 228, 228, 228, 228, 228, 18 | 229, 229, 229, 229, 229, 229, 229, 229, 19 | 230, 230, 230, 230, 230, 230, 230, 230, 20 | 230, 231, 231, 231, 231, 231, 231, 231, 21 | 231, 231, 232, 232, 232, 232, 232, 232, 22 | 232, 232, 232, 233, 233, 233, 233, 233, 23 | 233, 233, 233, 233, 234, 234, 234, 234, 24 | 234, 234, 234, 234, 234, 235, 235, 235, 25 | 235, 235, 235, 235, 235, 236, 236, 236, 26 | 236, 236, 236, 236, 236, 237, 237, 237, 27 | 237, 237, 237, 237, 238, 238, 238, 238, 28 | 238, 238, 238, 239, 239, 239, 239, 239, 29 | 239, 240, 240, 240, 240, 240, 240, 241, 30 | 241, 241, 241, 241, 241, 242, 242, 242, 31 | 242, 242, 243, 243, 243, 243, 243, 244, 32 | 244, 244, 244, 244, 245, 245, 245, 245, 33 | 245, 246, 246, 246, 246, 247, 247, 247, 34 | 247, 248, 248, 248, 248, 249, 249, 249, 35 | 250, 250, 250, 250, 251, 251, 251, 251, 36 | 252, 252, 252, 252, 253, 253, 253, 254, 37 | 254, 254, 254, 255, 255, 255, 255, 256, 38 | 256, 256, 257, 257, 257, 257, 258, 258, 39 | 258, 259, 259, 259, 259, 260, 260, 260, 40 | 261, 261, 261, 261, 262, 262, 262, 263, 41 | 263, 263, 264, 264, 264, 265, 265, 265, 42 | 266, 266, 266, 267, 267, 267, 268, 268, 43 | 268, 269, 269, 269, 270, 270, 270, 271, 44 | 271, 272, 272, 272, 273, 273, 273, 274, 45 | 274, 275, 275, 276, 276, 276, 277, 277, 46 | 278, 278, 279, 279, 279, 280, 280, 281, 47 | 281, 282, 282, 283, 283, 284, 284, 285, 48 | 285, 286, 286, 287, 287, 288, 289, 289, 49 | 290, 290, 291, 291, 292, 293, 293, 294, 50 | 294, 295, 296, 296, 297, 298, 298, 299, 51 | 300, 300, 301, 301, 302, 303, 303, 304, 52 | 305, 305, 306, 306, 307, 308, 308, 309, 53 | 310, 310, 311, 311, 312, 312, 313, 314, 54 | 314, 315, 315, 316, 317, 317, 318, 318, 55 | 319, 320, 320, 321, 321, 322, 323, 323, 56 | 324, 324, 325, 326, 326, 327, 328, 328, 57 | 329, 329, 330, 331, 331, 332, 333, 334, 58 | 334, 335, 336, 336, 337, 338, 339, 339, 59 | 340, 341, 342, 342, 343, 344, 345, 346, 60 | 347, 347, 348, 349, 350, 351, 352, 353, 61 | 354, 355, 356, 357, 358, 359, 360, 361, 62 | 362, 363, 364, 365, 366, 367, 369, 370, 63 | 371, 372, 373, 375, 376, 377, 378, 380, 64 | 381, 383, 384, 385, 387, 388, 390, 391, 65 | 393, 394, 396, 397, 399, 400, 402, 404, 66 | 405, 407, 409, 410, 412, 414, 416, 418, 67 | 420, 421, 423, 425, 427, 429, 431, 433, 68 | 435, 436, 438, 440, 442, 444, 446, 448, 69 | 450, 452, 454, 456, 458, 460, 462, 464, 70 | 466, 468, 470, 472, 474, 476, 478, 480, 71 | 482, 484, 486, 488, 490, 492, 495, 497, 72 | 499, 501, 503, 505, 508, 510, 512, 514, 73 | 517, 519, 521, 524, 526, 528, 531, 533, 74 | 536, 538, 541, 543, 546, 548, 551, 553, 75 | 556, 558, 561, 564, 566, 569, 572, 574, 76 | 577, 580, 583, 586, 589, 591, 594, 597, 77 | 600, 603, 606, 609, 612, 615, 619, 622, 78 | 625, 628, 631, 635, 638, 641, 645, 648, 79 | 652, 655, 658, 662, 666, 669, 673, 676, 80 | 680, 684, 688, 691, 695, 699, 703, 707, 81 | 711, 715, 719, 723, 727, 731, 735, 740, 82 | 744, 748, 753, 757, 761, 766, 770, 775, 83 | 780, 784, 789, 793, 798, 803, 808, 813, 84 | 817, 822, 827, 832, 837, 842, 847, 852, 85 | 857, 862, 868, 873, 878, 883, 889, 894, 86 | 899, 905, 910, 915, 921, 926, 932, 938, 87 | 943, 949, 954, 960, 966, 971, 977, 983, 88 | 989, 995, 1001, 1006, 1012, 1018, 1024, 1030, 89 | 1036, 1042, 1048, 1055, 1061, 1067, 1073, 1079, 90 | 1086, 1092, 1098, 1105, 1111, 1117, 1124, 1130, 91 | 1137, 1143, 1150, 1156, 1163, 1169, 1176, 1183, 92 | 1189, 1196, 1203, 1209, 1216, 1223, 1230, 1237, 93 | 1243, 1250, 1257, 1264, 1271, 1278, 1285, 1292, 94 | 1299, 1306, 1313, 1321, 1328, 1335, 1342, 1349, 95 | 1357, 1364, 1371, 1378, 1386, 1393, 1400, 1408, 96 | 1415, 1423, 1430, 1438, 1445, 1453, 1460, 1468, 97 | 1475, 1483, 1491, 1498, 1506, 1514, 1521, 1529, 98 | 1537, 1545, 1552, 1560, 1568, 1576, 1584, 1592, 99 | 1600, 1607, 1616, 1624, 1632, 1641, 1649, 1658, 100 | 1667, 1676, 1685, 1695, 1704, 1713, 1723, 1733, 101 | 1743, 1753, 1763, 1773, 1783, 1793, 1804, 1814, 102 | 1825, 1836, 1846, 1857, 1868, 1879, 1890, 1902, 103 | 1913, 1924, 1936, 1947, 1959, 1970, 1982, 1994, 104 | 2005, 2017, 2029, 2041, 2053, 2065, 2077, 2089, 105 | 2101, 2114, 2126, 2138, 2150, 2163, 2175, 2187, 106 | 2200, 2212, 2225, 2237, 2250, 2262, 2275, 2287, 107 | 2300, 2312, 2325, 2337, 2350, 2363, 2375, 2388, 108 | 2401, 2414, 2427, 2440, 2453, 2466, 2479, 2492, 109 | 2506, 2519, 2532, 2546, 2559, 2573, 2586, 2600, 110 | 2614, 2627, 2641, 2655, 2669, 2683, 2696, 2710, 111 | 2725, 2739, 2753, 2767, 2781, 2795, 2810, 2824, 112 | 2839, 2853, 2868, 2882, 2897, 2911, 2926, 2941, 113 | 2956, 2971, 2986, 3001, 3016, 3031, 3046, 3061, 114 | 3076, 3091, 3107, 3122, 3137, 3153, 3168, 3184, 115 | 3200, 3215, 3231, 3247, 3262, 3278, 3294, 3310, 116 | 3326, 3342, 3358, 3374, 3391, 3407, 3423, 3439, 117 | 3456, 3472, 3489, 3505, 3522, 3538, 3555, 3572, 118 | 3589, 3605, 3622, 3639, 3656, 3673, 3690, 3707, 119 | 3725, 3742, 3759, 3776, 3794, 3811, 3829, 3846, 120 | 3864, 3881, 3899, 3917, 3934, 3952, 3970, 3988, 121 | 4006, 4024, 4042, 4060, 4078, 4096, 4114, 4133, 122 | 4151, 4169, 4188, 4206, 4225, 4243, 4262, 4281, 123 | 4300, 4318, 4338, 4357, 4377, 4397, 4417, 4438, 124 | 4459, 4480, 4501, 4523, 4544, 4566, 4588, 4611, 125 | 4633, 4655, 4678, 4701, 4723, 4746, 4769, 4792, 126 | 4815, 4838, 4861, 4884, 4907, 4931, 4954, 4977, 127 | 5000, 5022, 5045, 5068, 5092, 5115, 5139, 5163, 128 | 5187, 5212, 5237, 5262, 5289, 5315, 5343, 5371, 129 | 5400, 5430, 5464, 5500, 5539, 5578, 5619, 5659, 130 | 5700, 5740, 5782, 5824, 5867, 5911, 5955, 6000, 131 | 4600, 4626, 4652, 4679, 4704, 4729, 4754, 4777, 132 | 4800, 4821, 4843, 4864, 4885, 4906, 4927, 4948, 133 | 4969, 4989, 5010, 5030, 5051, 5071, 5092, 5112, 134 | 5133, 5153, 5174, 5194, 5215, 5236, 5257, 5278, 135 | 5300, 5321, 5343, 5364, 5386, 5408, 5430, 5453, 136 | 5475, 5497, 5519, 5542, 5564, 5587, 5609, 5632, 137 | 5654, 5676, 5699, 5721, 5743, 5765, 5787, 5809, 138 | 5831, 5853, 5874, 5895, 5917, 5938, 5958, 5979, 139 | 6000, 6020, 6040, 6060, 6079, 6099, 6118, 6137, 140 | 6157, 6176, 6194, 6213, 6232, 6250, 6269, 6287, 141 | 6306, 6324, 6342, 6361, 6379, 6397, 6415, 6434, 142 | 6452, 6470, 6488, 6507, 6525, 6544, 6562, 6581, 143 | 6600, 6618, 6637, 6656, 6675, 6694, 6713, 6731, 144 | 6750, 6769, 6788, 6807, 6826, 6845, 6864, 6883, 145 | 6902, 6921, 6940, 6959, 6977, 6996, 7015, 7034, 146 | 7052, 7071, 7089, 7108, 7126, 7145, 7163, 7181, 147 | 7200, 7218, 7236, 7254, 7272, 7290, 7308, 7326, 148 | 7344, 7362, 7380, 7398, 7416, 7434, 7452, 7470, 149 | 7488, 7505, 7523, 7541, 7559, 7577, 7595, 7613, 150 | 7630, 7648, 7666, 7684, 7702, 7719, 7737, 7755, 151 | 7773, 7790, 7808, 7826, 7844, 7861, 7879, 7897, 152 | 7914, 7932, 7950, 7968, 7985, 8003, 8021, 8038, 153 | 8056, 8074, 8092, 8109, 8127, 8145, 8162, 8180, 154 | 8198, 8215, 8233, 8251, 8269, 8286, 8304, 8322, 155 | 8340, 8357, 8375, 8393, 8410, 8428, 8446, 8464, 156 | 8482, 8499, 8517, 8535, 8553, 8571, 8588, 8606, 157 | 8624, 8642, 8660, 8678, 8696, 8714, 8731, 8749, 158 | 8767, 8785, 8803, 8821, 8839, 8857, 8875, 8893, 159 | 8911, 8929, 8948, 8966, 8984, 9002, 9020, 9038, 160 | 9056, 9075, 9093, 9111, 9129, 9148, 9166, 9184, 161 | 9203, 9221, 9239, 9258, 9276, 9295, 9313, 9332, 162 | 9350, 9369, 9387, 9406, 9425, 9443, 9462, 9481, 163 | 9500, 9518, 9537, 9556, 9575, 9594, 9612, 9631, 164 | 9650, 9669, 9688, 9707, 9726, 9745, 9764, 9783, 165 | 9802, 9822, 9841, 9860, 9879, 9898, 9917, 9937, 166 | 9956, 9975, 9994, 10014, 10033, 10052, 10072, 10091, 167 | 10110, 10130, 10149, 10169, 10188, 10208, 10227, 10246, 168 | 10266, 10285, 10305, 10325, 10344, 10364, 10383, 10403, 169 | 10422, 10442, 10462, 10481, 10501, 10520, 10540, 10560, 170 | 10579, 10599, 10619, 10638, 10658, 10678, 10698, 10717, 171 | 10737, 10757, 10776, 10796, 10816, 10836, 10855, 10875, 172 | 10895, 10915, 10935, 10954, 10974, 10994, 11014, 11033, 173 | 11053, 11073, 11093, 11113, 11132, 11152, 11172, 11192, 174 | 11212, 11231, 11251, 11271, 11291, 11310, 11330, 11350, 175 | 11370, 11390, 11409, 11429, 11449, 11469, 11488, 11508, 176 | 11528, 11548, 11567, 11587, 11607, 11627, 11646, 11666, 177 | 11686, 11705, 11725, 11745, 11764, 11784, 11804, 11823, 178 | 11843, 11862, 11882, 11902, 11921, 11941, 11960, 11980, 179 | 12000, 12019, 12039, 12058, 12078, 12098, 12118, 12138, 180 | 12158, 12178, 12198, 12218, 12238, 12258, 12278, 12299, 181 | 12319, 12339, 12360, 12380, 12400, 12421, 12441, 12462, 182 | 12483, 12503, 12524, 12544, 12565, 12586, 12606, 12627, 183 | 12648, 12669, 12689, 12710, 12731, 12752, 12773, 12793, 184 | 12814, 12835, 12856, 12877, 12898, 12918, 12939, 12960, 185 | 12981, 13002, 13023, 13043, 13064, 13085, 13106, 13126, 186 | 13147, 13168, 13188, 13209, 13230, 13250, 13271, 13291, 187 | 13312, 13332, 13353, 13373, 13394, 13414, 13434, 13455, 188 | 13475, 13495, 13515, 13535, 13555, 13575, 13595, 13615, 189 | 13635, 13655, 13675, 13695, 13714, 13734, 13753, 13773, 190 | 13792, 13811, 13831, 13850, 13869, 13888, 13907, 13926, 191 | 13945, 13964, 13982, 14001, 14019, 14038, 14056, 14074, 192 | 14093, 14111, 14129, 14147, 14164, 14182, 14200, 14217, 193 | 14235, 14252, 14269, 14287, 14304, 14321, 14337, 14354, 194 | 14371, 14387, 14404, 14420, 14436, 14452, 14468, 14484, 195 | 14500, 14515, 14531, 14546, 14561, 14576, 14592, 14607, 196 | 14621, 14636, 14651, 14666, 14680, 14695, 14709, 14723, 197 | 14738, 14752, 14766, 14780, 14794, 14807, 14821, 14835, 198 | 14848, 14862, 14875, 14889, 14902, 14915, 14928, 14941, 199 | 14954, 14967, 14980, 14993, 15005, 15018, 15031, 15043, 200 | 15056, 15068, 15080, 15092, 15105, 15117, 15129, 15141, 201 | 15153, 15165, 15177, 15188, 15200, 15212, 15223, 15235, 202 | 15246, 15258, 15269, 15281, 15292, 15303, 15315, 15326, 203 | 15337, 15348, 15359, 15370, 15381, 15392, 15403, 15414, 204 | 15425, 15436, 15446, 15457, 15468, 15478, 15489, 15500, 205 | 15510, 15521, 15531, 15542, 15552, 15563, 15573, 15583, 206 | 15594, 15604, 15615, 15625, 15635, 15645, 15656, 15666, 207 | 15676, 15686, 15696, 15707, 15717, 15727, 15737, 15747, 208 | 15757, 15767, 15777, 15788, 15798, 15808, 15818, 15828, 209 | 15838, 15848, 15858, 15868, 15878, 15888, 15898, 15908, 210 | 15919, 15929, 15939, 15949, 15959, 15969, 15979, 15989, 211 | 16000, 16010, 16020, 16030, 16040, 16050, 16060, 16070, 212 | 16080, 16090, 16100, 16110, 16120, 16130, 16140, 16150, 213 | 16160, 16169, 16179, 16189, 16199, 16209, 16218, 16228, 214 | 16238, 16247, 16257, 16267, 16276, 16286, 16295, 16305, 215 | 16314, 16324, 16333, 16343, 16352, 16362, 16371, 16380, 216 | 16390, 16399, 16408, 16417, 16427, 16436, 16445, 16454, 217 | 16463, 16472, 16481, 16490, 16500, 16509, 16517, 16526, 218 | 16535, 16544, 16553, 16562, 16571, 16580, 16588, 16597, 219 | 16606, 16614, 16623, 16632, 16640, 16649, 16657, 16666, 220 | 16674, 16683, 16691, 16700, 16708, 16716, 16725, 16733, 221 | 16741, 16749, 16758, 16766, 16774, 16782, 16790, 16798, 222 | 16806, 16814, 16822, 16830, 16838, 16846, 16853, 16861, 223 | 16869, 16877, 16884, 16892, 16900, 16907, 16915, 16922, 224 | 16930, 16937, 16945, 16952, 16960, 16967, 16974, 16981, 225 | 16989, 16996, 17003, 17010, 17017, 17024, 17031, 17038, 226 | 17045, 17052, 17059, 17066, 17073, 17079, 17086, 17093, 227 | 17100, 17106, 17113, 17119, 17126, 17132, 17139, 17145, 228 | 17151, 17158, 17164, 17170, 17176, 17182, 17188, 17194, 229 | 17200, 17206, 17212, 17218, 17224, 17230, 17236, 17241, 230 | 17247, 17253, 17258, 17264, 17270, 17275, 17281, 17286, 231 | 17292, 17297, 17302, 17308, 17313, 17318, 17324, 17329, 232 | 17334, 17339, 17344, 17349, 17354, 17359, 17364, 17369, 233 | 17374, 17379, 17384, 17389, 17394, 17398, 17403, 17408, 234 | 17413, 17417, 17422, 17427, 17431, 17436, 17440, 17445, 235 | 17449, 17454, 17458, 17463, 17467, 17471, 17476, 17480, 236 | 17484, 17489, 17493, 17497, 17501, 17506, 17510, 17514, 237 | 17518, 17522, 17526, 17531, 17535, 17539, 17543, 17547, 238 | 17551, 17555, 17559, 17563, 17567, 17570, 17574, 17578, 239 | 17582, 17586, 17590, 17594, 17597, 17601, 17605, 17609, 240 | 17612, 17616, 17620, 17624, 17627, 17631, 17635, 17638, 241 | 17642, 17646, 17649, 17653, 17657, 17660, 17664, 17667, 242 | 17671, 17675, 17678, 17682, 17685, 17689, 17692, 17696, 243 | 17700, 17703, 17707, 17710, 17713, 17717, 17720, 17724, 244 | 17727, 17730, 17733, 17737, 17740, 17743, 17746, 17749, 245 | 17753, 17756, 17759, 17762, 17765, 17768, 17771, 17774, 246 | 17777, 17780, 17783, 17785, 17788, 17791, 17794, 17797, 247 | 17800, 17802, 17805, 17808, 17810, 17813, 17816, 17818, 248 | 17821, 17824, 17826, 17829, 17831, 17834, 17836, 17839, 249 | 17841, 17844, 17846, 17848, 17851, 17853, 17856, 17858, 250 | 17860, 17863, 17865, 17867, 17869, 17872, 17874, 17876, 251 | 17878, 17881, 17883, 17885, 17887, 17889, 17891, 17894, 252 | 17896, 17898, 17900, 17902, 17904, 17906, 17908, 17910, 253 | 17912, 17914, 17916, 17918, 17920, 17922, 17924, 17926, 254 | 17928, 17930, 17932, 17934, 17936, 17938, 17940, 17941, 255 | 17943, 17945, 17947, 17949, 17951, 17953, 17954, 17956, 256 | 17958, 17960, 17962, 17964, 17965, 17967, 17969, 17971, 257 | 17973, 17975, 17976, 17978, 17980, 17982, 17983, 17985, 258 | 17987, 17989, 17991, 17992, 17994, 17996, 17998, 17999 259 | ]; 260 | -------------------------------------------------------------------------------- /tests/data/spline_output.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | pub static RESID_OUTPUT: [i32; 2048] = [ 3 | 220, 220, 220, 220, 220, 220, 220, 220, 4 | 220, 220, 220, 220, 220, 220, 220, 220, 5 | 220, 221, 221, 221, 221, 221, 221, 221, 6 | 221, 221, 221, 221, 221, 221, 221, 221, 7 | 221, 221, 222, 222, 222, 222, 222, 222, 8 | 222, 222, 222, 222, 222, 222, 222, 222, 9 | 222, 223, 223, 223, 223, 223, 223, 223, 10 | 223, 223, 223, 223, 223, 223, 223, 223, 11 | 224, 224, 224, 224, 224, 224, 224, 224, 12 | 224, 224, 224, 224, 224, 225, 225, 225, 13 | 225, 225, 225, 225, 225, 225, 225, 225, 14 | 225, 226, 226, 226, 226, 226, 226, 226, 15 | 226, 226, 226, 226, 227, 227, 227, 227, 16 | 227, 227, 227, 227, 227, 227, 228, 228, 17 | 228, 228, 228, 228, 228, 228, 228, 228, 18 | 229, 229, 229, 229, 229, 229, 229, 229, 19 | 230, 230, 230, 230, 230, 230, 230, 230, 20 | 230, 231, 231, 231, 231, 231, 231, 231, 21 | 231, 231, 232, 232, 232, 232, 232, 232, 22 | 232, 232, 232, 233, 233, 233, 233, 233, 23 | 233, 233, 233, 233, 234, 234, 234, 234, 24 | 234, 234, 234, 234, 234, 235, 235, 235, 25 | 235, 235, 235, 235, 235, 236, 236, 236, 26 | 236, 236, 236, 236, 236, 237, 237, 237, 27 | 237, 237, 237, 237, 238, 238, 238, 238, 28 | 238, 238, 238, 239, 239, 239, 239, 239, 29 | 239, 240, 240, 240, 240, 240, 240, 241, 30 | 241, 241, 241, 241, 241, 242, 242, 242, 31 | 242, 242, 243, 243, 243, 243, 243, 244, 32 | 244, 244, 244, 244, 245, 245, 245, 245, 33 | 245, 246, 246, 246, 246, 247, 247, 247, 34 | 247, 248, 248, 248, 248, 249, 249, 249, 35 | 250, 250, 250, 250, 251, 251, 251, 251, 36 | 252, 252, 252, 252, 253, 253, 253, 254, 37 | 254, 254, 254, 255, 255, 255, 255, 256, 38 | 256, 256, 257, 257, 257, 257, 258, 258, 39 | 258, 259, 259, 259, 259, 260, 260, 260, 40 | 261, 261, 261, 261, 262, 262, 262, 263, 41 | 263, 263, 264, 264, 264, 265, 265, 265, 42 | 266, 266, 266, 267, 267, 267, 268, 268, 43 | 268, 269, 269, 269, 270, 270, 270, 271, 44 | 271, 272, 272, 272, 273, 273, 273, 274, 45 | 274, 275, 275, 276, 276, 276, 277, 277, 46 | 278, 278, 279, 279, 279, 280, 280, 281, 47 | 281, 282, 282, 283, 283, 284, 284, 285, 48 | 285, 286, 286, 287, 287, 288, 289, 289, 49 | 290, 290, 291, 291, 292, 293, 293, 294, 50 | 294, 295, 296, 296, 297, 298, 298, 299, 51 | 300, 300, 301, 301, 302, 303, 303, 304, 52 | 305, 305, 306, 306, 307, 308, 308, 309, 53 | 310, 310, 311, 311, 312, 312, 313, 314, 54 | 314, 315, 315, 316, 317, 317, 318, 318, 55 | 319, 320, 320, 321, 321, 322, 323, 323, 56 | 324, 324, 325, 326, 326, 327, 328, 328, 57 | 329, 329, 330, 331, 331, 332, 333, 334, 58 | 334, 335, 336, 336, 337, 338, 339, 339, 59 | 340, 341, 342, 342, 343, 344, 345, 346, 60 | 347, 347, 348, 349, 350, 351, 352, 353, 61 | 354, 355, 356, 357, 358, 359, 360, 361, 62 | 362, 363, 364, 365, 366, 367, 369, 370, 63 | 371, 372, 373, 375, 376, 377, 378, 380, 64 | 381, 383, 384, 385, 387, 388, 390, 391, 65 | 393, 394, 396, 397, 399, 400, 402, 404, 66 | 405, 407, 409, 410, 412, 414, 416, 418, 67 | 420, 421, 423, 425, 427, 429, 431, 433, 68 | 435, 436, 438, 440, 442, 444, 446, 448, 69 | 450, 452, 454, 456, 458, 460, 462, 464, 70 | 466, 468, 470, 472, 474, 476, 478, 480, 71 | 482, 484, 486, 488, 490, 492, 495, 497, 72 | 499, 501, 503, 505, 508, 510, 512, 514, 73 | 517, 519, 521, 524, 526, 528, 531, 533, 74 | 536, 538, 541, 543, 546, 548, 551, 553, 75 | 556, 558, 561, 564, 566, 569, 572, 574, 76 | 577, 580, 583, 586, 589, 591, 594, 597, 77 | 600, 603, 606, 609, 612, 615, 619, 622, 78 | 625, 628, 631, 635, 638, 641, 645, 648, 79 | 652, 655, 658, 662, 666, 669, 673, 676, 80 | 680, 684, 688, 691, 695, 699, 703, 707, 81 | 711, 715, 719, 723, 727, 731, 735, 740, 82 | 744, 748, 753, 757, 761, 766, 770, 775, 83 | 780, 784, 789, 793, 798, 803, 808, 813, 84 | 817, 822, 827, 832, 837, 842, 847, 852, 85 | 857, 862, 868, 873, 878, 883, 889, 894, 86 | 899, 905, 910, 915, 921, 926, 932, 938, 87 | 943, 949, 954, 960, 966, 971, 977, 983, 88 | 989, 995, 1001, 1006, 1012, 1018, 1024, 1030, 89 | 1036, 1042, 1048, 1055, 1061, 1067, 1073, 1079, 90 | 1086, 1092, 1098, 1105, 1111, 1117, 1124, 1130, 91 | 1137, 1143, 1150, 1156, 1163, 1169, 1176, 1183, 92 | 1189, 1196, 1203, 1209, 1216, 1223, 1230, 1237, 93 | 1243, 1250, 1257, 1264, 1271, 1278, 1285, 1292, 94 | 1299, 1306, 1313, 1321, 1328, 1335, 1342, 1349, 95 | 1357, 1364, 1371, 1378, 1386, 1393, 1400, 1408, 96 | 1415, 1423, 1430, 1438, 1445, 1453, 1460, 1468, 97 | 1475, 1483, 1491, 1498, 1506, 1514, 1521, 1529, 98 | 1537, 1545, 1552, 1560, 1568, 1576, 1584, 1592, 99 | 1600, 1607, 1616, 1624, 1632, 1641, 1649, 1658, 100 | 1667, 1676, 1685, 1695, 1704, 1713, 1723, 1733, 101 | 1743, 1753, 1763, 1773, 1783, 1793, 1804, 1814, 102 | 1825, 1836, 1846, 1857, 1868, 1879, 1890, 1902, 103 | 1913, 1924, 1936, 1947, 1959, 1970, 1982, 1994, 104 | 2005, 2017, 2029, 2041, 2053, 2065, 2077, 2089, 105 | 2101, 2114, 2126, 2138, 2150, 2163, 2175, 2187, 106 | 2200, 2212, 2225, 2237, 2250, 2262, 2275, 2287, 107 | 2300, 2312, 2325, 2337, 2350, 2363, 2375, 2388, 108 | 2401, 2414, 2427, 2440, 2453, 2466, 2479, 2492, 109 | 2506, 2519, 2532, 2546, 2559, 2573, 2586, 2600, 110 | 2614, 2627, 2641, 2655, 2669, 2683, 2696, 2710, 111 | 2725, 2739, 2753, 2767, 2781, 2795, 2810, 2824, 112 | 2839, 2853, 2868, 2882, 2897, 2911, 2926, 2941, 113 | 2956, 2971, 2986, 3001, 3016, 3031, 3046, 3061, 114 | 3076, 3091, 3107, 3122, 3137, 3153, 3168, 3184, 115 | 3200, 3215, 3231, 3247, 3262, 3278, 3294, 3310, 116 | 3326, 3342, 3358, 3374, 3391, 3407, 3423, 3439, 117 | 3456, 3472, 3489, 3505, 3522, 3538, 3555, 3572, 118 | 3589, 3605, 3622, 3639, 3656, 3673, 3690, 3707, 119 | 3725, 3742, 3759, 3776, 3794, 3811, 3829, 3846, 120 | 3864, 3881, 3899, 3917, 3934, 3952, 3970, 3988, 121 | 4006, 4024, 4042, 4060, 4078, 4096, 4114, 4133, 122 | 4151, 4169, 4188, 4206, 4225, 4243, 4262, 4281, 123 | 4300, 4318, 4338, 4357, 4377, 4397, 4417, 4438, 124 | 4459, 4480, 4501, 4523, 4544, 4566, 4588, 4611, 125 | 4633, 4655, 4678, 4701, 4723, 4746, 4769, 4792, 126 | 4815, 4838, 4861, 4884, 4907, 4931, 4954, 4977, 127 | 5000, 5022, 5045, 5068, 5092, 5115, 5139, 5163, 128 | 5187, 5212, 5237, 5262, 5289, 5315, 5343, 5371, 129 | 5400, 5430, 5464, 5500, 5539, 5578, 5619, 5659, 130 | 5700, 5740, 5782, 5824, 5867, 5911, 5955, 6000, 131 | 4600, 4626, 4652, 4679, 4704, 4729, 4754, 4777, 132 | 4800, 4821, 4843, 4864, 4885, 4906, 4927, 4948, 133 | 4969, 4989, 5010, 5030, 5051, 5071, 5092, 5112, 134 | 5133, 5153, 5174, 5194, 5215, 5236, 5257, 5278, 135 | 5300, 5321, 5343, 5364, 5386, 5408, 5430, 5453, 136 | 5475, 5497, 5519, 5542, 5564, 5587, 5609, 5632, 137 | 5654, 5676, 5699, 5721, 5743, 5765, 5787, 5809, 138 | 5831, 5853, 5874, 5895, 5917, 5938, 5958, 5979, 139 | 6000, 6020, 6040, 6060, 6079, 6099, 6118, 6137, 140 | 6157, 6176, 6194, 6213, 6232, 6250, 6269, 6287, 141 | 6306, 6324, 6342, 6361, 6379, 6397, 6415, 6434, 142 | 6452, 6470, 6488, 6507, 6525, 6544, 6562, 6581, 143 | 6600, 6618, 6637, 6656, 6675, 6694, 6713, 6731, 144 | 6750, 6769, 6788, 6807, 6826, 6845, 6864, 6883, 145 | 6902, 6921, 6940, 6959, 6977, 6996, 7015, 7034, 146 | 7052, 7071, 7089, 7108, 7126, 7145, 7163, 7181, 147 | 7200, 7218, 7236, 7254, 7272, 7290, 7308, 7326, 148 | 7344, 7362, 7380, 7398, 7416, 7434, 7452, 7470, 149 | 7488, 7505, 7523, 7541, 7559, 7577, 7595, 7613, 150 | 7630, 7648, 7666, 7684, 7702, 7719, 7737, 7755, 151 | 7773, 7790, 7808, 7826, 7844, 7861, 7879, 7897, 152 | 7914, 7932, 7950, 7968, 7985, 8003, 8021, 8038, 153 | 8056, 8074, 8092, 8109, 8127, 8145, 8162, 8180, 154 | 8198, 8215, 8233, 8251, 8269, 8286, 8304, 8322, 155 | 8340, 8357, 8375, 8393, 8410, 8428, 8446, 8464, 156 | 8482, 8499, 8517, 8535, 8553, 8571, 8588, 8606, 157 | 8624, 8642, 8660, 8678, 8696, 8714, 8731, 8749, 158 | 8767, 8785, 8803, 8821, 8839, 8857, 8875, 8893, 159 | 8911, 8929, 8948, 8966, 8984, 9002, 9020, 9038, 160 | 9056, 9075, 9093, 9111, 9129, 9148, 9166, 9184, 161 | 9203, 9221, 9239, 9258, 9276, 9295, 9313, 9332, 162 | 9350, 9369, 9387, 9406, 9425, 9443, 9462, 9481, 163 | 9500, 9518, 9537, 9556, 9575, 9594, 9612, 9631, 164 | 9650, 9669, 9688, 9707, 9726, 9745, 9764, 9783, 165 | 9802, 9822, 9841, 9860, 9879, 9898, 9917, 9937, 166 | 9956, 9975, 9994, 10014, 10033, 10052, 10072, 10091, 167 | 10110, 10130, 10149, 10169, 10188, 10208, 10227, 10246, 168 | 10266, 10285, 10305, 10325, 10344, 10364, 10383, 10403, 169 | 10422, 10442, 10462, 10481, 10501, 10520, 10540, 10560, 170 | 10579, 10599, 10619, 10638, 10658, 10678, 10698, 10717, 171 | 10737, 10757, 10776, 10796, 10816, 10836, 10855, 10875, 172 | 10895, 10915, 10935, 10954, 10974, 10994, 11014, 11033, 173 | 11053, 11073, 11093, 11113, 11132, 11152, 11172, 11192, 174 | 11212, 11231, 11251, 11271, 11291, 11310, 11330, 11350, 175 | 11370, 11390, 11409, 11429, 11449, 11469, 11488, 11508, 176 | 11528, 11548, 11567, 11587, 11607, 11627, 11646, 11666, 177 | 11686, 11705, 11725, 11745, 11764, 11784, 11804, 11823, 178 | 11843, 11862, 11882, 11902, 11921, 11941, 11960, 11980, 179 | 12000, 12019, 12039, 12058, 12078, 12098, 12118, 12138, 180 | 12158, 12178, 12198, 12218, 12238, 12258, 12278, 12299, 181 | 12319, 12339, 12360, 12380, 12400, 12421, 12441, 12462, 182 | 12483, 12503, 12524, 12544, 12565, 12586, 12606, 12627, 183 | 12648, 12669, 12689, 12710, 12731, 12752, 12773, 12793, 184 | 12814, 12835, 12856, 12877, 12898, 12918, 12939, 12960, 185 | 12981, 13002, 13023, 13043, 13064, 13085, 13106, 13126, 186 | 13147, 13168, 13188, 13209, 13230, 13250, 13271, 13291, 187 | 13312, 13332, 13353, 13373, 13394, 13414, 13434, 13455, 188 | 13475, 13495, 13515, 13535, 13555, 13575, 13595, 13615, 189 | 13635, 13655, 13675, 13695, 13714, 13734, 13753, 13773, 190 | 13792, 13811, 13831, 13850, 13869, 13888, 13907, 13926, 191 | 13945, 13964, 13982, 14001, 14019, 14038, 14056, 14074, 192 | 14093, 14111, 14129, 14147, 14164, 14182, 14200, 14217, 193 | 14235, 14252, 14269, 14287, 14304, 14321, 14337, 14354, 194 | 14371, 14387, 14404, 14420, 14436, 14452, 14468, 14484, 195 | 14500, 14515, 14531, 14546, 14561, 14576, 14592, 14607, 196 | 14621, 14636, 14651, 14666, 14680, 14695, 14709, 14723, 197 | 14738, 14752, 14766, 14780, 14794, 14807, 14821, 14835, 198 | 14848, 14862, 14875, 14889, 14902, 14915, 14928, 14941, 199 | 14954, 14967, 14980, 14993, 15005, 15018, 15031, 15043, 200 | 15056, 15068, 15080, 15092, 15105, 15117, 15129, 15141, 201 | 15153, 15165, 15177, 15188, 15200, 15212, 15223, 15235, 202 | 15246, 15258, 15269, 15281, 15292, 15303, 15315, 15326, 203 | 15337, 15348, 15359, 15370, 15381, 15392, 15403, 15414, 204 | 15425, 15436, 15446, 15457, 15468, 15478, 15489, 15500, 205 | 15510, 15521, 15531, 15542, 15552, 15563, 15573, 15583, 206 | 15594, 15604, 15615, 15625, 15635, 15645, 15656, 15666, 207 | 15676, 15686, 15696, 15707, 15717, 15727, 15737, 15747, 208 | 15757, 15767, 15777, 15788, 15798, 15808, 15818, 15828, 209 | 15838, 15848, 15858, 15868, 15878, 15888, 15898, 15908, 210 | 15919, 15929, 15939, 15949, 15959, 15969, 15979, 15989, 211 | 16000, 16010, 16020, 16030, 16040, 16050, 16060, 16070, 212 | 16080, 16090, 16100, 16110, 16120, 16130, 16140, 16150, 213 | 16160, 16169, 16179, 16189, 16199, 16209, 16218, 16228, 214 | 16238, 16247, 16257, 16267, 16276, 16286, 16295, 16305, 215 | 16314, 16324, 16333, 16343, 16352, 16362, 16371, 16380, 216 | 16390, 16399, 16408, 16417, 16427, 16436, 16445, 16454, 217 | 16463, 16472, 16481, 16490, 16500, 16509, 16517, 16526, 218 | 16535, 16544, 16553, 16562, 16571, 16580, 16588, 16597, 219 | 16606, 16614, 16623, 16632, 16640, 16649, 16657, 16666, 220 | 16674, 16683, 16691, 16700, 16708, 16716, 16725, 16733, 221 | 16741, 16749, 16758, 16766, 16774, 16782, 16790, 16798, 222 | 16806, 16814, 16822, 16830, 16838, 16846, 16853, 16861, 223 | 16869, 16877, 16884, 16892, 16900, 16907, 16915, 16922, 224 | 16930, 16937, 16945, 16952, 16960, 16967, 16974, 16981, 225 | 16989, 16996, 17003, 17010, 17017, 17024, 17031, 17038, 226 | 17045, 17052, 17059, 17066, 17073, 17079, 17086, 17093, 227 | 17100, 17106, 17113, 17119, 17126, 17132, 17139, 17145, 228 | 17151, 17158, 17164, 17170, 17176, 17182, 17188, 17194, 229 | 17200, 17206, 17212, 17218, 17224, 17230, 17236, 17241, 230 | 17247, 17253, 17258, 17264, 17270, 17275, 17281, 17286, 231 | 17292, 17297, 17302, 17308, 17313, 17318, 17324, 17329, 232 | 17334, 17339, 17344, 17349, 17354, 17359, 17364, 17369, 233 | 17374, 17379, 17384, 17389, 17394, 17398, 17403, 17408, 234 | 17413, 17417, 17422, 17427, 17431, 17436, 17440, 17445, 235 | 17449, 17454, 17458, 17463, 17467, 17471, 17476, 17480, 236 | 17484, 17489, 17493, 17497, 17501, 17506, 17510, 17514, 237 | 17518, 17522, 17526, 17531, 17535, 17539, 17543, 17547, 238 | 17551, 17555, 17559, 17563, 17567, 17570, 17574, 17578, 239 | 17582, 17586, 17590, 17594, 17597, 17601, 17605, 17609, 240 | 17612, 17616, 17620, 17624, 17627, 17631, 17635, 17638, 241 | 17642, 17646, 17649, 17653, 17657, 17660, 17664, 17667, 242 | 17671, 17675, 17678, 17682, 17685, 17689, 17692, 17696, 243 | 17700, 17703, 17707, 17710, 17713, 17717, 17720, 17724, 244 | 17727, 17730, 17733, 17737, 17740, 17743, 17746, 17749, 245 | 17753, 17756, 17759, 17762, 17765, 17768, 17771, 17774, 246 | 17777, 17780, 17783, 17785, 17788, 17791, 17794, 17797, 247 | 17800, 17802, 17805, 17808, 17810, 17813, 17816, 17818, 248 | 17821, 17824, 17826, 17829, 17831, 17834, 17836, 17839, 249 | 17841, 17844, 17846, 17848, 17851, 17853, 17856, 17858, 250 | 17860, 17863, 17865, 17867, 17869, 17872, 17874, 17876, 251 | 17878, 17881, 17883, 17885, 17887, 17889, 17891, 17894, 252 | 17896, 17898, 17900, 17902, 17904, 17906, 17908, 17910, 253 | 17912, 17914, 17916, 17918, 17920, 17922, 17924, 17926, 254 | 17928, 17930, 17932, 17934, 17936, 17938, 17940, 17941, 255 | 17943, 17945, 17947, 17949, 17951, 17953, 17954, 17956, 256 | 17958, 17960, 17962, 17964, 17965, 17967, 17969, 17971, 257 | 17973, 17975, 17976, 17978, 17980, 17982, 17983, 17985, 258 | 17987, 17989, 17991, 17992, 17994, 17996, 17998, 17999 259 | ]; 260 | -------------------------------------------------------------------------------- /src/data/spline8580_f0.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | pub static SPLINE8580_F0: [i16; 2048] = [ 3 | 0, 6, 12, 18, 25, 31, 37, 43, 4 | 50, 56, 62, 68, 75, 81, 87, 93, 5 | 100, 106, 112, 118, 125, 131, 137, 143, 6 | 150, 156, 162, 168, 175, 181, 187, 193, 7 | 200, 206, 212, 218, 225, 231, 237, 243, 8 | 250, 256, 262, 268, 275, 281, 287, 293, 9 | 300, 306, 312, 318, 325, 331, 337, 343, 10 | 350, 356, 362, 368, 375, 381, 387, 393, 11 | 400, 406, 412, 418, 425, 431, 437, 443, 12 | 450, 456, 462, 468, 475, 481, 487, 493, 13 | 500, 506, 512, 518, 525, 531, 537, 543, 14 | 550, 556, 562, 568, 575, 581, 587, 593, 15 | 600, 606, 612, 618, 625, 631, 637, 643, 16 | 650, 656, 662, 668, 675, 681, 687, 693, 17 | 700, 706, 712, 718, 725, 731, 737, 743, 18 | 750, 756, 762, 768, 775, 781, 787, 793, 19 | 800, 806, 812, 818, 824, 831, 837, 843, 20 | 849, 856, 862, 868, 874, 880, 886, 893, 21 | 899, 905, 911, 917, 923, 930, 936, 942, 22 | 948, 954, 960, 966, 973, 979, 985, 991, 23 | 997, 1003, 1009, 1016, 1022, 1028, 1034, 1040, 24 | 1046, 1052, 1058, 1065, 1071, 1077, 1083, 1089, 25 | 1095, 1101, 1107, 1113, 1120, 1126, 1132, 1138, 26 | 1144, 1150, 1156, 1163, 1169, 1175, 1181, 1187, 27 | 1193, 1199, 1206, 1212, 1218, 1224, 1230, 1236, 28 | 1243, 1249, 1255, 1261, 1267, 1274, 1280, 1286, 29 | 1292, 1298, 1305, 1311, 1317, 1323, 1330, 1336, 30 | 1342, 1348, 1355, 1361, 1367, 1374, 1380, 1386, 31 | 1392, 1399, 1405, 1411, 1418, 1424, 1431, 1437, 32 | 1443, 1450, 1456, 1463, 1469, 1475, 1482, 1488, 33 | 1495, 1501, 1508, 1514, 1521, 1527, 1534, 1540, 34 | 1547, 1553, 1560, 1566, 1573, 1580, 1586, 1593, 35 | 1600, 1606, 1613, 1620, 1626, 1633, 1640, 1646, 36 | 1653, 1660, 1667, 1674, 1680, 1687, 1694, 1701, 37 | 1708, 1715, 1722, 1729, 1736, 1743, 1750, 1756, 38 | 1763, 1770, 1778, 1785, 1792, 1799, 1806, 1813, 39 | 1820, 1827, 1834, 1841, 1848, 1855, 1862, 1870, 40 | 1877, 1884, 1891, 1898, 1905, 1913, 1920, 1927, 41 | 1934, 1941, 1948, 1956, 1963, 1970, 1977, 1984, 42 | 1992, 1999, 2006, 2013, 2021, 2028, 2035, 2042, 43 | 2050, 2057, 2064, 2071, 2078, 2086, 2093, 2100, 44 | 2107, 2115, 2122, 2129, 2136, 2143, 2151, 2158, 45 | 2165, 2172, 2179, 2186, 2194, 2201, 2208, 2215, 46 | 2222, 2229, 2237, 2244, 2251, 2258, 2265, 2272, 47 | 2279, 2286, 2293, 2300, 2307, 2314, 2321, 2329, 48 | 2336, 2343, 2349, 2356, 2363, 2370, 2377, 2384, 49 | 2391, 2398, 2405, 2412, 2419, 2425, 2432, 2439, 50 | 2446, 2453, 2459, 2466, 2473, 2479, 2486, 2493, 51 | 2500, 2506, 2513, 2519, 2526, 2533, 2539, 2546, 52 | 2552, 2559, 2565, 2572, 2578, 2585, 2591, 2598, 53 | 2604, 2611, 2617, 2624, 2630, 2636, 2643, 2649, 54 | 2656, 2662, 2668, 2675, 2681, 2688, 2694, 2700, 55 | 2707, 2713, 2719, 2725, 2732, 2738, 2744, 2751, 56 | 2757, 2763, 2769, 2776, 2782, 2788, 2794, 2801, 57 | 2807, 2813, 2819, 2825, 2832, 2838, 2844, 2850, 58 | 2856, 2863, 2869, 2875, 2881, 2887, 2893, 2900, 59 | 2906, 2912, 2918, 2924, 2930, 2936, 2943, 2949, 60 | 2955, 2961, 2967, 2973, 2979, 2986, 2992, 2998, 61 | 3004, 3010, 3016, 3022, 3028, 3034, 3041, 3047, 62 | 3053, 3059, 3065, 3071, 3077, 3083, 3090, 3096, 63 | 3102, 3108, 3114, 3120, 3126, 3133, 3139, 3145, 64 | 3151, 3157, 3163, 3169, 3176, 3182, 3188, 3194, 65 | 3200, 3206, 3213, 3219, 3225, 3231, 3237, 3243, 66 | 3250, 3256, 3262, 3268, 3275, 3281, 3287, 3293, 67 | 3300, 3306, 3312, 3318, 3325, 3331, 3337, 3343, 68 | 3350, 3356, 3362, 3369, 3375, 3381, 3388, 3394, 69 | 3400, 3407, 3413, 3419, 3426, 3432, 3438, 3445, 70 | 3451, 3457, 3464, 3470, 3476, 3483, 3489, 3495, 71 | 3502, 3508, 3515, 3521, 3527, 3534, 3540, 3546, 72 | 3553, 3559, 3566, 3572, 3578, 3585, 3591, 3598, 73 | 3604, 3610, 3617, 3623, 3629, 3636, 3642, 3649, 74 | 3655, 3661, 3668, 3674, 3680, 3687, 3693, 3699, 75 | 3706, 3712, 3718, 3725, 3731, 3737, 3744, 3750, 76 | 3756, 3763, 3769, 3775, 3782, 3788, 3794, 3801, 77 | 3807, 3813, 3819, 3826, 3832, 3838, 3844, 3851, 78 | 3857, 3863, 3869, 3876, 3882, 3888, 3894, 3900, 79 | 3907, 3913, 3919, 3925, 3931, 3937, 3943, 3950, 80 | 3956, 3962, 3968, 3974, 3980, 3986, 3992, 3998, 81 | 4004, 4010, 4016, 4022, 4028, 4034, 4040, 4046, 82 | 4052, 4058, 4064, 4070, 4076, 4082, 4088, 4094, 83 | 4100, 4105, 4111, 4117, 4123, 4129, 4134, 4140, 84 | 4146, 4152, 4157, 4163, 4169, 4174, 4180, 4185, 85 | 4191, 4197, 4202, 4208, 4213, 4219, 4224, 4230, 86 | 4236, 4241, 4246, 4252, 4257, 4263, 4268, 4274, 87 | 4279, 4285, 4290, 4295, 4301, 4306, 4312, 4317, 88 | 4322, 4328, 4333, 4338, 4344, 4349, 4354, 4360, 89 | 4365, 4370, 4376, 4381, 4386, 4391, 4397, 4402, 90 | 4407, 4413, 4418, 4423, 4428, 4434, 4439, 4444, 91 | 4450, 4455, 4460, 4465, 4471, 4476, 4481, 4486, 92 | 4492, 4497, 4502, 4508, 4513, 4518, 4523, 4529, 93 | 4534, 4539, 4545, 4550, 4555, 4561, 4566, 4571, 94 | 4577, 4582, 4587, 4593, 4598, 4604, 4609, 4614, 95 | 4620, 4625, 4631, 4636, 4642, 4647, 4653, 4658, 96 | 4663, 4669, 4675, 4680, 4686, 4691, 4697, 4702, 97 | 4708, 4714, 4719, 4725, 4730, 4736, 4742, 4747, 98 | 4753, 4759, 4765, 4770, 4776, 4782, 4788, 4794, 99 | 4800, 4805, 4811, 4817, 4823, 4829, 4835, 4841, 100 | 4847, 4852, 4858, 4864, 4870, 4876, 4882, 4888, 101 | 4894, 4900, 4906, 4912, 4918, 4924, 4930, 4936, 102 | 4942, 4948, 4954, 4960, 4966, 4972, 4978, 4984, 103 | 4990, 4996, 5002, 5008, 5014, 5020, 5027, 5033, 104 | 5039, 5045, 5051, 5057, 5063, 5069, 5075, 5082, 105 | 5088, 5094, 5100, 5106, 5112, 5119, 5125, 5131, 106 | 5137, 5143, 5150, 5156, 5162, 5168, 5175, 5181, 107 | 5187, 5193, 5200, 5206, 5212, 5218, 5225, 5231, 108 | 5237, 5243, 5250, 5256, 5262, 5269, 5275, 5281, 109 | 5288, 5294, 5300, 5307, 5313, 5320, 5326, 5332, 110 | 5339, 5345, 5352, 5358, 5364, 5371, 5377, 5384, 111 | 5390, 5397, 5403, 5409, 5416, 5422, 5429, 5435, 112 | 5442, 5448, 5455, 5461, 5468, 5474, 5481, 5487, 113 | 5494, 5501, 5507, 5514, 5520, 5527, 5533, 5540, 114 | 5547, 5553, 5560, 5566, 5573, 5580, 5586, 5593, 115 | 5600, 5606, 5613, 5619, 5626, 5633, 5639, 5646, 116 | 5653, 5660, 5666, 5673, 5680, 5686, 5693, 5700, 117 | 5707, 5713, 5720, 5727, 5734, 5740, 5747, 5754, 118 | 5761, 5767, 5774, 5781, 5788, 5795, 5801, 5808, 119 | 5815, 5822, 5829, 5836, 5843, 5849, 5856, 5863, 120 | 5870, 5877, 5884, 5891, 5898, 5905, 5911, 5918, 121 | 5925, 5932, 5939, 5946, 5953, 5960, 5967, 5974, 122 | 5981, 5988, 5995, 6002, 6009, 6016, 6023, 6030, 123 | 6037, 6044, 6051, 6058, 6065, 6072, 6079, 6086, 124 | 6093, 6101, 6108, 6115, 6122, 6129, 6136, 6143, 125 | 6150, 6157, 6165, 6172, 6179, 6186, 6193, 6200, 126 | 6208, 6215, 6222, 6229, 6236, 6243, 6251, 6258, 127 | 6265, 6272, 6280, 6287, 6294, 6301, 6309, 6316, 128 | 6323, 6330, 6338, 6345, 6352, 6360, 6367, 6374, 129 | 6382, 6389, 6396, 6404, 6411, 6418, 6426, 6433, 130 | 6440, 6448, 6455, 6462, 6470, 6477, 6485, 6492, 131 | 6500, 6507, 6514, 6522, 6529, 6537, 6544, 6552, 132 | 6559, 6567, 6575, 6582, 6590, 6597, 6605, 6613, 133 | 6620, 6628, 6636, 6643, 6651, 6659, 6667, 6674, 134 | 6682, 6690, 6698, 6706, 6713, 6721, 6729, 6737, 135 | 6745, 6753, 6761, 6768, 6776, 6784, 6792, 6800, 136 | 6808, 6816, 6824, 6832, 6840, 6848, 6856, 6864, 137 | 6872, 6880, 6888, 6896, 6903, 6911, 6919, 6927, 138 | 6935, 6943, 6951, 6959, 6967, 6975, 6983, 6991, 139 | 7000, 7008, 7016, 7024, 7032, 7040, 7048, 7056, 140 | 7064, 7072, 7080, 7088, 7096, 7103, 7111, 7119, 141 | 7127, 7135, 7143, 7151, 7159, 7167, 7175, 7183, 142 | 7191, 7199, 7207, 7215, 7223, 7231, 7238, 7246, 143 | 7254, 7262, 7270, 7278, 7286, 7293, 7301, 7309, 144 | 7317, 7325, 7332, 7340, 7348, 7356, 7363, 7371, 145 | 7379, 7386, 7394, 7402, 7409, 7417, 7424, 7432, 146 | 7440, 7447, 7455, 7462, 7470, 7477, 7485, 7492, 147 | 7500, 7507, 7514, 7522, 7529, 7537, 7544, 7551, 148 | 7559, 7566, 7573, 7581, 7588, 7595, 7603, 7610, 149 | 7617, 7625, 7632, 7639, 7647, 7654, 7661, 7669, 150 | 7676, 7683, 7690, 7698, 7705, 7712, 7719, 7727, 151 | 7734, 7741, 7748, 7756, 7763, 7770, 7777, 7784, 152 | 7791, 7799, 7806, 7813, 7820, 7827, 7834, 7842, 153 | 7849, 7856, 7863, 7870, 7877, 7884, 7891, 7898, 154 | 7906, 7913, 7920, 7927, 7934, 7941, 7948, 7955, 155 | 7962, 7969, 7976, 7983, 7990, 7997, 8004, 8011, 156 | 8018, 8025, 8032, 8039, 8046, 8053, 8060, 8067, 157 | 8074, 8081, 8088, 8094, 8101, 8108, 8115, 8122, 158 | 8129, 8136, 8143, 8150, 8156, 8163, 8170, 8177, 159 | 8184, 8191, 8198, 8204, 8211, 8218, 8225, 8232, 160 | 8238, 8245, 8252, 8259, 8265, 8272, 8279, 8286, 161 | 8292, 8299, 8306, 8313, 8319, 8326, 8333, 8339, 162 | 8346, 8353, 8360, 8366, 8373, 8380, 8386, 8393, 163 | 8400, 8406, 8413, 8419, 8426, 8433, 8439, 8446, 164 | 8453, 8459, 8466, 8473, 8479, 8486, 8492, 8499, 165 | 8506, 8512, 8519, 8526, 8532, 8539, 8545, 8552, 166 | 8559, 8565, 8572, 8578, 8585, 8591, 8598, 8605, 167 | 8611, 8618, 8624, 8631, 8637, 8644, 8651, 8657, 168 | 8664, 8670, 8677, 8683, 8690, 8696, 8703, 8709, 169 | 8716, 8722, 8729, 8735, 8741, 8748, 8754, 8761, 170 | 8767, 8774, 8780, 8786, 8793, 8799, 8806, 8812, 171 | 8818, 8825, 8831, 8837, 8844, 8850, 8856, 8862, 172 | 8869, 8875, 8881, 8887, 8894, 8900, 8906, 8912, 173 | 8919, 8925, 8931, 8937, 8943, 8949, 8955, 8962, 174 | 8968, 8974, 8980, 8986, 8992, 8998, 9004, 9010, 175 | 9016, 9022, 9028, 9034, 9040, 9046, 9052, 9057, 176 | 9063, 9069, 9075, 9081, 9087, 9092, 9098, 9104, 177 | 9110, 9115, 9121, 9127, 9133, 9138, 9144, 9150, 178 | 9155, 9161, 9166, 9172, 9177, 9183, 9189, 9194, 179 | 9200, 9205, 9210, 9216, 9221, 9226, 9232, 9237, 180 | 9242, 9248, 9253, 9258, 9263, 9268, 9273, 9278, 181 | 9283, 9288, 9293, 9298, 9303, 9308, 9313, 9318, 182 | 9323, 9328, 9333, 9337, 9342, 9347, 9352, 9356, 183 | 9361, 9366, 9371, 9375, 9380, 9385, 9389, 9394, 184 | 9398, 9403, 9408, 9412, 9417, 9421, 9426, 9430, 185 | 9435, 9439, 9444, 9448, 9453, 9457, 9462, 9466, 186 | 9470, 9475, 9479, 9484, 9488, 9493, 9497, 9501, 187 | 9506, 9510, 9515, 9519, 9523, 9528, 9532, 9536, 188 | 9541, 9545, 9550, 9554, 9558, 9563, 9567, 9572, 189 | 9576, 9580, 9585, 9589, 9594, 9598, 9602, 9607, 190 | 9611, 9616, 9620, 9625, 9629, 9634, 9638, 9643, 191 | 9647, 9652, 9656, 9661, 9665, 9670, 9674, 9679, 192 | 9684, 9688, 9693, 9698, 9702, 9707, 9712, 9716, 193 | 9721, 9726, 9731, 9735, 9740, 9745, 9750, 9755, 194 | 9760, 9765, 9769, 9774, 9779, 9784, 9789, 9794, 195 | 9800, 9805, 9810, 9815, 9820, 9825, 9830, 9836, 196 | 9841, 9846, 9851, 9857, 9862, 9867, 9873, 9878, 197 | 9884, 9889, 9894, 9900, 9905, 9911, 9916, 9922, 198 | 9927, 9933, 9939, 9944, 9950, 9955, 9961, 9967, 199 | 9972, 9978, 9983, 9989, 9995, 10000, 10006, 10012, 200 | 10018, 10023, 10029, 10035, 10040, 10046, 10052, 10058, 201 | 10063, 10069, 10075, 10081, 10087, 10092, 10098, 10104, 202 | 10110, 10115, 10121, 10127, 10133, 10138, 10144, 10150, 203 | 10156, 10162, 10167, 10173, 10179, 10185, 10190, 10196, 204 | 10202, 10207, 10213, 10219, 10225, 10230, 10236, 10242, 205 | 10247, 10253, 10259, 10264, 10270, 10275, 10281, 10287, 206 | 10292, 10298, 10303, 10309, 10314, 10320, 10325, 10331, 207 | 10336, 10342, 10347, 10352, 10358, 10363, 10369, 10374, 208 | 10379, 10384, 10390, 10395, 10400, 10405, 10411, 10416, 209 | 10421, 10426, 10431, 10436, 10441, 10446, 10451, 10456, 210 | 10461, 10466, 10471, 10476, 10481, 10485, 10490, 10495, 211 | 10500, 10504, 10509, 10513, 10518, 10522, 10527, 10531, 212 | 10536, 10540, 10545, 10549, 10553, 10558, 10562, 10566, 213 | 10570, 10574, 10578, 10583, 10587, 10591, 10595, 10599, 214 | 10603, 10607, 10611, 10615, 10618, 10622, 10626, 10630, 215 | 10634, 10638, 10641, 10645, 10649, 10653, 10656, 10660, 216 | 10664, 10667, 10671, 10675, 10678, 10682, 10686, 10689, 217 | 10693, 10696, 10700, 10704, 10707, 10711, 10714, 10718, 218 | 10721, 10725, 10728, 10732, 10735, 10739, 10742, 10746, 219 | 10750, 10753, 10757, 10760, 10764, 10767, 10771, 10774, 220 | 10778, 10781, 10785, 10788, 10792, 10795, 10799, 10803, 221 | 10806, 10810, 10813, 10817, 10821, 10824, 10828, 10832, 222 | 10835, 10839, 10843, 10846, 10850, 10854, 10858, 10861, 223 | 10865, 10869, 10873, 10877, 10881, 10884, 10888, 10892, 224 | 10896, 10900, 10904, 10908, 10912, 10916, 10921, 10925, 225 | 10929, 10933, 10937, 10941, 10946, 10950, 10954, 10959, 226 | 10963, 10968, 10972, 10977, 10981, 10986, 10990, 10995, 227 | 11000, 11004, 11009, 11014, 11018, 11023, 11028, 11033, 228 | 11038, 11042, 11047, 11052, 11057, 11062, 11067, 11072, 229 | 11077, 11082, 11087, 11092, 11097, 11102, 11107, 11112, 230 | 11117, 11122, 11127, 11132, 11137, 11142, 11148, 11153, 231 | 11158, 11163, 11168, 11174, 11179, 11184, 11189, 11195, 232 | 11200, 11205, 11211, 11216, 11221, 11227, 11232, 11237, 233 | 11243, 11248, 11254, 11259, 11264, 11270, 11275, 11281, 234 | 11286, 11292, 11297, 11303, 11308, 11314, 11319, 11325, 235 | 11330, 11336, 11342, 11347, 11353, 11358, 11364, 11370, 236 | 11375, 11381, 11386, 11392, 11398, 11403, 11409, 11415, 237 | 11420, 11426, 11432, 11438, 11443, 11449, 11455, 11460, 238 | 11466, 11472, 11478, 11483, 11489, 11495, 11501, 11507, 239 | 11512, 11518, 11524, 11530, 11536, 11541, 11547, 11553, 240 | 11559, 11565, 11571, 11576, 11582, 11588, 11594, 11600, 241 | 11606, 11611, 11617, 11623, 11629, 11635, 11641, 11647, 242 | 11652, 11658, 11664, 11670, 11676, 11682, 11688, 11694, 243 | 11700, 11705, 11711, 11717, 11723, 11729, 11735, 11741, 244 | 11747, 11753, 11759, 11765, 11771, 11777, 11783, 11789, 245 | 11795, 11801, 11807, 11813, 11819, 11825, 11831, 11837, 246 | 11843, 11849, 11856, 11862, 11868, 11874, 11880, 11886, 247 | 11892, 11899, 11905, 11911, 11917, 11923, 11929, 11936, 248 | 11942, 11948, 11954, 11961, 11967, 11973, 11979, 11986, 249 | 11992, 11998, 12004, 12011, 12017, 12023, 12029, 12036, 250 | 12042, 12048, 12055, 12061, 12067, 12074, 12080, 12086, 251 | 12093, 12099, 12105, 12112, 12118, 12125, 12131, 12137, 252 | 12144, 12150, 12157, 12163, 12169, 12176, 12182, 12189, 253 | 12195, 12201, 12208, 12214, 12221, 12227, 12234, 12240, 254 | 12246, 12253, 12259, 12266, 12272, 12279, 12285, 12292, 255 | 12298, 12305, 12311, 12318, 12324, 12331, 12337, 12343, 256 | 12350, 12356, 12363, 12369, 12376, 12382, 12389, 12395, 257 | 12402, 12408, 12415, 12421, 12428, 12434, 12441, 12447, 258 | 12454, 12460, 12467, 12473, 12480, 12486, 12493, 12499 259 | ]; 260 | -------------------------------------------------------------------------------- /src/wave.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | 8 | use bit_field::BitField; 9 | 10 | use super::data; 11 | use super::ChipModel; 12 | 13 | const ACC_MASK: u32 = 0x00ff_ffff; 14 | const ACC_BIT19_MASK: u32 = 0x0008_0000; 15 | const ACC_MSB_MASK: u32 = 0x0080_0000; 16 | const SHIFT_MASK: u32 = 0x007f_ffff; 17 | const OUTPUT_MASK: u16 = 0x0fff; 18 | 19 | /// A 24 bit accumulator is the basis for waveform generation. FREQ is added to 20 | /// the lower 16 bits of the accumulator each cycle. 21 | /// The accumulator is set to zero when TEST is set, and starts counting 22 | /// when TEST is cleared. 23 | /// The noise waveform is taken from intermediate bits of a 23 bit shift 24 | /// register. This register is clocked by bit 19 of the accumulator. 25 | #[derive(Clone, Copy)] 26 | pub struct WaveformGenerator { 27 | // Configuration 28 | frequency: u16, 29 | pulse_width: u16, 30 | // Control 31 | waveform: u8, 32 | ring: bool, 33 | sync: bool, 34 | test: bool, 35 | // Runtime State 36 | pub acc: u32, 37 | pub shift: u32, 38 | msb_rising: bool, 39 | // Static Data 40 | wave_ps: &'static [u8; 4096], 41 | wave_pst: &'static [u8; 4096], 42 | wave_pt: &'static [u8; 4096], 43 | wave_st: &'static [u8; 4096], 44 | } 45 | 46 | pub struct Syncable { 47 | pub main: T, 48 | pub sync_source: T, 49 | pub sync_dest: T, 50 | } 51 | 52 | impl WaveformGenerator { 53 | pub fn new(chip_model: ChipModel) -> Self { 54 | let (wave_ps, wave_pst, wave_pt, wave_st) = match chip_model { 55 | ChipModel::Mos6581 => ( 56 | &data::WAVE6581_PS, 57 | &data::WAVE6581_PST, 58 | &data::WAVE6581_PT, 59 | &data::WAVE6581_ST, 60 | ), 61 | ChipModel::Mos8580 => ( 62 | &data::WAVE8580_PS, 63 | &data::WAVE8580_PST, 64 | &data::WAVE8580_PT, 65 | &data::WAVE8580_ST, 66 | ), 67 | }; 68 | let mut waveform = WaveformGenerator { 69 | frequency: 0, 70 | pulse_width: 0, 71 | waveform: 0, 72 | ring: false, 73 | sync: false, 74 | test: false, 75 | acc: 0, 76 | shift: 0, 77 | msb_rising: false, 78 | wave_ps, 79 | wave_pst, 80 | wave_pt, 81 | wave_st, 82 | }; 83 | waveform.reset(); 84 | waveform 85 | } 86 | 87 | pub fn get_acc(&self) -> u32 { 88 | self.acc 89 | } 90 | 91 | pub fn get_control(&self) -> u8 { 92 | let mut value = 0u8; 93 | value.set_bit(1, self.sync); 94 | value.set_bit(2, self.ring); 95 | value.set_bit(3, self.test); 96 | value | (self.waveform << 4) 97 | } 98 | 99 | pub fn get_frequency(&self) -> u16 { 100 | self.frequency 101 | } 102 | 103 | pub fn get_frequency_hi(&self) -> u8 { 104 | (self.frequency >> 8) as u8 105 | } 106 | 107 | pub fn get_frequency_lo(&self) -> u8 { 108 | (self.frequency & 0x00ff) as u8 109 | } 110 | 111 | pub fn get_pulse_width_hi(&self) -> u8 { 112 | (self.pulse_width >> 8) as u8 113 | } 114 | 115 | pub fn get_pulse_width_lo(&self) -> u8 { 116 | (self.pulse_width & 0x00ff) as u8 117 | } 118 | 119 | pub fn get_shift(&self) -> u32 { 120 | self.shift 121 | } 122 | 123 | pub fn get_sync(&self) -> bool { 124 | self.sync 125 | } 126 | 127 | pub fn is_msb_rising(&self) -> bool { 128 | self.msb_rising 129 | } 130 | 131 | pub fn set_acc(&mut self, value: u32) { 132 | self.acc = value; 133 | } 134 | 135 | pub fn set_control(&mut self, value: u8) { 136 | self.waveform = (value >> 4) & 0x0f; 137 | self.sync = value.get_bit(1); 138 | self.ring = value.get_bit(2); 139 | let test = value.get_bit(3); 140 | if test { 141 | // Test bit set. 142 | // The accumulator and the shift register are both cleared. 143 | // NB! The shift register is not really cleared immediately. It seems like 144 | // the individual bits in the shift register start to fade down towards 145 | // zero when test is set. All bits reach zero within approximately 146 | // $2000 - $4000 cycles. 147 | // This is not modeled. There should fortunately be little audible output 148 | // from this peculiar behavior. 149 | self.acc = 0; 150 | self.shift = 0; 151 | } else if self.test { 152 | // Test bit cleared. 153 | // The accumulator starts counting, and the shift register is reset to 154 | // the value 0x7ffff8. 155 | // NB! The shift register will not actually be set to this exact value if the 156 | // shift register bits have not had time to fade to zero. 157 | // This is not modeled. 158 | self.shift = 0x007f_fff8; 159 | } 160 | self.test = test; 161 | } 162 | 163 | pub fn set_frequency_hi(&mut self, value: u8) { 164 | let result = (((value as u16) << 8) & 0xff00) | (self.frequency & 0x00ff); 165 | self.frequency = result; 166 | } 167 | 168 | pub fn set_frequency_lo(&mut self, value: u8) { 169 | let result = (self.frequency & 0xff00) | ((value as u16) & 0x00ff); 170 | self.frequency = result; 171 | } 172 | 173 | pub fn set_pulse_width_hi(&mut self, value: u8) { 174 | let result = (((value as u16) << 8) & 0x0f00) | (self.pulse_width & 0x00ff); 175 | self.pulse_width = result; 176 | } 177 | 178 | pub fn set_pulse_width_lo(&mut self, value: u8) { 179 | let result = (self.pulse_width & 0x0f00) | ((value as u16) & 0x00ff); 180 | self.pulse_width = result; 181 | } 182 | 183 | #[inline] 184 | pub fn clock(&mut self) { 185 | // No operation if test bit is set. 186 | if !self.test { 187 | let acc_prev = self.acc; 188 | // Calculate new accumulator value; 189 | self.acc = (self.acc + self.frequency as u32) & ACC_MASK; 190 | // Check whether the MSB is set high. This is used for synchronization. 191 | self.msb_rising = (acc_prev & ACC_MSB_MASK) == 0 && (self.acc & ACC_MSB_MASK) != 0; 192 | if (acc_prev & ACC_BIT19_MASK) == 0 && (self.acc & ACC_BIT19_MASK) != 0 { 193 | // Shift noise register once for each time accumulator bit 19 is set high. 194 | let bit0 = ((self.shift >> 22) ^ (self.shift >> 17)) & 0x01; 195 | self.shift = ((self.shift << 1) & SHIFT_MASK) | bit0; 196 | } 197 | } 198 | } 199 | 200 | #[inline] 201 | pub fn clock_delta(&mut self, delta: u32) { 202 | if !self.test { 203 | let acc_prev = self.acc; 204 | // Calculate new accumulator value; 205 | let mut delta_acc = delta * self.frequency as u32; 206 | self.acc = (self.acc + delta_acc) & ACC_MASK; 207 | // Check whether the MSB is set high. This is used for synchronization. 208 | self.msb_rising = (acc_prev & ACC_MSB_MASK) == 0 && (self.acc & ACC_MSB_MASK) != 0; 209 | // Shift noise register once for each time accumulator bit 19 is set high. 210 | // Bit 19 is set high each time 2^20 (0x100000) is added to the accumulator. 211 | let mut shift_period = 0x0010_0000; 212 | while delta_acc != 0 { 213 | if delta_acc < shift_period { 214 | shift_period = delta_acc; 215 | // Determine whether bit 19 is set on the last period. 216 | // NB! Requires two's complement integer. 217 | if shift_period <= 0x0008_0000 { 218 | // Check for flip from 0 to 1. 219 | if ((self.acc as i32 - shift_period as i32) & ACC_BIT19_MASK as i32) != 0 220 | || (self.acc & ACC_BIT19_MASK) == 0 221 | { 222 | break; 223 | } 224 | // Check for flip from 0 (to 1 or via 1 to 0) or from 1 via 0 to 1. 225 | } else if ((self.acc as i32 - shift_period as i32) & ACC_BIT19_MASK as i32) != 0 226 | && (self.acc & ACC_BIT19_MASK) == 0 227 | { 228 | break; 229 | } 230 | } 231 | // Shift the noise/random register. 232 | let bit0 = ((self.shift >> 22) ^ (self.shift >> 17)) & 0x01; 233 | self.shift = (self.shift << 1) & SHIFT_MASK | bit0; 234 | delta_acc -= shift_period; 235 | } 236 | } 237 | } 238 | 239 | /// 12-bit waveform output 240 | #[inline] 241 | pub fn output(&self, sync_source: Option<&WaveformGenerator>) -> u16 { 242 | match self.waveform { 243 | 0x0 => 0, 244 | 0x1 => self.output_t(sync_source), 245 | 0x2 => self.output_s(), 246 | 0x3 => self.output_st(), 247 | 0x4 => self.output_p(), 248 | 0x5 => self.output_pt(sync_source), 249 | 0x6 => self.output_ps(), 250 | 0x7 => self.output_pst(), 251 | 0x8 => self.output_n(), 252 | 0x9 => 0, 253 | 0xa => 0, 254 | 0xb => 0, 255 | 0xc => 0, 256 | 0xd => 0, 257 | 0xe => 0, 258 | 0xf => 0, 259 | _ => panic!("invalid waveform {}", self.waveform), 260 | } 261 | } 262 | 263 | pub fn reset(&mut self) { 264 | self.frequency = 0; 265 | self.pulse_width = 0; 266 | self.waveform = 0; // NOTE this is not in orig resid 267 | self.ring = false; 268 | self.sync = false; 269 | self.test = false; 270 | self.acc = 0; 271 | self.shift = 0x007f_fff8; 272 | self.msb_rising = false; 273 | } 274 | 275 | // -- Output Functions 276 | 277 | /// Noise: 278 | /// The noise output is taken from intermediate bits of a 23-bit shift register 279 | /// which is clocked by bit 19 of the accumulator. 280 | /// NB! The output is actually delayed 2 cycles after bit 19 is set high. 281 | /// This is not modeled. 282 | /// 283 | /// Operation: Calculate EOR result, shift register, set bit 0 = result. 284 | ///``` ignore, 285 | /// ----------------------->--------------------- 286 | /// | | 287 | /// ----EOR---- | 288 | /// | | | 289 | /// 2 2 2 1 1 1 1 1 1 1 1 1 1 | 290 | /// Register bits: 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 <--- 291 | /// | | | | | | | | 292 | /// OSC3 bits : 7 6 5 4 3 2 1 0 293 | /// ``` 294 | /// Since waveform output is 12 bits the output is left-shifted 4 times. 295 | #[inline] 296 | fn output_n(&self) -> u16 { 297 | (((self.shift & 0x0040_0000) >> 11) 298 | | ((self.shift & 0x0010_0000) >> 10) 299 | | ((self.shift & 0x0001_0000) >> 7) 300 | | ((self.shift & 0x0000_2000) >> 5) 301 | | ((self.shift & 0x0000_0800) >> 4) 302 | | ((self.shift & 0x0000_0080) >> 1) 303 | | ((self.shift & 0x0000_0010) << 1) 304 | | ((self.shift & 0x0000_0004) << 2)) as u16 305 | } 306 | 307 | /// Pulse: 308 | /// The upper 12 bits of the accumulator are used. 309 | /// These bits are compared to the pulse width register by a 12 bit digital 310 | /// comparator; output is either all one or all zero bits. 311 | /// NB! The output is actually delayed one cycle after the compare. 312 | /// This is not modeled. 313 | /// 314 | /// The test bit, when set to one, holds the pulse waveform output at 0xfff 315 | /// regardless of the pulse width setting. 316 | #[inline] 317 | fn output_p(&self) -> u16 { 318 | if self.test || ((self.acc >> 12) as u16 >= self.pulse_width) { 319 | 0x0fff 320 | } else { 321 | 0x0000 322 | } 323 | } 324 | 325 | /// Sawtooth: 326 | /// The output is identical to the upper 12 bits of the accumulator. 327 | #[inline] 328 | fn output_s(&self) -> u16 { 329 | (self.acc >> 12) as u16 330 | } 331 | 332 | /// Triangle: 333 | /// The upper 12 bits of the accumulator are used. 334 | /// The MSB is used to create the falling edge of the triangle by inverting 335 | /// the lower 11 bits. The MSB is thrown away and the lower 11 bits are 336 | /// left-shifted (half the resolution, full amplitude). 337 | /// Ring modulation substitutes the MSB with MSB EOR sync_source MSB. 338 | #[inline] 339 | fn output_t(&self, sync_source: Option<&WaveformGenerator>) -> u16 { 340 | let acc = if self.ring { 341 | self.acc ^ sync_source.map(|x| x.acc).unwrap_or(0) 342 | } else { 343 | self.acc 344 | }; 345 | let msb = acc & ACC_MSB_MASK; 346 | let output = if msb != 0 { !self.acc } else { self.acc }; 347 | (output >> 11) as u16 & OUTPUT_MASK 348 | } 349 | 350 | // -- Combined Waveforms 351 | 352 | #[inline] 353 | fn output_ps(&self) -> u16 { 354 | ((self.wave_ps[self.output_s() as usize] as u16) << 4) & self.output_p() 355 | } 356 | 357 | #[inline] 358 | fn output_pst(&self) -> u16 { 359 | ((self.wave_pst[self.output_s() as usize] as u16) << 4) & self.output_p() 360 | } 361 | 362 | #[inline] 363 | fn output_pt(&self, sync_source: Option<&WaveformGenerator>) -> u16 { 364 | ((self.wave_pt[(self.output_t(sync_source) >> 1) as usize] as u16) << 4) & self.output_p() 365 | } 366 | 367 | #[inline] 368 | fn output_st(&self) -> u16 { 369 | (self.wave_st[self.output_s() as usize] as u16) << 4 370 | } 371 | } 372 | 373 | impl Syncable<&'_ WaveformGenerator> { 374 | pub fn read_osc(&self) -> u8 { 375 | (self.main.output(Some(self.sync_source)) >> 4) as u8 376 | } 377 | } 378 | 379 | impl Syncable<&'_ mut WaveformGenerator> { 380 | /// Synchronize oscillators. 381 | /// This must be done after all the oscillators have been clock()'ed since the 382 | /// oscillators operate in parallel. 383 | /// Note that the oscillators must be clocked exactly on the cycle when the 384 | /// MSB is set high for hard sync to operate correctly. See SID::clock(). 385 | #[inline] 386 | pub fn synchronize(&mut self) { 387 | // A special case occurs when a sync source is synced itself on the same 388 | // cycle as when its MSB is set high. In this case the destination will 389 | // not be synced. This has been verified by sampling OSC3. 390 | if self.main.is_msb_rising() { 391 | if self.sync_dest.sync { 392 | if !(self.main.sync && self.sync_source.is_msb_rising()) { 393 | self.sync_dest.set_acc(0); 394 | } 395 | } 396 | } 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /tests/filter_test.rs: -------------------------------------------------------------------------------- 1 | use resid::{ChipModel, Sid}; 2 | 3 | const CPU_FREQ: u32 = 985248; 4 | const SAMPLE_FREQ: u32 = 44100; 5 | const SAMPLE_COUNT: usize = 128; 6 | const CYCLES_PER_SAMPLE: u32 = CPU_FREQ / SAMPLE_FREQ; 7 | 8 | fn dump(sid: &mut Sid, _name: &str, samples: usize) -> Vec { 9 | let mut buffer = vec![0; samples]; 10 | let _ = sid.sample(samples as u32 * CYCLES_PER_SAMPLE, &mut buffer, 1); 11 | buffer 12 | } 13 | 14 | fn setup(sid: &mut Sid, voice: u8, waveform: u8, freq: u16, pw: u16, vol: u8) { 15 | let offset = voice * 7; 16 | let control = (waveform << 4) | 1; 17 | sid.write(offset + 0x00, (freq & 0x00ff) as u8); // FREQ_LO 18 | sid.write(offset + 0x01, (freq >> 8) as u8); // FREQ_HI 19 | sid.write(offset + 0x02, (pw & 0x00ff) as u8); // PW_LO 20 | sid.write(offset + 0x03, (pw >> 8) as u8); // PW_HI 21 | sid.write(offset + 0x04, control); // CONTROL 22 | sid.write(offset + 0x05, 9); // ATTACK_DECAY 23 | sid.write(offset + 0x06, 0); // SUSTAIN_RELEASE 24 | sid.write(0x18, vol); // MODE_VOL 25 | } 26 | 27 | #[test] 28 | fn filter_off() { 29 | let expected: Vec = vec![ 30 | -21189, -21155, -21147, -21139, -20987, -20956, -20909, -20878, -20831, -20800, -20753, 31 | -20721, -20675, -20643, -20166, -20112, -20030, -19975, -19893, -19839, -19757, -19703, 32 | -19621, -19566, -19484, -19430, -19348, -19293, -19212, -19157, -19075, -19021, -18966, 33 | -18884, -18830, -18748, -18693, -18612, -18557, -18475, -18421, -18339, -18284, -18203, 34 | -18148, -18066, -18012, -17930, -17875, -17793, -19205, -17658, -17604, -17522, -17467, 35 | -17385, -17331, -17249, -17195, -17140, -17058, -17004, -16922, -16867, -16785, -16731, 36 | -16649, -16595, -16513, -16458, -18424, -18392, -18345, -18314, -16104, -16049, -15967, 37 | -15913, -15831, -15776, -15695, -15640, -15558, -15504, -15422, -15367, -15285, -15231, 38 | -15176, -15095, -15040, -14958, -14904, -14822, -14767, -14685, -14631, -14549, -14495, 39 | -14413, -14358, -17220, -14222, -14222, -14222, -14222, -14222, -14222, -14222, -14222, 40 | -14222, -14222, -14222, -14222, -17188, -17188, -17188, -17188, -17188, -17188, -17188, 41 | -17188, -17188, -17188, -17188, -17188, 0, 0, 42 | ]; 43 | let mut sid = Sid::new(ChipModel::Mos6581); 44 | sid.enable_external_filter(false); 45 | sid.enable_filter(false); 46 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 47 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 48 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 49 | let res = dump(&mut sid, "filter_off", SAMPLE_COUNT); 50 | assert_eq!(res, expected); 51 | } 52 | 53 | #[test] 54 | fn filter_on() { 55 | let expected: Vec = vec![ 56 | -21189, -21155, -21147, -21139, -20987, -20956, -20909, -20878, -20831, -20800, -20753, 57 | -20721, -20675, -20643, -20166, -20112, -20030, -19975, -19893, -19839, -19757, -19703, 58 | -19621, -19566, -19484, -19430, -19348, -19293, -19212, -19157, -19075, -19021, -18966, 59 | -18884, -18830, -18748, -18693, -18612, -18557, -18475, -18421, -18339, -18284, -18203, 60 | -18148, -18066, -18012, -17930, -17875, -17793, -19205, -17658, -17604, -17522, -17467, 61 | -17385, -17331, -17249, -17195, -17140, -17058, -17004, -16922, -16867, -16785, -16731, 62 | -16649, -16595, -16513, -16458, -18424, -18392, -18345, -18314, -16104, -16049, -15967, 63 | -15913, -15831, -15776, -15695, -15640, -15558, -15504, -15422, -15367, -15285, -15231, 64 | -15176, -15095, -15040, -14958, -14904, -14822, -14767, -14685, -14631, -14549, -14495, 65 | -14413, -14358, -17220, -14222, -14222, -14222, -14222, -14222, -14222, -14222, -14222, 66 | -14222, -14222, -14222, -14222, -17188, -17188, -17188, -17188, -17188, -17188, -17188, 67 | -17188, -17188, -17188, -17188, -17188, 0, 0, 68 | ]; 69 | let mut sid = Sid::new(ChipModel::Mos6581); 70 | sid.enable_external_filter(false); 71 | sid.enable_filter(true); 72 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 73 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 74 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 75 | let res = dump(&mut sid, "filter_on", SAMPLE_COUNT); 76 | assert_eq!(res, expected); 77 | } 78 | 79 | #[test] 80 | fn filter_vol_8() { 81 | let expected: Vec = vec![ 82 | -16919, -16849, -16833, -16817, -16515, -16452, -16358, -16296, -16202, -16139, -16045, 83 | -15983, -15889, -15827, -14872, -14763, -14600, -14491, -14327, -14218, -14054, -13945, 84 | -13781, -13672, -13509, -13400, -13236, -13127, -12963, -12854, -12691, -12581, -12472, 85 | -12309, -12200, -12036, -11927, -11763, -11654, -11491, -11381, -11218, -11109, -10945, 86 | -10836, -10672, -10563, -10400, -10291, -10127, -12949, -9856, -9747, -9584, -9475, -9311, 87 | -9202, -9038, -8929, -8820, -8656, -8547, -8384, -8275, -8111, -8002, -7838, -7729, -7565, 88 | -7456, -11387, -11325, -11231, -11168, -6747, -6638, -6475, -6365, -6202, -6093, -5929, 89 | -5820, -5656, -5547, -5384, -5275, -5111, -5002, -4893, -4729, -4620, -4456, -4347, -4184, 90 | -4075, -3911, -3802, -3638, -3529, -3365, -3256, -8979, -2984, -2984, -2984, -2984, -2984, 91 | -2984, -2984, -2984, -2984, -2984, -2984, -2984, -8917, -8917, -8917, -8917, -8917, -8917, 92 | -8917, -8917, -8917, -8917, -8917, -8917, 0, 0, 93 | ]; 94 | let mut sid = Sid::new(ChipModel::Mos6581); 95 | sid.enable_external_filter(false); 96 | sid.enable_filter(true); 97 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 98 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 99 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 100 | sid.write(0x18, 8); // MODE_VOL 101 | let res = dump(&mut sid, "filter_vol_8", SAMPLE_COUNT); 102 | assert_eq!(res, expected); 103 | } 104 | 105 | #[test] 106 | fn filter_voice3_off() { 107 | let expected: Vec = vec![ 108 | -22668, -22683, -22693, -22704, -22580, -22567, -22547, -22534, -22514, -22501, -22481, 109 | -22468, -22449, -22436, -21986, -21949, -21895, -21859, -21804, -21768, -21713, -21677, 110 | -21622, -21586, -21531, -21495, -21440, -21404, -21349, -21313, -21259, -21222, -21186, 111 | -21131, -21095, -21040, -21004, -20949, -20913, -20859, -20822, -20768, -20731, -20677, 112 | -20640, -20586, -20549, -20495, -20459, -20404, -20368, -20314, -20277, -20223, -20187, 113 | -20132, -20096, -20041, -20005, -19968, -19914, -19877, -19823, -19787, -19732, -19696, 114 | -19641, -19605, -19550, -19514, -21507, -21493, -21474, -21461, -19277, -19241, -19187, 115 | -19150, -19096, -19059, -19005, -18968, -18914, -18877, -18823, -18787, -18732, -18696, 116 | -18659, -18605, -18568, -18514, -18477, -18423, -18387, -18332, -18296, -18241, -18205, 117 | -18150, -18114, -18059, -18023, -18023, -18023, -18023, -18023, -18023, -18023, -18023, 118 | -18023, -18023, -18023, -18023, -20989, -20989, -20989, -20989, -20989, -20989, -20989, 119 | -20989, -20989, -20989, -20989, -20989, 0, 0, 120 | ]; 121 | let mut sid = Sid::new(ChipModel::Mos6581); 122 | sid.enable_external_filter(false); 123 | sid.enable_filter(true); 124 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 125 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 126 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 127 | sid.write(0x18, (0x08 << 4) | 0x04); // MODE_VOL 128 | let res = dump(&mut sid, "filter_voice3_off", SAMPLE_COUNT); 129 | assert_eq!(res, expected); 130 | } 131 | 132 | #[test] 133 | fn filter_hp_lp_lp() { 134 | let expected: Vec = vec![ 135 | -21189, -21155, -21147, -21139, -20987, -20956, -20909, -20878, -20831, -20800, -20753, 136 | -20721, -20675, -20643, -20166, -20112, -20030, -19975, -19893, -19839, -19757, -19703, 137 | -19621, -19566, -19484, -19430, -19348, -19293, -19212, -19157, -19075, -19021, -18966, 138 | -18884, -18830, -18748, -18693, -18612, -18557, -18475, -18421, -18339, -18284, -18203, 139 | -18148, -18066, -18012, -17930, -17875, -17793, -19205, -17658, -17604, -17522, -17467, 140 | -17385, -17331, -17249, -17195, -17140, -17058, -17004, -16922, -16867, -16785, -16731, 141 | -16649, -16595, -16513, -16458, -18424, -18392, -18345, -18314, -16104, -16049, -15967, 142 | -15913, -15831, -15776, -15695, -15640, -15558, -15504, -15422, -15367, -15285, -15231, 143 | -15176, -15095, -15040, -14958, -14904, -14822, -14767, -14685, -14631, -14549, -14495, 144 | -14413, -14358, -17220, -14222, -14222, -14222, -14222, -14222, -14222, -14222, -14222, 145 | -14222, -14222, -14222, -14222, -17188, -17188, -17188, -17188, -17188, -17188, -17188, 146 | -17188, -17188, -17188, -17188, -17188, 0, 0, 147 | ]; 148 | let mut sid = Sid::new(ChipModel::Mos6581); 149 | sid.enable_external_filter(false); 150 | sid.enable_filter(true); 151 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 152 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 153 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 154 | sid.write(0x18, (0x07 << 4) | 0x04); // MODE_VOL 155 | let res = dump(&mut sid, "filter_hp_lp_lp", SAMPLE_COUNT); 156 | assert_eq!(res, expected); 157 | } 158 | 159 | #[test] 160 | fn filter_filt_15() { 161 | let expected: Vec = vec![ 162 | -29856, -29561, -29267, -28987, -28842, -28599, -28381, -28146, -27950, -27748, -27560, 163 | -27377, -27217, -27042, -27311, -27155, -27024, -26884, -26777, -26643, -26551, -26431, 164 | -26353, -26255, -26183, -26099, -26047, -25969, -25930, -25869, -25835, -25784, -25741, 165 | -25726, -25693, -25692, -25665, -25674, -25659, -25673, -25668, -25694, -25694, -25728, 166 | -25739, -25779, -25796, -25845, -25869, -25924, -24557, -26116, -26150, -26212, -26250, 167 | -26319, -26363, -26436, -26484, -26536, -26616, -26673, -26758, -26818, -26907, -26971, 168 | -27063, -27129, -27225, -27295, -25440, -25640, -25846, -26033, -28295, -28346, -28425, 169 | -28479, -28562, -28619, -28704, -28764, -28852, -28915, -29004, -29068, -29160, -29226, 170 | -29293, -29389, -29458, -29554, -29625, -29723, -29793, -29892, -29965, -30065, -30139, 171 | -30240, -30313, -27617, -30705, -30719, -30739, -30763, -30792, -30826, -30864, -30907, 172 | -30952, -31001, -31056, -31112, -28342, -28625, -28888, -29144, -29407, -29651, -29888, 173 | -30130, -30355, -30574, -30796, -31003, 0, 0, 174 | ]; 175 | let mut sid = Sid::new(ChipModel::Mos6581); 176 | sid.enable_external_filter(false); 177 | sid.enable_filter(true); 178 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 179 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 180 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 181 | sid.write(0x17, 0x0f); // RESFILT 182 | sid.write(0x18, (0x07 << 4) | 0x04); // MODE_VOL 183 | let res = dump(&mut sid, "filter_filt_15", SAMPLE_COUNT); 184 | assert_eq!(res, expected); 185 | } 186 | 187 | #[test] 188 | fn filter_res_15() { 189 | let expected: Vec = vec![ 190 | -21189, -21155, -21147, -21139, -20987, -20956, -20909, -20878, -20831, -20800, -20753, 191 | -20721, -20675, -20643, -20166, -20112, -20030, -19975, -19893, -19839, -19757, -19703, 192 | -19621, -19566, -19484, -19430, -19348, -19293, -19212, -19157, -19075, -19021, -18966, 193 | -18884, -18830, -18748, -18693, -18612, -18557, -18475, -18421, -18339, -18284, -18203, 194 | -18148, -18066, -18012, -17930, -17875, -17793, -19205, -17658, -17604, -17522, -17467, 195 | -17385, -17331, -17249, -17195, -17140, -17058, -17004, -16922, -16867, -16785, -16731, 196 | -16649, -16595, -16513, -16458, -18424, -18392, -18345, -18314, -16104, -16049, -15967, 197 | -15913, -15831, -15776, -15695, -15640, -15558, -15504, -15422, -15367, -15285, -15231, 198 | -15176, -15095, -15040, -14958, -14904, -14822, -14767, -14685, -14631, -14549, -14495, 199 | -14413, -14358, -17220, -14222, -14222, -14222, -14222, -14222, -14222, -14222, -14222, 200 | -14222, -14222, -14222, -14222, -17188, -17188, -17188, -17188, -17188, -17188, -17188, 201 | -17188, -17188, -17188, -17188, -17188, 0, 0, 202 | ]; 203 | let mut sid = Sid::new(ChipModel::Mos6581); 204 | sid.enable_external_filter(false); 205 | sid.enable_filter(true); 206 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 207 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 208 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 209 | sid.write(0x17, 0xf0); // RESFILT 210 | sid.write(0x18, (0x07 << 4) | 0x04); // MODE_VOL 211 | let res = dump(&mut sid, "filter_res_15", SAMPLE_COUNT); 212 | assert_eq!(res, expected); 213 | } 214 | 215 | #[test] 216 | fn filter_fc_255() { 217 | let expected: Vec = vec![ 218 | -21189, -21155, -21147, -21139, -20987, -20956, -20909, -20878, -20831, -20800, -20753, 219 | -20721, -20675, -20643, -20166, -20112, -20030, -19975, -19893, -19839, -19757, -19703, 220 | -19621, -19566, -19484, -19430, -19348, -19293, -19212, -19157, -19075, -19021, -18966, 221 | -18884, -18830, -18748, -18693, -18612, -18557, -18475, -18421, -18339, -18284, -18203, 222 | -18148, -18066, -18012, -17930, -17875, -17793, -19205, -17658, -17604, -17522, -17467, 223 | -17385, -17331, -17249, -17195, -17140, -17058, -17004, -16922, -16867, -16785, -16731, 224 | -16649, -16595, -16513, -16458, -18424, -18392, -18345, -18314, -16104, -16049, -15967, 225 | -15913, -15831, -15776, -15695, -15640, -15558, -15504, -15422, -15367, -15285, -15231, 226 | -15176, -15095, -15040, -14958, -14904, -14822, -14767, -14685, -14631, -14549, -14495, 227 | -14413, -14358, -17220, -14222, -14222, -14222, -14222, -14222, -14222, -14222, -14222, 228 | -14222, -14222, -14222, -14222, -17188, -17188, -17188, -17188, -17188, -17188, -17188, 229 | -17188, -17188, -17188, -17188, -17188, 0, 0, 230 | ]; 231 | let mut sid = Sid::new(ChipModel::Mos6581); 232 | sid.enable_external_filter(false); 233 | sid.enable_filter(true); 234 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 235 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 236 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 237 | sid.write(0x15, 0xff); // FCLO 238 | sid.write(0x18, (0x07 << 4) | 0x04); // MODE_VOL 239 | let res = dump(&mut sid, "filter_fc_255", SAMPLE_COUNT); 240 | assert_eq!(res, expected); 241 | } 242 | 243 | #[test] 244 | fn filter_fc_res_filt() { 245 | let expected: Vec = vec![ 246 | -29925, -29739, -29539, -29342, -29279, -29106, -28952, -28775, -28627, -28465, -28315, 247 | -28161, -28027, -27872, -28161, -28025, -27909, -27779, -27679, -27547, -27452, -27327, 248 | -27241, -27131, -27045, -26944, -26873, -26773, -26711, -26625, -26564, -26488, -26416, 249 | -26370, -26307, -26276, -26216, -26194, -26149, -26132, -26096, -26092, -26061, -26065, 250 | -26048, -26058, -26050, -26073, -26071, -26103, -24691, -26219, -26235, -26284, -26308, 251 | -26364, -26397, -26461, -26503, -26549, -26625, -26679, -26764, -26826, -26918, -26988, 252 | -27087, -27163, -27269, -27352, -25479, -25648, -25828, -25996, -28280, -28371, -28492, 253 | -28590, -28716, -28817, -28949, -29054, -29188, -29299, -29437, -29549, -29693, -29809, 254 | -29926, -30075, -30195, -30343, -30468, -30619, -30742, -30898, -31023, -31176, -31307, 255 | -31461, -31589, -28901, -32022, -32096, -32176, -32256, -32343, -32429, -32518, -32614, 256 | -32708, -32768, -32768, -32768, -30234, -30490, -30733, -30975, -31226, -31465, -31702, 257 | -31948, -32181, -32411, -32650, -32768, 0, 0, 258 | ]; 259 | let mut sid = Sid::new(ChipModel::Mos6581); 260 | sid.enable_external_filter(false); 261 | sid.enable_filter(true); 262 | setup(&mut sid, 0, 4, 0x19b1, 0x0200, 4); 263 | setup(&mut sid, 1, 4, 0x29b1, 0x0100, 4); 264 | setup(&mut sid, 2, 4, 0x39b1, 0x0050, 4); 265 | sid.write(0x15, 0xff); // FCLO 266 | sid.write(0x17, 0xff); // RESFILT 267 | sid.write(0x18, (0x07 << 4) | 0x04); // MODE_VOL 268 | let res = dump(&mut sid, "filter_fc_res_filt", SAMPLE_COUNT); 269 | assert_eq!(res, expected); 270 | } 271 | -------------------------------------------------------------------------------- /src/envelope.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | 8 | use bit_field::BitField; 9 | 10 | const RATE_COUNTER_MASK: u16 = 0x7fff; 11 | const RATE_COUNTER_MSB_MASK: u16 = 0x8000; 12 | 13 | // Rate counter periods are calculated from the Envelope Rates table in 14 | // the Programmer's Reference Guide. The rate counter period is the number of 15 | // cycles between each increment of the envelope counter. 16 | // The rates have been verified by sampling ENV3. 17 | // 18 | // The rate counter is a 16 bit register which is incremented each cycle. 19 | // When the counter reaches a specific comparison value, the envelope counter 20 | // is incremented (attack) or decremented (decay/release) and the 21 | // counter is zeroed. 22 | // 23 | // NB! Sampling ENV3 shows that the calculated values are not exact. 24 | // It may seem like most calculated values have been rounded (.5 is rounded 25 | // down) and 1 has beed added to the result. A possible explanation for this 26 | // is that the SID designers have used the calculated values directly 27 | // as rate counter comparison values, not considering a one cycle delay to 28 | // zero the counter. This would yield an actual period of comparison value + 1. 29 | // 30 | // The time of the first envelope count can not be exactly controlled, except 31 | // possibly by resetting the chip. Because of this we cannot do cycle exact 32 | // sampling and must devise another method to calculate the rate counter 33 | // periods. 34 | // 35 | // The exact rate counter periods can be determined e.g. by counting the number 36 | // of cycles from envelope level 1 to envelope level 129, and dividing the 37 | // number of cycles by 128. CIA1 timer A and B in linked mode can perform 38 | // the cycle count. This is the method used to find the rates below. 39 | // 40 | // To avoid the ADSR delay bug, sampling of ENV3 should be done using 41 | // sustain = release = 0. This ensures that the attack state will not lower 42 | // the current rate counter period. 43 | // 44 | // The ENV3 sampling code below yields a maximum timing error of 14 cycles. 45 | // lda #$01 46 | // l1: cmp $d41c 47 | // bne l1 48 | // ... 49 | // lda #$ff 50 | // l2: cmp $d41c 51 | // bne l2 52 | // 53 | // This yields a maximum error for the calculated rate period of 14/128 cycles. 54 | // The described method is thus sufficient for exact calculation of the rate 55 | // periods. 56 | // 57 | static RATE_COUNTER_PERIOD: [u16; 16] = [ 58 | 9, // 2ms*1.0MHz/256 = 7.81 59 | 32, // 8ms*1.0MHz/256 = 31.25 60 | 63, // 16ms*1.0MHz/256 = 62.50 61 | 95, // 24ms*1.0MHz/256 = 93.75 62 | 149, // 38ms*1.0MHz/256 = 148.44 63 | 220, // 56ms*1.0MHz/256 = 218.75 64 | 267, // 68ms*1.0MHz/256 = 265.63 65 | 313, // 80ms*1.0MHz/256 = 312.50 66 | 392, // 100ms*1.0MHz/256 = 390.63 67 | 977, // 250ms*1.0MHz/256 = 976.56 68 | 1954, // 500ms*1.0MHz/256 = 1953.13 69 | 3126, // 800ms*1.0MHz/256 = 3125.00 70 | 3907, // 1 s*1.0MHz/256 = 3906.25 71 | 11720, // 3 s*1.0MHz/256 = 11718.75 72 | 19532, // 5 s*1.0MHz/256 = 19531.25 73 | 31251, // 8 s*1.0MHz/256 = 31250.00 74 | ]; 75 | 76 | /// From the sustain levels it follows that both the low and high 4 bits of the 77 | /// envelope counter are compared to the 4-bit sustain value. 78 | /// This has been verified by sampling ENV3. 79 | static SUSTAIN_LEVEL: [u8; 16] = [ 80 | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 81 | ]; 82 | 83 | #[derive(Clone, Copy, PartialEq)] 84 | pub enum State { 85 | Attack, 86 | DecaySustain, 87 | Release, 88 | } 89 | 90 | /// A 15 bit counter is used to implement the envelope rates, in effect 91 | /// dividing the clock to the envelope counter by the currently selected rate 92 | /// period. 93 | /// In addition, another counter is used to implement the exponential envelope 94 | /// decay, in effect further dividing the clock to the envelope counter. 95 | /// The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope 96 | /// counter values 255, 93, 54, 26, 14, 6, respectively. 97 | #[derive(Clone, Copy)] 98 | pub struct EnvelopeGenerator { 99 | // Configuration 100 | attack: u8, 101 | decay: u8, 102 | sustain: u8, 103 | release: u8, 104 | // Control 105 | gate: bool, 106 | // Runtime State 107 | pub state: State, 108 | pub envelope_counter: u8, 109 | pub exponential_counter: u8, 110 | pub exponential_counter_period: u8, 111 | pub hold_zero: bool, 112 | pub rate_counter: u16, 113 | pub rate_counter_period: u16, 114 | } 115 | 116 | impl Default for EnvelopeGenerator { 117 | fn default() -> Self { 118 | let mut envelope = EnvelopeGenerator { 119 | attack: 0, 120 | decay: 0, 121 | sustain: 0, 122 | release: 0, 123 | gate: false, 124 | state: State::Release, 125 | envelope_counter: 0, 126 | exponential_counter: 0, 127 | exponential_counter_period: 0, 128 | hold_zero: false, 129 | rate_counter: 0, 130 | rate_counter_period: 0, 131 | }; 132 | envelope.reset(); 133 | envelope 134 | } 135 | } 136 | 137 | impl EnvelopeGenerator { 138 | pub fn get_attack_decay(&self) -> u8 { 139 | self.attack << 4 | self.decay 140 | } 141 | 142 | pub fn get_control(&self) -> u8 { 143 | let mut value = 0u8; 144 | value.set_bit(0, self.gate); 145 | value 146 | } 147 | 148 | pub fn get_sustain_release(&self) -> u8 { 149 | self.sustain << 4 | self.release 150 | } 151 | 152 | pub fn set_attack_decay(&mut self, value: u8) { 153 | self.attack = (value >> 4) & 0x0f; 154 | self.decay = value & 0x0f; 155 | match self.state { 156 | State::Attack => self.rate_counter_period = RATE_COUNTER_PERIOD[self.attack as usize], 157 | State::DecaySustain => { 158 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.decay as usize] 159 | } 160 | _ => {} 161 | } 162 | } 163 | 164 | pub fn set_control(&mut self, value: u8) { 165 | let gate = value.get_bit(0); 166 | if !self.gate && gate { 167 | // Gate bit on: Start attack, decay, sustain. 168 | self.state = State::Attack; 169 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.attack as usize]; 170 | // Switching to attack state unlocks the zero freeze. 171 | self.hold_zero = false; 172 | } else if self.gate && !gate { 173 | // Gate bit off: Start release. 174 | self.state = State::Release; 175 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.release as usize]; 176 | } 177 | self.gate = gate; 178 | } 179 | 180 | pub fn set_sustain_release(&mut self, value: u8) { 181 | self.sustain = (value >> 4) & 0x0f; 182 | self.release = value & 0x0f; 183 | if self.state == State::Release { 184 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.release as usize]; 185 | } 186 | } 187 | 188 | #[inline] 189 | pub fn clock(&mut self) { 190 | // Check for ADSR delay bug. 191 | // If the rate counter comparison value is set below the current value of the 192 | // rate counter, the counter will continue counting up until it wraps around 193 | // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the 194 | // envelope can finally be stepped. 195 | // This has been verified by sampling ENV3. 196 | self.rate_counter += 1; 197 | if self.rate_counter & RATE_COUNTER_MSB_MASK != 0 { 198 | self.rate_counter += 1; 199 | self.rate_counter &= RATE_COUNTER_MASK; 200 | } 201 | if self.rate_counter == self.rate_counter_period { 202 | self.rate_counter = 0; 203 | // The first envelope step in the attack state also resets the exponential 204 | // counter. This has been verified by sampling ENV3. 205 | self.exponential_counter += 1; // TODO check w/ ref impl 206 | if self.state == State::Attack 207 | || self.exponential_counter == self.exponential_counter_period 208 | { 209 | self.exponential_counter = 0; 210 | // Check whether the envelope counter is frozen at zero. 211 | if self.hold_zero { 212 | return; 213 | } 214 | match self.state { 215 | State::Attack => { 216 | // The envelope counter can flip from 0xff to 0x00 by changing state to 217 | // release, then to attack. The envelope counter is then frozen at 218 | // zero; to unlock this situation the state must be changed to release, 219 | // then to attack. This has been verified by sampling ENV3. 220 | self.envelope_counter += 1; 221 | if self.envelope_counter == 0xff { 222 | self.state = State::DecaySustain; 223 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.decay as usize]; 224 | } 225 | } 226 | State::DecaySustain => { 227 | if self.envelope_counter != SUSTAIN_LEVEL[self.sustain as usize] { 228 | self.envelope_counter -= 1; 229 | } 230 | } 231 | State::Release => { 232 | // The envelope counter can flip from 0x00 to 0xff by changing state to 233 | // attack, then to release. The envelope counter will then continue 234 | // counting down in the release state. 235 | // This has been verified by sampling ENV3. 236 | // NB! The operation below requires two's complement integer. 237 | self.envelope_counter -= 1; 238 | } 239 | } 240 | // Check for change of exponential counter period. 241 | match self.envelope_counter { 242 | 0xff => self.exponential_counter_period = 1, 243 | 0x5d => self.exponential_counter_period = 2, 244 | 0x36 => self.exponential_counter_period = 4, 245 | 0x1a => self.exponential_counter_period = 8, 246 | 0x0e => self.exponential_counter_period = 16, 247 | 0x06 => self.exponential_counter_period = 30, 248 | 0x00 => { 249 | self.exponential_counter_period = 1; 250 | // When the envelope counter is changed to zero, it is frozen at zero. 251 | // This has been verified by sampling ENV3. 252 | self.hold_zero = true; 253 | } 254 | _ => {} 255 | } 256 | } 257 | } 258 | } 259 | 260 | #[inline] 261 | pub fn clock_delta(&mut self, mut delta: u32) { 262 | // NB! This requires two's complement integer. 263 | let mut rate_step = self.rate_counter_period as i32 - self.rate_counter as i32; 264 | if rate_step <= 0 { 265 | rate_step += 0x7fff; 266 | } 267 | while delta != 0 { 268 | if delta < rate_step as u32 { 269 | self.rate_counter += delta as u16; 270 | if self.rate_counter & RATE_COUNTER_MSB_MASK != 0 { 271 | self.rate_counter += 1; 272 | self.rate_counter &= RATE_COUNTER_MASK; 273 | } 274 | return; 275 | } 276 | self.rate_counter = 0; 277 | delta -= rate_step as u32; 278 | // The first envelope step in the attack state also resets the exponential 279 | // counter. This has been verified by sampling ENV3. 280 | self.exponential_counter += 1; // TODO check w/ ref impl 281 | if self.state == State::Attack 282 | || self.exponential_counter == self.exponential_counter_period 283 | { 284 | self.exponential_counter = 0; 285 | // Check whether the envelope counter is frozen at zero. 286 | if self.hold_zero { 287 | rate_step = self.rate_counter_period as i32; 288 | continue; 289 | } 290 | match self.state { 291 | State::Attack => { 292 | // The envelope counter can flip from 0xff to 0x00 by changing state to 293 | // release, then to attack. The envelope counter is then frozen at 294 | // zero; to unlock this situation the state must be changed to release, 295 | // then to attack. This has been verified by sampling ENV3. 296 | self.envelope_counter += 1; 297 | if self.envelope_counter == 0xff { 298 | self.state = State::DecaySustain; 299 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.decay as usize]; 300 | } 301 | } 302 | State::DecaySustain => { 303 | if self.envelope_counter != SUSTAIN_LEVEL[self.sustain as usize] { 304 | self.envelope_counter -= 1; 305 | } 306 | } 307 | State::Release => { 308 | // The envelope counter can flip from 0x00 to 0xff by changing state to 309 | // attack, then to release. The envelope counter will then continue 310 | // counting down in the release state. 311 | // This has been verified by sampling ENV3. 312 | // NB! The operation below requires two's complement integer. 313 | self.envelope_counter -= 1; 314 | } 315 | } 316 | // Check for change of exponential counter period. 317 | match self.envelope_counter { 318 | 0xff => self.exponential_counter_period = 1, 319 | 0x5d => self.exponential_counter_period = 2, 320 | 0x36 => self.exponential_counter_period = 4, 321 | 0x1a => self.exponential_counter_period = 8, 322 | 0x0e => self.exponential_counter_period = 16, 323 | 0x06 => self.exponential_counter_period = 30, 324 | 0x00 => { 325 | self.exponential_counter_period = 1; 326 | // When the envelope counter is changed to zero, it is frozen at zero. 327 | // This has been verified by sampling ENV3. 328 | self.hold_zero = true; 329 | } 330 | _ => {} 331 | } 332 | } 333 | rate_step = self.rate_counter_period as i32; 334 | } 335 | } 336 | 337 | #[inline] 338 | pub fn output(&self) -> u8 { 339 | self.envelope_counter 340 | } 341 | 342 | pub fn read_env(&self) -> u8 { 343 | self.output() 344 | } 345 | 346 | pub fn reset(&mut self) { 347 | self.attack = 0; 348 | self.decay = 0; 349 | self.sustain = 0; 350 | self.release = 0; 351 | self.gate = false; 352 | self.state = State::Release; 353 | self.envelope_counter = 0; 354 | self.exponential_counter = 0; 355 | self.exponential_counter_period = 1; 356 | self.hold_zero = true; 357 | self.rate_counter = 0; 358 | self.rate_counter_period = RATE_COUNTER_PERIOD[self.release as usize]; 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /src/filter.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | 8 | use core::f64; 9 | 10 | use super::data::{SPLINE6581_F0, SPLINE8580_F0}; 11 | use super::ChipModel; 12 | 13 | const MIXER_DC: i32 = (-0xfff * 0xff / 18) >> 7; 14 | 15 | /// The SID filter is modeled with a two-integrator-loop biquadratic filter, 16 | /// which has been confirmed by Bob Yannes to be the actual circuit used in 17 | /// the SID chip. 18 | /// 19 | /// Measurements show that excellent emulation of the SID filter is achieved, 20 | /// except when high resonance is combined with high sustain levels. 21 | /// In this case the SID op-amps are performing less than ideally and are 22 | /// causing some peculiar behavior of the SID filter. This however seems to 23 | /// have more effect on the overall amplitude than on the color of the sound. 24 | /// 25 | /// The theory for the filter circuit can be found in "Microelectric Circuits" 26 | /// by Adel S. Sedra and Kenneth C. Smith. 27 | /// The circuit is modeled based on the explanation found there except that 28 | /// an additional inverter is used in the feedback from the bandpass output, 29 | /// allowing the summer op-amp to operate in single-ended mode. This yields 30 | /// inverted filter outputs with levels independent of Q, which corresponds with 31 | /// the results obtained from a real SID. 32 | /// 33 | /// We have been able to model the summer and the two integrators of the circuit 34 | /// to form components of an IIR filter. 35 | /// Vhp is the output of the summer, Vbp is the output of the first integrator, 36 | /// and Vlp is the output of the second integrator in the filter circuit. 37 | /// 38 | /// According to Bob Yannes, the active stages of the SID filter are not really 39 | /// op-amps. Rather, simple NMOS inverters are used. By biasing an inverter 40 | /// into its region of quasi-linear operation using a feedback resistor from 41 | /// input to output, a MOS inverter can be made to act like an op-amp for 42 | /// small signals centered around the switching threshold. 43 | #[derive(Clone, Copy)] 44 | pub struct Filter { 45 | // Configuration 46 | enabled: bool, 47 | fc: u16, 48 | filt: u8, 49 | res: u8, 50 | // Mode 51 | voice3_off: bool, 52 | hp_bp_lp: u8, 53 | vol: u8, 54 | // Runtime State 55 | pub vhp: i32, 56 | pub vbp: i32, 57 | pub vlp: i32, 58 | pub vnf: i32, 59 | // Cutoff Freq/Res 60 | mixer_dc: i32, 61 | q_1024_div: i32, 62 | w0: i32, 63 | w0_ceil_1: i32, 64 | w0_ceil_dt: i32, 65 | // Cutoff Freq Tables 66 | f0: &'static [i16; 2048], 67 | } 68 | 69 | impl Filter { 70 | pub fn new(chip_model: ChipModel) -> Self { 71 | let f0 = match chip_model { 72 | ChipModel::Mos6581 => &SPLINE6581_F0, 73 | ChipModel::Mos8580 => &SPLINE8580_F0, 74 | }; 75 | let mut filter = Filter { 76 | enabled: true, 77 | fc: 0, 78 | filt: 0, 79 | res: 0, 80 | voice3_off: false, 81 | hp_bp_lp: 0, 82 | vol: 0, 83 | vhp: 0, 84 | vbp: 0, 85 | vlp: 0, 86 | vnf: 0, 87 | mixer_dc: MIXER_DC, 88 | q_1024_div: 0, 89 | w0: 0, 90 | w0_ceil_1: 0, 91 | w0_ceil_dt: 0, 92 | f0, 93 | }; 94 | filter.set_q(); 95 | filter.set_w0(); 96 | filter 97 | } 98 | 99 | pub fn get_fc_hi(&self) -> u8 { 100 | (self.fc >> 3) as u8 101 | } 102 | 103 | pub fn get_fc_lo(&self) -> u8 { 104 | (self.fc & 0x007) as u8 105 | } 106 | 107 | pub fn get_mode_vol(&self) -> u8 { 108 | let value = if self.voice3_off { 0x80 } else { 0 }; 109 | value | (self.hp_bp_lp << 4) | (self.vol & 0x0f) 110 | } 111 | 112 | pub fn get_res_filt(&self) -> u8 { 113 | (self.res << 4) | (self.filt & 0x0f) 114 | } 115 | 116 | pub fn set_enabled(&mut self, enabled: bool) { 117 | self.enabled = enabled; 118 | } 119 | 120 | pub fn set_fc_hi(&mut self, value: u8) { 121 | let result = ((value as u16) << 3) & 0x7f8 | self.fc & 0x007; 122 | self.fc = result; 123 | self.set_w0(); 124 | } 125 | 126 | pub fn set_fc_lo(&mut self, value: u8) { 127 | let result = self.fc & 0x7f8 | (value as u16) & 0x007; 128 | self.fc = result; 129 | self.set_w0(); 130 | } 131 | 132 | pub fn set_mode_vol(&mut self, value: u8) { 133 | self.voice3_off = value & 0x80 != 0; 134 | self.hp_bp_lp = (value >> 4) & 0x07; 135 | self.vol = value & 0x0f; 136 | } 137 | 138 | pub fn set_res_filt(&mut self, value: u8) { 139 | self.res = (value >> 4) & 0x0f; 140 | self.filt = value & 0x0f; 141 | self.set_q(); 142 | } 143 | 144 | #[inline] 145 | pub fn clock(&mut self, mut voice1: i32, mut voice2: i32, mut voice3: i32, mut ext_in: i32) { 146 | // Scale each voice down from 20 to 13 bits. 147 | voice1 >>= 7; 148 | voice2 >>= 7; 149 | // NB! Voice 3 is not silenced by voice3off if it is routed through 150 | // the filter. 151 | voice3 = if self.voice3_off && self.filt & 0x04 == 0 { 152 | 0 153 | } else { 154 | voice3 >> 7 155 | }; 156 | ext_in >>= 7; 157 | 158 | // This is handy for testing. 159 | if !self.enabled { 160 | self.vnf = voice1 + voice2 + voice3 + ext_in; 161 | self.vhp = 0; 162 | self.vbp = 0; 163 | self.vlp = 0; 164 | return; 165 | } 166 | 167 | // Route voices into or around filter. 168 | // The code below is expanded to a switch for faster execution. 169 | // (filt1 ? Vi : Vnf) += voice1; 170 | // (filt2 ? Vi : Vnf) += voice2; 171 | // (filt3 ? Vi : Vnf) += voice3; 172 | let vi = match self.filt { 173 | 0x0 => { 174 | self.vnf = voice1 + voice2 + voice3 + ext_in; 175 | 0 176 | } 177 | 0x1 => { 178 | self.vnf = voice2 + voice3 + ext_in; 179 | voice1 180 | } 181 | 0x2 => { 182 | self.vnf = voice1 + voice3 + ext_in; 183 | voice2 184 | } 185 | 0x3 => { 186 | self.vnf = voice3 + ext_in; 187 | voice1 + voice2 188 | } 189 | 0x4 => { 190 | self.vnf = voice1 + voice2 + ext_in; 191 | voice3 192 | } 193 | 0x5 => { 194 | self.vnf = voice2 + ext_in; 195 | voice1 + voice3 196 | } 197 | 0x6 => { 198 | self.vnf = voice1 + ext_in; 199 | voice2 + voice3 200 | } 201 | 0x7 => { 202 | self.vnf = ext_in; 203 | voice1 + voice2 + voice3 204 | } 205 | 0x8 => { 206 | self.vnf = voice1 + voice2 + voice3; 207 | ext_in 208 | } 209 | 0x9 => { 210 | self.vnf = voice2 + voice3; 211 | voice1 + ext_in 212 | } 213 | 0xa => { 214 | self.vnf = voice1 + voice3; 215 | voice2 + ext_in 216 | } 217 | 0xb => { 218 | self.vnf = voice3; 219 | voice1 + voice2 + ext_in 220 | } 221 | 0xc => { 222 | self.vnf = voice1 + voice2; 223 | voice3 + ext_in 224 | } 225 | 0xd => { 226 | self.vnf = voice2; 227 | voice1 + voice3 + ext_in 228 | } 229 | 0xe => { 230 | self.vnf = voice1; 231 | voice2 + voice3 + ext_in 232 | } 233 | 0xf => { 234 | self.vnf = 0; 235 | voice1 + voice2 + voice3 + ext_in 236 | } 237 | _ => { 238 | self.vnf = voice1 + voice2 + voice3 + ext_in; 239 | 0 240 | } 241 | }; 242 | 243 | // delta_t = 1 is converted to seconds given a 1MHz clock by dividing 244 | // with 1 000 000. 245 | 246 | // Calculate filter outputs. 247 | // Vhp = Vbp/Q - Vlp - Vi; 248 | // dVbp = -w0*Vhp*dt; 249 | // dVlp = -w0*Vbp*dt; 250 | let dvbp = (self.w0_ceil_1 * self.vhp) >> 20; 251 | let dvlp = (self.w0_ceil_1 * self.vbp) >> 20; 252 | self.vbp -= dvbp; 253 | self.vlp -= dvlp; 254 | self.vhp = ((self.vbp * self.q_1024_div) >> 10) - self.vlp - vi; 255 | } 256 | 257 | #[inline] 258 | pub fn clock_delta( 259 | &mut self, 260 | mut delta: u32, 261 | mut voice1: i32, 262 | mut voice2: i32, 263 | mut voice3: i32, 264 | mut ext_in: i32, 265 | ) { 266 | // Scale each voice down from 20 to 13 bits. 267 | voice1 >>= 7; 268 | voice2 >>= 7; 269 | if self.voice3_off && self.filt & 0x04 == 0 { 270 | voice3 = 0; 271 | } else { 272 | voice3 >>= 7; 273 | } 274 | ext_in >>= 7; 275 | // Enable filter on/off. 276 | // This is not really part of SID, but is useful for testing. 277 | // On slow CPUs it may be necessary to bypass the filter to lower the CPU 278 | // load. 279 | if !self.enabled { 280 | self.vnf = voice1 + voice2 + voice3 + ext_in; 281 | self.vhp = 0; 282 | self.vbp = 0; 283 | self.vlp = 0; 284 | return; 285 | } 286 | 287 | // Route voices into or around filter. 288 | // The code below is expanded to a switch for faster execution. 289 | // (filt1 ? Vi : Vnf) += voice1; 290 | // (filt2 ? Vi : Vnf) += voice2; 291 | // (filt3 ? Vi : Vnf) += voice3; 292 | let vi = match self.filt { 293 | 0x0 => { 294 | self.vnf = voice1 + voice2 + voice3 + ext_in; 295 | 0 296 | } 297 | 0x1 => { 298 | self.vnf = voice2 + voice3 + ext_in; 299 | voice1 300 | } 301 | 0x2 => { 302 | self.vnf = voice1 + voice3 + ext_in; 303 | voice2 304 | } 305 | 0x3 => { 306 | self.vnf = voice3 + ext_in; 307 | voice1 + voice2 308 | } 309 | 0x4 => { 310 | self.vnf = voice1 + voice2 + ext_in; 311 | voice3 312 | } 313 | 0x5 => { 314 | self.vnf = voice2 + ext_in; 315 | voice1 + voice3 316 | } 317 | 0x6 => { 318 | self.vnf = voice1 + ext_in; 319 | voice2 + voice3 320 | } 321 | 0x7 => { 322 | self.vnf = ext_in; 323 | voice1 + voice2 + voice3 324 | } 325 | 0x8 => { 326 | self.vnf = voice1 + voice2 + voice3; 327 | ext_in 328 | } 329 | 0x9 => { 330 | self.vnf = voice2 + voice3; 331 | voice1 + ext_in 332 | } 333 | 0xa => { 334 | self.vnf = voice1 + voice3; 335 | voice2 + ext_in 336 | } 337 | 0xb => { 338 | self.vnf = voice3; 339 | voice1 + voice2 + ext_in 340 | } 341 | 0xc => { 342 | self.vnf = voice1 + voice2; 343 | voice3 + ext_in 344 | } 345 | 0xd => { 346 | self.vnf = voice2; 347 | voice1 + voice3 + ext_in 348 | } 349 | 0xe => { 350 | self.vnf = voice1; 351 | voice2 + voice3 + ext_in 352 | } 353 | 0xf => { 354 | self.vnf = 0; 355 | voice1 + voice2 + voice3 + ext_in 356 | } 357 | _ => { 358 | self.vnf = voice1 + voice2 + voice3 + ext_in; 359 | 0 360 | } 361 | }; 362 | 363 | // Maximum delta cycles for the filter to work satisfactorily under current 364 | // cutoff frequency and resonance constraints is approximately 8. 365 | let mut delta_flt = 8; 366 | 367 | while delta != 0 { 368 | if delta < delta_flt { 369 | delta_flt = delta; 370 | } 371 | // delta_t is converted to seconds given a 1MHz clock by dividing 372 | // with 1 000 000. This is done in two operations to avoid integer 373 | // multiplication overflow. 374 | 375 | // Calculate filter outputs. 376 | // Vhp = Vbp/Q - Vlp - Vi; 377 | // dVbp = -w0*Vhp*dt; 378 | // dVlp = -w0*Vbp*dt; 379 | let w0_delta_t = (self.w0_ceil_dt * delta_flt as i32) >> 6; 380 | let dvbp = (w0_delta_t * self.vhp) >> 14; 381 | let dvlp = (w0_delta_t * self.vbp) >> 14; 382 | self.vbp -= dvbp; 383 | self.vlp -= dvlp; 384 | self.vhp = ((self.vbp * self.q_1024_div) >> 10) - self.vlp - vi; 385 | 386 | delta -= delta_flt; 387 | } 388 | } 389 | 390 | #[inline] 391 | pub fn output(&self) -> i32 { 392 | // This is handy for testing. 393 | if !self.enabled { 394 | (self.vnf + self.mixer_dc) * self.vol as i32 395 | } else { 396 | // Mix highpass, bandpass, and lowpass outputs. The sum is not 397 | // weighted, this can be confirmed by sampling sound output for 398 | // e.g. bandpass, lowpass, and bandpass+lowpass from a SID chip. 399 | // The code below is expanded to a switch for faster execution. 400 | // if (hp) Vf += Vhp; 401 | // if (bp) Vf += Vbp; 402 | // if (lp) Vf += Vlp; 403 | let vf = match self.hp_bp_lp { 404 | 0x0 => 0, 405 | 0x1 => self.vlp, 406 | 0x2 => self.vbp, 407 | 0x3 => self.vlp + self.vbp, 408 | 0x4 => self.vhp, 409 | 0x5 => self.vlp + self.vhp, 410 | 0x6 => self.vbp + self.vhp, 411 | 0x7 => self.vlp + self.vbp + self.vhp, 412 | _ => 0, 413 | }; 414 | // Sum non-filtered and filtered output. 415 | // Multiply the sum with volume. 416 | (self.vnf + vf + self.mixer_dc) * self.vol as i32 417 | } 418 | } 419 | 420 | pub fn reset(&mut self) { 421 | self.fc = 0; 422 | self.filt = 0; 423 | self.res = 0; 424 | self.voice3_off = false; 425 | self.hp_bp_lp = 0; 426 | self.vol = 0; 427 | self.vhp = 0; 428 | self.vbp = 0; 429 | self.vlp = 0; 430 | self.vnf = 0; 431 | self.set_w0(); 432 | self.set_q(); 433 | } 434 | 435 | fn set_q(&mut self) { 436 | // Q is controlled linearly by res. Q has approximate range [0.707, 1.7]. 437 | // As resonance is increased, the filter must be clocked more often to keep 438 | // stable. 439 | 440 | // The coefficient 1024 is dispensed of later by right-shifting 10 times 441 | // (2 ^ 10 = 1024). 442 | self.q_1024_div = (1024.0 / (0.707 + 1.0 * self.res as f64 / 15.0)) as i32; 443 | } 444 | 445 | fn set_w0(&mut self) { 446 | // Multiply with 1.048576 to facilitate division by 1 000 000 by right- 447 | // shifting 20 times (2 ^ 20 = 1048576). 448 | self.w0 = (2.0 * f64::consts::PI * self.f0[self.fc as usize] as f64 * 1.048_576) as i32; 449 | 450 | // Limit f0 to 16kHz to keep 1 cycle filter stable. 451 | let w0_max_1 = (2.0 * f64::consts::PI * 16000.0 * 1.048_576) as i32; 452 | self.w0_ceil_1 = if self.w0 <= w0_max_1 { 453 | self.w0 454 | } else { 455 | w0_max_1 456 | }; 457 | 458 | // Limit f0 to 4kHz to keep delta_t cycle filter stable. 459 | let w0_max_dt = (2.0 * f64::consts::PI * 4000.0 * 1.048_576) as i32; 460 | self.w0_ceil_dt = if self.w0 <= w0_max_dt { 461 | self.w0 462 | } else { 463 | w0_max_dt 464 | }; 465 | } 466 | } 467 | -------------------------------------------------------------------------------- /src/sampler.rs: -------------------------------------------------------------------------------- 1 | // This file is part of resid-rs. 2 | // Copyright (c) 2017-2019 Sebastian Jastrzebski . All rights reserved. 3 | // Portions (c) 2004 Dag Lem 4 | // Licensed under the GPLv3. See LICENSE file in the project root for full license text. 5 | 6 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] 7 | #![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))] 8 | 9 | use core::f64; 10 | 11 | #[cfg(feature = "alloc")] 12 | use alloc::vec::Vec; 13 | 14 | #[cfg(not(feature = "std"))] 15 | use libm::F64Ext; 16 | 17 | #[cfg(not(feature = "std"))] 18 | use super::math; 19 | use super::synth::Synth; 20 | 21 | // Resampling constants. 22 | // The error in interpolated lookup is bounded by 1.234/L^2, 23 | // while the error in non-interpolated lookup is bounded by 24 | // 0.7854/L + 0.4113/L^2, see 25 | // http://www-ccrma.stanford.edu/~jos/resample/Choice_Table_Size.html 26 | // For a resolution of 16 bits this yields L >= 285 and L >= 51473, 27 | // respectively. 28 | const FIR_RES_FAST: i32 = 51473; 29 | const FIR_RES_INTERPOLATE: i32 = 285; 30 | const FIR_SHIFT: i32 = 15; 31 | const RING_SIZE: usize = 16384; 32 | 33 | const FIXP_SHIFT: i32 = 16; 34 | const FIXP_MASK: i32 = 0xffff; 35 | 36 | #[derive(Clone, Copy, PartialEq)] 37 | pub enum SamplingMethod { 38 | Fast, 39 | Interpolate, 40 | #[cfg(feature = "alloc")] 41 | Resample, 42 | #[cfg(feature = "alloc")] 43 | ResampleFast, 44 | } 45 | 46 | #[derive(Clone)] 47 | struct Fir { 48 | data: Vec, 49 | n: i32, 50 | res: i32, 51 | } 52 | 53 | #[derive(Clone)] 54 | pub struct Sampler { 55 | // Dependencies 56 | pub synth: Synth, 57 | // Configuration 58 | cycles_per_sample: u32, 59 | #[cfg(feature = "alloc")] 60 | fir: Fir, 61 | sampling_method: SamplingMethod, 62 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 63 | use_sse42: bool, 64 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 65 | use_avx2: bool, 66 | // Runtime State 67 | buffer: [i16; RING_SIZE * 2], 68 | index: usize, 69 | offset: i32, 70 | prev_sample: i16, 71 | } 72 | 73 | impl Sampler { 74 | pub fn new(synth: Synth) -> Self { 75 | Sampler { 76 | synth, 77 | cycles_per_sample: 0, 78 | #[cfg(feature = "alloc")] 79 | fir: Fir { 80 | data: Vec::new(), 81 | n: 0, 82 | res: 0, 83 | }, 84 | sampling_method: SamplingMethod::Fast, 85 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 86 | use_avx2: alloc::is_x86_feature_detected!("avx2"), 87 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 88 | use_sse42: alloc::is_x86_feature_detected!("sse4.2"), 89 | buffer: [0; RING_SIZE * 2], 90 | index: 0, 91 | offset: 0, 92 | prev_sample: 0, 93 | } 94 | } 95 | 96 | pub fn set_parameters(&mut self, method: SamplingMethod, clock_freq: u32, sample_freq: u32) { 97 | self.cycles_per_sample = 98 | (clock_freq as f64 / sample_freq as f64 * (1 << FIXP_SHIFT) as f64 + 0.5) as u32; 99 | self.sampling_method = method; 100 | 101 | #[cfg(feature = "alloc")] 102 | if self.sampling_method == SamplingMethod::Resample 103 | || self.sampling_method == SamplingMethod::ResampleFast 104 | { 105 | self.init_fir(clock_freq as f64, sample_freq as f64, -1.0, 0.97); 106 | } 107 | // Clear state 108 | for j in 0..RING_SIZE * 2 { 109 | self.buffer[j] = 0; 110 | } 111 | self.index = 0; 112 | self.offset = 0; 113 | self.prev_sample = 0; 114 | } 115 | 116 | pub fn reset(&mut self) { 117 | self.synth.reset(); 118 | self.index = 0; 119 | self.offset = 0; 120 | self.prev_sample = 0; 121 | } 122 | 123 | #[inline] 124 | pub fn clock(&mut self, delta: u32, buffer: &mut [i16], interleave: usize) -> (usize, u32) { 125 | match self.sampling_method { 126 | SamplingMethod::Fast => self.clock_fast(delta, buffer, interleave), 127 | SamplingMethod::Interpolate => self.clock_interpolate(delta, buffer, interleave), 128 | #[cfg(feature = "alloc")] 129 | SamplingMethod::Resample => self.clock_resample_interpolate(delta, buffer, interleave), 130 | #[cfg(feature = "alloc")] 131 | SamplingMethod::ResampleFast => self.clock_resample_fast(delta, buffer, interleave), 132 | } 133 | } 134 | 135 | /// SID clocking with audio sampling - delta clocking picking nearest sample. 136 | #[inline] 137 | fn clock_fast( 138 | &mut self, 139 | mut delta: u32, 140 | buffer: &mut [i16], 141 | interleave: usize, 142 | ) -> (usize, u32) { 143 | let mut index = 0; 144 | loop { 145 | let next_sample_offset = self.get_next_sample_offset(); 146 | let delta_sample = (next_sample_offset >> FIXP_SHIFT) as u32; 147 | if delta_sample > delta || index >= buffer.len() { 148 | break; 149 | } 150 | self.synth.clock_delta(delta_sample); 151 | delta -= delta_sample; 152 | buffer[(index * interleave) as usize] = self.synth.output(); 153 | index += 1; 154 | self.update_sample_offset(next_sample_offset); 155 | } 156 | if delta > 0 && index < buffer.len() { 157 | self.synth.clock_delta(delta); 158 | self.offset -= (delta as i32) << FIXP_SHIFT; 159 | (index, 0) 160 | } else { 161 | (index, delta) 162 | } 163 | } 164 | 165 | #[inline] 166 | fn clock_interpolate( 167 | &mut self, 168 | mut delta: u32, 169 | buffer: &mut [i16], 170 | interleave: usize, 171 | ) -> (usize, u32) { 172 | let mut index = 0; 173 | loop { 174 | let next_sample_offset = self.get_next_sample_offset(); 175 | let delta_sample = (next_sample_offset >> FIXP_SHIFT) as u32; 176 | if delta_sample > delta || index >= buffer.len() { 177 | break; 178 | } 179 | for _i in 0..(delta_sample - 1) { 180 | self.prev_sample = self.synth.output(); 181 | self.synth.clock(); 182 | } 183 | delta -= delta_sample; 184 | let sample_now = self.synth.output(); 185 | buffer[index * interleave] = self.prev_sample 186 | + ((self.offset * (sample_now - self.prev_sample) as i32) >> FIXP_SHIFT) as i16; 187 | index += 1; 188 | self.prev_sample = sample_now; 189 | self.update_sample_offset(next_sample_offset); 190 | } 191 | if delta > 0 && index < buffer.len() { 192 | for _i in 0..(delta - 1) { 193 | self.synth.clock(); 194 | } 195 | self.offset -= (delta as i32) << FIXP_SHIFT; 196 | (index, 0) 197 | } else { 198 | (index, delta) 199 | } 200 | } 201 | 202 | /// SID clocking with audio sampling - cycle based with audio resampling. 203 | /// 204 | /// This is the theoretically correct (and computationally intensive) audio 205 | /// sample generation. The samples are generated by resampling to the specified 206 | /// sampling frequency. The work rate is inversely proportional to the 207 | /// percentage of the bandwidth allocated to the filter transition band. 208 | /// 209 | /// This implementation is based on the paper "A Flexible Sampling-Rate 210 | /// Conversion Method", by J. O. Smith and P. Gosset, or rather on the 211 | /// expanded tutorial on the "Digital Audio Resampling Home Page": 212 | /// http://www-ccrma.stanford.edu/~jos/resample/ 213 | /// 214 | /// By building shifted FIR tables with samples according to the 215 | /// sampling frequency, this implementation dramatically reduces the 216 | /// computational effort in the filter convolutions, without any loss 217 | /// of accuracy. The filter convolutions are also vectorizable on 218 | /// current hardware. 219 | /// 220 | /// Further possible optimizations are: 221 | /// * An equiripple filter design could yield a lower filter order, see 222 | /// http://www.mwrf.com/Articles/ArticleID/7229/7229.html 223 | /// * The Convolution Theorem could be used to bring the complexity of 224 | /// convolution down from O(n*n) to O(n*log(n)) using the Fast Fourier 225 | /// Transform, see http://en.wikipedia.org/wiki/Convolution_theorem 226 | /// * Simply resampling in two steps can also yield computational 227 | /// savings, since the transition band will be wider in the first step 228 | /// and the required filter order is thus lower in this step. 229 | /// Laurent Ganier has found the optimal intermediate sampling frequency 230 | /// to be (via derivation of sum of two steps): 231 | /// 2 * pass_freq + sqrt [ 2 * pass_freq * orig_sample_freq 232 | /// * (dest_sample_freq - 2 * pass_freq) / dest_sample_freq ] 233 | /// 234 | /// NB! the result of right shifting negative numbers is really 235 | /// implementation dependent in the C++ standard. 236 | #[cfg(feature = "alloc")] 237 | #[inline] 238 | fn clock_resample_interpolate( 239 | &mut self, 240 | mut delta: u32, 241 | buffer: &mut [i16], 242 | interleave: usize, 243 | ) -> (usize, u32) { 244 | let mut index = 0; 245 | let half = 1i32 << 15; 246 | loop { 247 | let next_sample_offset = self.get_next_sample_offset2(); 248 | let delta_sample = (next_sample_offset >> FIXP_SHIFT) as u32; 249 | if delta_sample > delta || index >= buffer.len() { 250 | break; 251 | } 252 | 253 | for _i in 0..delta_sample { 254 | self.synth.clock(); 255 | let output = self.synth.output(); 256 | self.buffer[self.index] = output; 257 | self.buffer[self.index + RING_SIZE] = output; 258 | self.index += 1; 259 | self.index &= 0x3fff; 260 | } 261 | delta -= delta_sample; 262 | self.update_sample_offset2(next_sample_offset); 263 | 264 | let fir_offset_1 = (self.offset * self.fir.res) >> FIXP_SHIFT; 265 | let fir_offset_rmd = (self.offset * self.fir.res) & FIXP_MASK; 266 | let fir_start_1 = (fir_offset_1 * self.fir.n) as usize; 267 | let fir_end_1 = fir_start_1 + self.fir.n as usize; 268 | let sample_start_1 = (self.index as i32 - self.fir.n + RING_SIZE as i32) as usize; 269 | let sample_end_1 = sample_start_1 + self.fir.n as usize; 270 | 271 | // Convolution with filter impulse response. 272 | let v1 = self.compute_convolution_fir( 273 | &self.buffer[sample_start_1..sample_end_1], 274 | &self.fir.data[fir_start_1..fir_end_1], 275 | ); 276 | 277 | // Use next FIR table, wrap around to first FIR table using 278 | // previous sample. 279 | let mut fir_offset_2 = fir_offset_1 + 1; 280 | let mut sample_start_2 = sample_start_1; 281 | if fir_offset_2 == self.fir.res { 282 | fir_offset_2 = 0; 283 | sample_start_2 -= 1; 284 | } 285 | let fir_start_2 = (fir_offset_2 * self.fir.n) as usize; 286 | let fir_end_2 = fir_start_2 + self.fir.n as usize; 287 | let sample_end_2 = sample_start_2 + self.fir.n as usize; 288 | 289 | let v2 = self.compute_convolution_fir( 290 | &self.buffer[sample_start_2..sample_end_2], 291 | &self.fir.data[fir_start_2..fir_end_2], 292 | ); 293 | 294 | // Linear interpolation. 295 | // fir_offset_rmd is equal for all samples, it can thus be factorized out: 296 | // sum(v1 + rmd*(v2 - v1)) = sum(v1) + rmd*(sum(v2) - sum(v1)) 297 | let mut v = v1 + ((fir_offset_rmd * (v2 - v1)) >> FIXP_SHIFT); 298 | v >>= FIR_SHIFT; 299 | 300 | // Saturated arithmetics to guard against 16 bit sample overflow. 301 | if v >= half { 302 | v = half - 1; 303 | } else if v < -half { 304 | v = -half; 305 | } 306 | 307 | buffer[index * interleave] = v as i16; 308 | index += 1; 309 | } 310 | if delta > 0 && index < buffer.len() { 311 | for _i in 0..delta { 312 | self.synth.clock(); 313 | let output = self.synth.output(); 314 | self.buffer[self.index] = output; 315 | self.buffer[self.index + RING_SIZE] = output; 316 | self.index += 1; 317 | self.index &= 0x3fff; 318 | } 319 | self.offset -= (delta as i32) << FIXP_SHIFT; 320 | (index, 0) 321 | } else { 322 | (index, delta) 323 | } 324 | } 325 | 326 | /// SID clocking with audio sampling - cycle based with audio resampling. 327 | #[cfg(feature = "alloc")] 328 | #[inline] 329 | fn clock_resample_fast( 330 | &mut self, 331 | mut delta: u32, 332 | buffer: &mut [i16], 333 | interleave: usize, 334 | ) -> (usize, u32) { 335 | let mut index = 0; 336 | let half = 1i32 << 15; 337 | loop { 338 | let next_sample_offset = self.get_next_sample_offset2(); 339 | let delta_sample = (next_sample_offset >> FIXP_SHIFT) as u32; 340 | if delta_sample > delta || index >= buffer.len() { 341 | break; 342 | } 343 | 344 | for _i in 0..delta_sample { 345 | self.synth.clock(); 346 | let output = self.synth.output(); 347 | self.buffer[self.index] = output; 348 | self.buffer[self.index + RING_SIZE] = output; 349 | self.index += 1; 350 | self.index &= 0x3fff; 351 | } 352 | delta -= delta_sample; 353 | self.update_sample_offset2(next_sample_offset); 354 | 355 | let fir_offset = (self.offset * self.fir.res) >> FIXP_SHIFT; 356 | let fir_start = (fir_offset * self.fir.n) as usize; 357 | let fir_end = fir_start + self.fir.n as usize; 358 | let sample_start = (self.index as i32 - self.fir.n + RING_SIZE as i32) as usize; 359 | let sample_end = sample_start + self.fir.n as usize; 360 | 361 | // Convolution with filter impulse response. 362 | let mut v = self.compute_convolution_fir( 363 | &self.buffer[sample_start..sample_end], 364 | &self.fir.data[fir_start..fir_end], 365 | ); 366 | v >>= FIR_SHIFT; 367 | 368 | // Saturated arithmetics to guard against 16 bit sample overflow. 369 | if v >= half { 370 | v = half - 1; 371 | } else if v < -half { 372 | v = -half; 373 | } 374 | 375 | buffer[index * interleave] = v as i16; 376 | index += 1; 377 | } 378 | if delta > 0 && index < buffer.len() { 379 | for _i in 0..delta { 380 | self.synth.clock(); 381 | let output = self.synth.output(); 382 | self.buffer[self.index] = output; 383 | self.buffer[self.index + RING_SIZE] = output; 384 | self.index += 1; 385 | self.index &= 0x3fff; 386 | } 387 | self.offset -= (delta as i32) << FIXP_SHIFT; 388 | (index, 0) 389 | } else { 390 | (index, delta) 391 | } 392 | } 393 | 394 | #[inline] 395 | pub fn compute_convolution_fir(&self, sample: &[i16], fir: &[i16]) -> i32 { 396 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 397 | { 398 | if self.use_avx2 { 399 | return unsafe { self.compute_convolution_fir_avx2(sample, fir) }; 400 | } 401 | if self.use_sse42 { 402 | return unsafe { self.compute_convolution_fir_sse(sample, fir) }; 403 | } 404 | } 405 | self.compute_convolution_fir_fallback(sample, fir) 406 | } 407 | 408 | #[target_feature(enable = "avx2")] 409 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 410 | pub unsafe fn compute_convolution_fir_avx2(&self, sample: &[i16], fir: &[i16]) -> i32 { 411 | #[cfg(target_arch = "x86")] 412 | use alloc::arch::x86::*; 413 | #[cfg(target_arch = "x86_64")] 414 | use alloc::arch::x86_64::*; 415 | 416 | // Convolution with filter impulse response. 417 | let len = alloc::cmp::min(sample.len(), fir.len()); 418 | let mut fs = &fir[..len]; 419 | let mut ss = &sample[..len]; 420 | let mut v1 = _mm256_set1_epi32(0); 421 | let mut v2 = _mm256_set1_epi32(0); 422 | let mut v3 = _mm256_set1_epi32(0); 423 | let mut v4 = _mm256_set1_epi32(0); 424 | while fs.len() >= 64 { 425 | let sv1 = _mm256_loadu_si256(ss.as_ptr() as *const _); 426 | let sv2 = _mm256_loadu_si256((&ss[16..]).as_ptr() as *const _); 427 | let sv3 = _mm256_loadu_si256((&ss[32..]).as_ptr() as *const _); 428 | let sv4 = _mm256_loadu_si256((&ss[48..]).as_ptr() as *const _); 429 | let fv1 = _mm256_loadu_si256(fs.as_ptr() as *const _); 430 | let fv2 = _mm256_loadu_si256((&fs[16..]).as_ptr() as *const _); 431 | let fv3 = _mm256_loadu_si256((&fs[32..]).as_ptr() as *const _); 432 | let fv4 = _mm256_loadu_si256((&fs[48..]).as_ptr() as *const _); 433 | let prod1 = _mm256_madd_epi16(sv1, fv1); 434 | let prod2 = _mm256_madd_epi16(sv2, fv2); 435 | let prod3 = _mm256_madd_epi16(sv3, fv3); 436 | let prod4 = _mm256_madd_epi16(sv4, fv4); 437 | v1 = _mm256_add_epi32(v1, prod1); 438 | v2 = _mm256_add_epi32(v2, prod2); 439 | v3 = _mm256_add_epi32(v3, prod3); 440 | v4 = _mm256_add_epi32(v4, prod4); 441 | fs = &fs[64..]; 442 | ss = &ss[64..]; 443 | } 444 | v1 = _mm256_add_epi32(v1, v2); 445 | v3 = _mm256_add_epi32(v3, v4); 446 | v1 = _mm256_add_epi32(v1, v3); 447 | let mut va = [0i32; 8]; 448 | _mm256_storeu_si256(va[..].as_mut_ptr() as *mut _, v1); 449 | let mut v = va[0] + va[1] + va[2] + va[3] + va[4] + va[5] + va[6] + va[7]; 450 | for i in 0..fs.len() { 451 | v += ss[i] as i32 * fs[i] as i32; 452 | } 453 | v 454 | } 455 | 456 | #[target_feature(enable = "sse4.2")] 457 | #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))] 458 | pub unsafe fn compute_convolution_fir_sse(&self, sample: &[i16], fir: &[i16]) -> i32 { 459 | #[cfg(target_arch = "x86")] 460 | use alloc::arch::x86::*; 461 | #[cfg(target_arch = "x86_64")] 462 | use alloc::arch::x86_64::*; 463 | 464 | // Convolution with filter impulse response. 465 | let len = alloc::cmp::min(sample.len(), fir.len()); 466 | let mut fs = &fir[..len]; 467 | let mut ss = &sample[..len]; 468 | let mut v1 = _mm_set1_epi32(0); 469 | let mut v2 = _mm_set1_epi32(0); 470 | let mut v3 = _mm_set1_epi32(0); 471 | let mut v4 = _mm_set1_epi32(0); 472 | while fs.len() >= 32 { 473 | let sv1 = _mm_loadu_si128(ss.as_ptr() as *const _); 474 | let sv2 = _mm_loadu_si128((&ss[8..]).as_ptr() as *const _); 475 | let sv3 = _mm_loadu_si128((&ss[16..]).as_ptr() as *const _); 476 | let sv4 = _mm_loadu_si128((&ss[24..]).as_ptr() as *const _); 477 | let fv1 = _mm_loadu_si128(fs.as_ptr() as *const _); 478 | let fv2 = _mm_loadu_si128((&fs[8..]).as_ptr() as *const _); 479 | let fv3 = _mm_loadu_si128((&fs[16..]).as_ptr() as *const _); 480 | let fv4 = _mm_loadu_si128((&fs[24..]).as_ptr() as *const _); 481 | let prod1 = _mm_madd_epi16(sv1, fv1); 482 | let prod2 = _mm_madd_epi16(sv2, fv2); 483 | let prod3 = _mm_madd_epi16(sv3, fv3); 484 | let prod4 = _mm_madd_epi16(sv4, fv4); 485 | v1 = _mm_add_epi32(v1, prod1); 486 | v2 = _mm_add_epi32(v2, prod2); 487 | v3 = _mm_add_epi32(v3, prod3); 488 | v4 = _mm_add_epi32(v4, prod4); 489 | fs = &fs[32..]; 490 | ss = &ss[32..]; 491 | } 492 | v1 = _mm_add_epi32(v1, v2); 493 | v3 = _mm_add_epi32(v3, v4); 494 | v1 = _mm_add_epi32(v1, v3); 495 | let mut va = [0i32; 4]; 496 | _mm_storeu_si128(va[..].as_mut_ptr() as *mut _, v1); 497 | let mut v = va[0] + va[1] + va[2] + va[3]; 498 | for i in 0..fs.len() { 499 | v += ss[i] as i32 * fs[i] as i32; 500 | } 501 | v 502 | } 503 | 504 | #[inline] 505 | pub fn compute_convolution_fir_fallback(&self, sample: &[i16], fir: &[i16]) -> i32 { 506 | if sample.len() < fir.len() { 507 | sample 508 | .iter() 509 | .zip(fir.iter()) 510 | .fold(0, |sum, (&s, &f)| sum + (s as i32 * f as i32)) 511 | } else { 512 | fir.iter() 513 | .zip(sample.iter()) 514 | .fold(0, |sum, (&f, &s)| sum + (f as i32 * s as i32)) 515 | } 516 | } 517 | 518 | #[inline] 519 | fn get_next_sample_offset(&self) -> i32 { 520 | self.offset + self.cycles_per_sample as i32 + (1 << (FIXP_SHIFT - 1)) 521 | } 522 | 523 | #[inline] 524 | fn get_next_sample_offset2(&self) -> i32 { 525 | self.offset + self.cycles_per_sample as i32 526 | } 527 | 528 | #[inline] 529 | fn update_sample_offset(&mut self, next_sample_offset: i32) { 530 | self.offset = (next_sample_offset & FIXP_MASK) - (1 << (FIXP_SHIFT - 1)); 531 | } 532 | 533 | #[inline] 534 | fn update_sample_offset2(&mut self, next_sample_offset: i32) { 535 | self.offset = next_sample_offset & FIXP_MASK; 536 | } 537 | 538 | #[cfg(feature = "alloc")] 539 | fn init_fir( 540 | &mut self, 541 | clock_freq: f64, 542 | sample_freq: f64, 543 | mut pass_freq: f64, 544 | filter_scale: f64, 545 | ) { 546 | let pi = core::f64::consts::PI; 547 | let samples_per_cycle = sample_freq / clock_freq; 548 | let cycles_per_sample = clock_freq / sample_freq; 549 | 550 | // The default passband limit is 0.9*sample_freq/2 for sample 551 | // frequencies below ~ 44.1kHz, and 20kHz for higher sample frequencies. 552 | if pass_freq < 0.0 { 553 | pass_freq = 20000.0; 554 | if 2.0 * pass_freq / sample_freq >= 0.9 { 555 | pass_freq = 0.9 * sample_freq / 2.0; 556 | } 557 | } 558 | 559 | // 16 bits -> -96dB stopband attenuation. 560 | let atten = -20.0f64 * (1.0 / (1i32 << 16) as f64).log10(); 561 | // A fraction of the bandwidth is allocated to the transition band, 562 | let dw = (1.0f64 - 2.0 * pass_freq / sample_freq) * pi; 563 | // The cutoff frequency is midway through the transition band. 564 | let wc = (2.0f64 * pass_freq / sample_freq + 1.0) * pi / 2.0; 565 | 566 | // For calculation of beta and N see the reference for the kaiserord 567 | // function in the MATLAB Signal Processing Toolbox: 568 | // http://www.mathworks.com/access/helpdesk/help/toolbox/signal/kaiserord.html 569 | let beta = 0.1102f64 * (atten - 8.7); 570 | let io_beta = self.i0(beta); 571 | 572 | // The filter order will maximally be 124 with the current constraints. 573 | // N >= (96.33 - 7.95)/(2.285*0.1*pi) -> N >= 123 574 | // The filter order is equal to the number of zero crossings, i.e. 575 | // it should be an even number (sinc is symmetric about x = 0). 576 | let mut n_cap = ((atten - 7.95) / (2.285 * dw) + 0.5) as i32; 577 | n_cap += n_cap & 1; 578 | 579 | // The filter length is equal to the filter order + 1. 580 | // The filter length must be an odd number (sinc is symmetric about x = 0). 581 | self.fir.n = (n_cap as f64 * cycles_per_sample) as i32 + 1; 582 | self.fir.n |= 1; 583 | 584 | // We clamp the filter table resolution to 2^n, making the fixpoint 585 | // sample_offset a whole multiple of the filter table resolution. 586 | let res = if self.sampling_method == SamplingMethod::Resample { 587 | FIR_RES_INTERPOLATE 588 | } else { 589 | FIR_RES_FAST 590 | }; 591 | let n = ((res as f64 / cycles_per_sample).ln() / (2.0f64).ln()).ceil() as i32; 592 | self.fir.res = 1 << n; 593 | 594 | self.fir.data.clear(); 595 | self.fir 596 | .data 597 | .resize((self.fir.n * self.fir.res) as usize, 0); 598 | 599 | // Calculate fir_RES FIR tables for linear interpolation. 600 | for i in 0..self.fir.res { 601 | let fir_offset = i * self.fir.n + self.fir.n / 2; 602 | let j_offset = i as f64 / self.fir.res as f64; 603 | // Calculate FIR table. This is the sinc function, weighted by the 604 | // Kaiser window. 605 | let fir_n_div2 = self.fir.n / 2; 606 | for j in -fir_n_div2..=fir_n_div2 { 607 | let jx = j as f64 - j_offset; 608 | let wt = wc * jx / cycles_per_sample; 609 | let temp = jx / fir_n_div2 as f64; 610 | let kaiser = if temp.abs() <= 1.0 { 611 | self.i0(beta * self.sqrt(1.0 - temp * temp)) / io_beta 612 | } else { 613 | 0f64 614 | }; 615 | let sincwt = if wt.abs() >= 1e-6 { wt.sin() / wt } else { 1.0 }; 616 | let val = (1i32 << FIR_SHIFT) as f64 * filter_scale * samples_per_cycle * wc / pi 617 | * sincwt 618 | * kaiser; 619 | self.fir.data[(fir_offset + j) as usize] = (val + 0.5) as i16; 620 | } 621 | } 622 | } 623 | 624 | fn i0(&self, x: f64) -> f64 { 625 | // Max error acceptable in I0. 626 | let i0e = 1e-6; 627 | let halfx = x / 2.0; 628 | let mut sum = 1.0; 629 | let mut u = 1.0; 630 | let mut n = 1; 631 | loop { 632 | let temp = halfx / n as f64; 633 | n += 1; 634 | u *= temp * temp; 635 | sum += u; 636 | if u < i0e * sum { 637 | break; 638 | } 639 | } 640 | sum 641 | } 642 | 643 | #[cfg(feature = "std")] 644 | fn sqrt(&self, value: f64) -> f64 { 645 | value.sqrt() 646 | } 647 | 648 | #[cfg(not(feature = "std"))] 649 | fn sqrt(&self, value: f64) -> f64 { 650 | math::sqrt(value) 651 | } 652 | } 653 | -------------------------------------------------------------------------------- /tests/data/sid_output.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | pub static RESID_OUTPUT: [i16; 4851] = [ 3 | 15417, 16016, 15991, 15956, 15921, 15886, 15852, 15817, 4 | 15782, 15748, 15713, 15679, 15644, 15610, 15576, 15541, 5 | 15507, 15473, 15439, 15406, 15372, 15338, 15305, 15271, 6 | 15238, 15204, 15171, 15138, 15104, 15071, 15038, 15005, 7 | 14972, 14939, 14907, 14874, 14841, 14809, 14776, 14744, 8 | 14712, 14679, 14647, 14615, 14583, 14551, 14519, 14487, 9 | 14456, 14424, 14392, 14361, 14329, 14298, 14267, 14235, 10 | 14204, 14173, 14142, 14111, 14080, 14049, 14018, 13988, 11 | 13957, 13926, 13896, 13865, 13835, 13805, 13774, 13744, 12 | 13714, 13684, 13654, 13624, 13594, 13564, 13535, 13505, 13 | 13475, 13446, 13416, 13387, 13358, 13328, 13299, 13270, 14 | 13241, 13212, 13183, 13154, 13125, 13097, 13068, 13039, 15 | 13011, 12982, 12954, 12925, 12897, 12869, 12841, 12812, 16 | 12784, 12756, 12728, 12700, 12673, 12645, 12617, 12590, 17 | 12562, 12534, 12507, 12480, 12452, 12425, 12398, 12371, 18 | 12344, 12317, 12290, 12263, 12236, 12209, 12182, 12156, 19 | 12129, 12102, 12076, 12049, 12023, 11997, 11970, 11944, 20 | 11918, 11892, 11866, 11840, 11814, 11788, 11762, 11737, 21 | 11711, 11685, 11660, 11634, 11609, 11583, 11558, 11533, 22 | 11507, 11482, 11457, 11432, 11407, 11382, 11357, 11332, 23 | 11307, 11282, 11258, 11233, 11208, 11184, 11159, 11135, 24 | 11111, 11086, 11062, 11038, 11014, 10990, 10966, 10942, 25 | 10918, 10894, 10870, 10846, 10822, 10799, 10775, 10751, 26 | 10728, 10704, 10681, 10658, 10634, 10611, 10588, 10565, 27 | 10542, 10519, 10496, 10473, 10450, 10427, 10404, 10381, 28 | 10358, 10336, 10313, 10291, 10268, 10246, 10223, 10201, 29 | 10178, 10156, 10134, 10112, 10090, 10068, 10046, 10024, 30 | 10002, 9980, 9958, 9936, 9914, 9893, 9871, 9849, 31 | 9828, 9806, 9785, 9764, 9742, 9721, 9700, 9678, 32 | 9657, 9636, 9615, 9594, 9573, 9552, 9531, 9510, 33 | 9490, 9469, 9448, 9428, 9407, 9386, 9366, 9345, 34 | 9325, 9304, 9284, 9264, 9244, 9223, 9203, 9183, 35 | 9163, 9143, 9123, 9103, 9083, 9063, 9044, 9024, 36 | 9004, 8984, 8965, 8945, 8926, 8906, 8887, 8867, 37 | 8848, 8828, 8809, 8790, 8771, 8751, 8732, 8713, 38 | 8694, 8675, 8656, 8637, 8618, 8600, 8581, 8562, 39 | 8543, 8525, 8506, 8487, 8469, 8450, 8432, 8413, 40 | 8395, 8377, 8358, 8340, 8322, 8304, 8285, 8267, 41 | 8249, 8231, 8213, 8195, 8177, 8160, 8142, 8124, 42 | 8106, 8089, 8071, 8053, 8036, 8018, 8001, 7983, 43 | 7966, 7948, 7931, 7914, 7896, 7879, 7862, 7845, 44 | 7827, 7810, 7793, 7776, 7759, 7742, 7725, 7709, 45 | 7692, 7675, 7658, 7642, 7625, 7608, 7592, 7575, 46 | 7558, 7542, 7526, 7509, 7493, 7476, 7460, 7444, 47 | 7428, 7411, 7395, 7379, 7363, 7347, 7331, 7315, 48 | 7299, 7283, 7267, 7251, 7235, 7220, 7204, 7188, 49 | 7172, 7157, 7141, 7125, 7110, 7094, 7079, 7064, 50 | 7048, 7033, 7017, 7002, 6987, 6972, 6956, 6941, 51 | 6926, 6911, 6896, 6881, 6866, 6851, 6836, 6821, 52 | 6806, 6791, 6776, 6762, 6747, 6732, 6718, 6703, 53 | 6688, 6674, 6659, 6645, 6630, 6616, 6601, 6587, 54 | 6572, 6558, 6544, 6530, 6515, 6501, 6487, 6473, 55 | 6459, 6445, 6431, 6417, 6403, 6389, 6375, 6361, 56 | 6347, 6333, 6319, 6305, 6292, 6278, 6264, 6251, 57 | 6237, 6223, 6210, 6196, 6183, 6169, 6156, 6142, 58 | 6129, 6116, 6102, 6089, 6076, 6063, 6049, 6036, 59 | 6023, 6010, 5997, 5984, 5971, 5958, 5945, 5932, 60 | 5919, 5906, 5893, 5880, 5867, 5855, 5842, 5829, 61 | 5816, 5804, 5791, 5778, 5766, 5753, 5741, 5728, 62 | 5716, 5703, 5691, 5678, 5666, 5654, 5642, 5629, 63 | 5617, 5605, 5592, 5580, 5568, 5556, 5544, 5532, 64 | 5520, 5508, 5496, 5484, 5472, 5460, 5448, 5436, 65 | 5424, 5413, 5401, 5389, 5377, 5366, 5354, 5342, 66 | 5331, 5319, 5307, 5296, 5284, 5273, 5261, 5250, 67 | 5239, 5227, 5216, 5204, 5193, 5182, 5171, 5159, 68 | 5148, 5137, 5126, 5114, 5103, 5092, 5081, 5070, 69 | 5059, 5048, 5037, 5026, 5015, 5004, 4993, 4982, 70 | 4972, 4961, 4950, 4939, 4929, 4918, 4907, 4897, 71 | 4886, 4875, 4865, 4854, 4844, 4833, 4823, 4812, 72 | 4802, 4791, 4781, 4770, 4760, 4750, 4739, 4729, 73 | 4719, 4709, 4698, 4688, 4678, 4668, 4657, 4647, 74 | 4637, 4627, 4617, 4607, 4597, 4587, 4577, 4567, 75 | 4557, 4547, 4537, 4528, 4518, 4508, 4498, 4489, 76 | 4479, 4469, 4460, 4450, 4440, 4430, 4421, 4411, 77 | 4402, 4392, 4383, 4373, 4364, 4354, 4345, 4335, 78 | 4326, 4316, 4307, 4298, 4288, 4279, 4270, 4261, 79 | 4251, 4242, 4233, 4224, 4214, 4205, 4196, 4187, 80 | 4178, 4169, 4160, 4151, 4142, 4133, 4124, 4115, 81 | 4106, 4097, 4088, 4079, 4070, 4062, 4053, 4044, 82 | 4036, 4027, 4018, 4009, 4001, 3992, 3983, 3974, 83 | 3966, 3957, 3949, 3940, 3932, 3923, 3915, 3906, 84 | 3898, 3889, 3881, 3872, 3864, 3856, 3847, 3839, 85 | 3831, 3822, 3814, 3806, 3798, 3789, 3781, 3773, 86 | 3765, 3757, 3748, 3740, 3732, 3724, 3716, 3708, 87 | 3700, 3692, 3684, 3676, 3668, 3660, 3652, 3644, 88 | 3636, 3628, 3621, 3613, 3605, 3597, 3590, 3582, 89 | 3574, 3566, 3559, 3551, 3543, 3536, 3528, 3520, 90 | 3512, 3505, 3497, 3490, 3482, 3475, 3467, 3460, 91 | 3452, 3445, 3437, 3430, 3423, 3415, 3408, 3400, 92 | 3393, 3386, 3378, 3371, 3364, 3357, 3349, 3342, 93 | 3335, 3328, 3320, 3313, 3306, 3299, 3292, 3285, 94 | 3278, 3271, 3264, 3257, 3250, 3243, 3236, 3229, 95 | 3222, 3215, 3208, 3201, 3194, 3187, 3180, 3173, 96 | 3166, 3159, 3153, 3146, 3139, 3132, 3126, 3119, 97 | 3112, 3105, 3099, 3092, 3085, 3079, 3072, 3065, 98 | 3059, 3052, 3045, 3039, 3032, 3026, 3019, 3013, 99 | 3006, 3000, 2993, 2987, 2981, 2974, 2968, 2961, 100 | 2955, 2948, 2942, 2936, 2929, 2923, 2917, 2911, 101 | 2904, 2898, 2892, 2886, 2879, 2873, 2867, 2861, 102 | 2854, 2848, 2842, 2836, 2830, 2824, 2818, 2812, 103 | 2806, 2800, 2794, 2788, 2782, 2776, 2770, 2764, 104 | 2758, 2752, 2746, 2740, 2734, 2728, 2722, 2716, 105 | 2710, 2705, 2699, 2693, 2688, 2682, 2676, 2670, 106 | 2665, 2659, 2653, 2647, 2642, 2636, 2630, 2625, 107 | 2619, 2613, 2607, 2602, 2596, 2591, 2585, 2580, 108 | 2574, 2569, 2563, 2558, 2552, 2547, 2541, 2536, 109 | 2530, 2525, 2520, 2514, 2509, 2503, 2498, 2492, 110 | 2487, 2482, 2477, 2471, 2466, 2461, 2455, 2450, 111 | 2445, 2440, 2434, 2429, 2424, 2419, 2413, 2408, 112 | 2403, 2398, 2393, 2387, 2382, 2377, 2372, 2367, 113 | 2362, 2357, 2352, 2347, 2342, 2337, 2332, 2327, 114 | 2322, 2317, 2312, 2307, 2302, 2297, 2292, 2287, 115 | 2282, 2277, 2272, 2267, 2263, 2258, 2253, 2248, 116 | 2244, 2239, 2234, 2230, 2225, 2220, 2215, 2211, 117 | 2206, 2201, 2196, 2192, 2187, 2182, 2178, 2173, 118 | 2168, 2163, 2159, 2154, 2149, 2145, 2140, 2136, 119 | 2131, 2127, 2122, 2118, 2113, 2109, 2104, 2100, 120 | 2095, 2091, 2086, 2082, 2078, 2073, 2069, 2064, 121 | 2060, 2055, 2051, 2046, 2042, 2038, 2033, 2029, 122 | 2025, 2021, 2016, 2012, 2008, 2003, 1999, 1995, 123 | 1991, 1986, 1982, 1978, 1974, 1969, 1965, 1961, 124 | 1957, 1952, 1948, 1944, 1940, 1936, 1932, 1927, 125 | 1923, 1919, 1915, 1911, 1907, 1903, 1899, 1895, 126 | 1891, 1887, 1883, 1879, 1875, 1871, 1867, 1863, 127 | 1859, 1855, 1851, 1847, 1843, 1839, 1835, 1831, 128 | 1827, 1823, 1819, 1815, 1812, 1808, 1804, 1800, 129 | 1797, 1793, 1789, 1785, 1782, 1778, 1774, 1771, 130 | 1767, 1763, 1759, 1756, 1752, 1748, 1744, 1741, 131 | 1737, 1733, 1730, 1726, 1722, 1718, 1715, 1711, 132 | 1707, 1703, 1700, 1696, 1693, 1689, 1686, 1682, 133 | 1679, 1675, 1671, 1668, 1664, 1661, 1657, 1654, 134 | 1650, 1647, 1644, 1640, 1637, 1633, 1630, 1626, 135 | 1623, 1619, 1616, 1612, 1609, 1606, 1602, 1599, 136 | 1595, 1592, 1588, 1585, 1582, 1578, 1575, 1572, 137 | 1569, 1565, 1562, 1559, 1556, 1552, 1549, 1546, 138 | 1542, 1539, 1536, 1533, 1529, 1526, 1523, 1520, 139 | 1516, 1513, 1510, 1507, 1503, 1500, 1497, 1494, 140 | 1491, 1487, 1484, 1481, 1478, 1475, 1472, 1469, 141 | 1466, 1463, 1460, 1457, 1454, 1451, 1448, 1445, 142 | 1442, 1439, 1436, 1433, 1430, 1427, 1424, 1421, 143 | 1418, 1415, 1412, 1409, 1406, 1403, 1400, 1397, 144 | 1394, 1391, 1388, 1385, 1382, 1379, 1376, 1373, 145 | 1370, 1367, 1364, 1361, 1358, 1355, 1353, 1350, 146 | 1347, 1344, 1342, 1339, 1336, 1333, 1331, 1328, 147 | 1325, 1323, 1320, 1317, 1314, 1312, 1309, 1306, 148 | 1303, 1301, 1298, 1295, 1293, 1290, 1287, 1284, 149 | 1282, 1279, 1276, 1273, 1271, 1268, 1265, 1263, 150 | 1260, 1257, 1254, 1252, 1249, 1246, 1244, 1241, 151 | 1239, 1236, 1234, 1231, 1228, 1226, 1223, 1221, 152 | 1218, 1216, 1213, 1211, 1208, 1206, 1203, 1201, 153 | 1198, 1196, 1193, 1191, 1188, 1186, 1184, 1181, 154 | 1179, 1176, 1174, 1171, 1169, 1166, 1164, 1161, 155 | 1159, 1157, 1154, 1152, 1149, 1147, 1144, 1142, 156 | 1139, 1137, 1134, 1132, 1130, 1128, 1125, 1123, 157 | 1121, 1119, 1116, 1114, 1112, 1109, 1107, 1105, 158 | 1103, 1100, 1098, 1096, 1094, 1091, 1089, 1087, 159 | 1084, 1082, 1080, 1078, 1075, 1073, 1071, 1069, 160 | 1066, 1064, 1062, 1059, 1057, 1055, 1053, 1051, 161 | 1048, 1046, 1044, 1042, 1040, 1038, 1035, 1033, 162 | 1031, 1029, 1027, 1024, 1022, 1020, 1018, 1016, 163 | 1014, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 164 | 998, 996, 994, 992, 990, 988, 986, 984, 165 | 982, 980, 978, 976, 974, 972, 970, 968, 166 | 966, 964, 962, 960, 958, 956, 954, 952, 167 | 950, 948, 946, 944, 942, 940, 938, 936, 168 | 934, 932, 930, 928, 926, 924, 922, 920, 169 | 918, 916, 914, 912, 910, 908, 906, 904, 170 | 903, 901, 899, 898, 896, 894, 892, 891, 171 | 889, 887, 885, 884, 882, 880, 879, 877, 172 | 875, 873, 872, 870, 868, 866, 865, 863, 173 | 861, 860, 858, 856, 854, 853, 851, 849, 174 | 847, 846, 844, 842, 841, 839, 837, 835, 175 | 834, 832, 830, 828, 827, 825, 823, 822, 176 | 820, 818, 816, 815, 813, 811, 809, 808, 177 | 806, 804, 803, 801, 799, 797, 796, 794, 178 | 792, 791, 789, 788, 786, 785, 783, 782, 179 | 780, 778, 777, 775, 774, 772, 771, 769, 180 | 768, 766, 765, 763, 761, 760, 758, 757, 181 | 755, 754, 752, 751, 749, 748, 747, 745, 182 | 744, 742, 741, 739, 738, 736, 735, 733, 183 | 732, 731, 729, 728, 726, 725, 723, 722, 184 | 720, 719, 717, 716, 715, 713, 712, 710, 185 | 709, 707, 706, 704, 703, 701, 700, 699, 186 | 697, 696, 694, 693, 691, 690, 688, 687, 187 | 685, 684, 683, 681, 680, 678, 677, 676, 188 | 675, 673, 672, 671, 670, 668, 667, 666, 189 | 664, 663, 662, 661, 659, 658, 657, 656, 190 | 654, 653, 652, 650, 649, 648, 647, 645, 191 | 644, 643, 642, 640, 639, 638, 636, 635, 192 | 634, 633, 631, 630, 629, 628, 626, 625, 193 | 624, 622, 621, 620, 619, 617, 616, 615, 194 | 614, 612, 611, 610, 608, 607, 606, 605, 195 | 603, 602, 601, 600, 599, 598, 596, 595, 196 | 594, 593, 592, 590, 589, 588, 587, 586, 197 | 585, 583, 582, 581, 580, 579, 577, 576, 198 | 575, 574, 573, 572, 570, 569, 568, 567, 199 | 566, 565, 564, 563, 562, 561, 560, 559, 200 | 558, 557, 556, 555, 554, 553, 552, 551, 201 | 550, 549, 548, 547, 546, 545, 544, 543, 202 | 542, 541, 540, 539, 538, 537, 536, 535, 203 | 534, 533, 532, 531, 530, 529, 528, 527, 204 | 526, 525, 524, 523, 522, 521, 520, 519, 205 | 518, 517, 516, 515, 514, 513, 512, 511, 206 | 510, 509, 508, 507, 506, 505, 504, 503, 207 | 502, 501, 500, 499, 498, 497, 496, 495, 208 | 494, 493, 492, 491, 490, 489, 488, 487, 209 | 486, 485, 484, 483, 482, 481, 480, 479, 210 | 478, 477, 476, 475, 474, 473, 472, 471, 211 | 470, 469, 468, 467, 466, 465, 464, 463, 212 | 462, 461, 460, 459, 458, 457, 456, 455, 213 | 454, 453, 452, 451, 451, 450, 449, 449, 214 | 448, 447, 446, 446, 445, 444, 443, 443, 215 | 442, 441, 441, 440, 439, 438, 438, 437, 216 | 436, 435, 435, 434, 433, 433, 432, 431, 217 | 430, 430, 429, 428, 427, 427, 426, 425, 218 | 425, 424, 423, 422, 422, 421, 420, 419, 219 | 419, 418, 417, 417, 416, 415, 414, 414, 220 | 413, 412, 411, 411, 410, 409, 409, 408, 221 | 407, 406, 406, 405, 404, 403, 403, 402, 222 | 401, 401, 400, 399, 398, 398, 397, 396, 223 | 395, 395, 394, 393, 393, 392, 391, 390, 224 | 390, 389, 388, 387, 387, 386, 385, 385, 225 | 384, 383, 382, 382, 381, 380, 379, 379, 226 | 378, 377, 377, 376, 375, 374, 374, 373, 227 | 372, 371, 371, 370, 369, 369, 368, 367, 228 | 366, 366, 365, 364, 363, 363, 362, 361, 229 | 361, 360, 359, 358, 358, 357, 356, 355, 230 | 355, 354, 353, 353, 352, 351, 350, 350, 231 | 349, 348, 347, 347, 346, 345, 345, 344, 232 | 343, 342, 342, 341, 340, 340, 339, 338, 233 | 338, 337, 337, 336, 336, 335, 335, 334, 234 | 334, 333, 332, 332, 331, 331, 330, 330, 235 | 329, 329, 328, 328, 327, 326, 326, 325, 236 | 325, 324, 324, 323, 323, 322, 322, 321, 237 | 320, 320, 319, 319, 318, 318, 317, 317, 238 | 316, 316, 315, 314, 314, 313, 313, 312, 239 | 312, 311, 311, 310, 310, 309, 308, 308, 240 | 307, 307, 306, 306, 305, 305, 304, 304, 241 | 303, 302, 302, 301, 301, 301, 300, 300, 242 | 299, 299, 298, 298, 297, 297, 296, 296, 243 | 296, 295, 295, 294, 294, 293, 293, 292, 244 | 292, 291, 291, 291, 290, 290, 289, 289, 245 | 288, 288, 287, 287, 286, 286, 286, 285, 246 | 285, 284, 284, 283, 283, 282, 282, 281, 247 | 281, 281, 280, 280, 279, 279, 278, 278, 248 | 277, 277, 276, 276, 276, 275, 275, 274, 249 | 274, 273, 273, 272, 272, 271, 271, 271, 250 | 270, 270, 269, 269, 268, 268, 267, 267, 251 | 266, 266, 266, 265, 265, 264, 264, 263, 252 | 263, 262, 262, 261, 261, 261, 260, 260, 253 | 259, 259, 258, 258, 257, 257, 256, 256, 254 | 256, 255, 255, 254, 254, 253, 253, 252, 255 | 252, 251, 251, 251, 250, 250, 249, 249, 256 | 248, 248, 247, 247, 246, 246, 246, 245, 257 | 245, 244, 244, 243, 243, 242, 242, 241, 258 | 241, 241, 240, 240, 239, 239, 238, 238, 259 | 237, 237, 236, 236, 236, 235, 235, 234, 260 | 234, 233, 233, 232, 232, 231, 231, 231, 261 | 230, 230, 229, 229, 228, 228, 227, 227, 262 | 226, 226, 226, 226, 225, 225, 225, 225, 263 | 224, 224, 224, 223, 223, 223, 223, 222, 264 | 222, 222, 222, 221, 221, 221, 220, 220, 265 | 220, 220, 219, 219, 219, 219, 218, 218, 266 | 218, 217, 217, 217, 217, 216, 216, 216, 267 | 216, 215, 215, 215, 214, 214, 214, 214, 268 | 213, 213, 213, 213, 212, 212, 212, 211, 269 | 211, 211, 211, 210, 210, 210, 210, 209, 270 | 209, 209, 208, 208, 208, 208, 207, 207, 271 | 207, 207, 206, 206, 206, 205, 205, 205, 272 | 205, 204, 204, 204, 204, 203, 203, 203, 273 | 202, 202, 202, 202, 201, 201, 201, 201, 274 | 200, 200, 200, 199, 199, 199, 199, 198, 275 | 198, 198, 198, 197, 197, 197, 196, 196, 276 | 196, 196, 195, 195, 195, 195, 194, 194, 277 | 194, 193, 193, 193, 193, 192, 192, 192, 278 | 192, 191, 191, 191, 190, 190, 190, 190, 279 | 189, 189, 189, 189, 188, 188, 188, 187, 280 | 187, 187, 187, 186, 186, 186, 186, 185, 281 | 185, 185, 184, 184, 184, 184, 183, 183, 282 | 183, 183, 182, 182, 182, 181, 181, 181, 283 | 181, 180, 180, 180, 180, 179, 179, 179, 284 | 178, 178, 178, 178, 177, 177, 177, 177, 285 | 176, 176, 176, 175, 175, 175, 175, 174, 286 | 174, 174, 174, 173, 173, 173, 172, 172, 287 | 172, 172, 171, 171, 171, 171, 170, 170, 288 | 170, 169, 169, 169, 169, 168, 168, 168, 289 | 168, 167, 167, 167, 166, 166, 166, 166, 290 | 165, 165, 165, 165, 164, 164, 164, 163, 291 | 163, 163, 163, 162, 162, 162, 162, 161, 292 | 161, 161, 160, 160, 160, 160, 159, 159, 293 | 159, 159, 158, 158, 158, 157, 157, 157, 294 | 157, 156, 156, 156, 156, 155, 155, 155, 295 | 154, 154, 154, 154, 153, 153, 153, 153, 296 | 152, 152, 152, 151, 151, 151, 151, 150, 297 | 150, 150, 150, 150, 150, 149, 149, 149, 298 | 149, 149, 148, 148, 148, 148, 148, 148, 299 | 147, 147, 147, 147, 147, 146, 146, 146, 300 | 146, 146, 146, 145, 145, 145, 145, 145, 301 | 144, 144, 144, 144, 144, 144, 143, 143, 302 | 143, 143, 143, 142, 142, 142, 142, 142, 303 | 142, 141, 141, 141, 141, 141, 140, 140, 304 | 140, 140, 140, 140, 139, 139, 139, 139, 305 | 139, 138, 138, 138, 138, 138, 138, 137, 306 | 137, 137, 137, 137, 136, 136, 136, 136, 307 | 136, 136, 135, 135, 135, 135, 135, 134, 308 | 134, 134, 134, 134, 134, 133, 133, 133, 309 | 133, 133, 132, 132, 132, 132, 132, 132, 310 | 131, 131, 131, 131, 131, 130, 130, 130, 311 | 130, 130, 130, 129, 129, 129, 129, 129, 312 | 128, 128, 128, 128, 128, 128, 127, 127, 313 | 127, 127, 127, 126, 126, 126, 126, 126, 314 | 126, 125, 125, 125, 125, 125, 124, 124, 315 | 124, 124, 124, 124, 123, 123, 123, 123, 316 | 123, 122, 122, 122, 122, 122, 122, 121, 317 | 121, 121, 121, 121, 120, 120, 120, 120, 318 | 120, 120, 119, 119, 119, 119, 119, 118, 319 | 118, 118, 118, 118, 118, 117, 117, 117, 320 | 117, 117, 116, 116, 116, 116, 116, 116, 321 | 115, 115, 115, 115, 115, 114, 114, 114, 322 | 114, 114, 114, 113, 113, 113, 113, 113, 323 | 113, 113, 113, 113, 113, 113, 113, 113, 324 | 113, 113, 113, 113, 113, 113, 113, 113, 325 | 113, 113, 113, 113, 113, 113, 113, 113, 326 | 113, 113, 113, 113, 113, 113, 113, 113, 327 | 113, 113, 113, 113, 113, 113, 113, 113, 328 | 113, 113, 113, 113, 113, 113, 113, 113, 329 | 113, 113, 113, 113, 113, 113, 113, 113, 330 | 113, 113, 113, 113, 113, 113, 113, 113, 331 | 113, 113, 113, 113, 113, 113, 113, 113, 332 | 113, 113, 113, 113, 113, 113, 113, 113, 333 | 113, 113, 113, 113, 113, 113, 113, 113, 334 | 113, 113, 113, 113, 113, 113, 113, 113, 335 | 113, 113, 113, 113, 113, 113, 113, 113, 336 | 113, 113, 113, 113, 113, 113, 113, 113, 337 | 113, 113, 113, 113, 113, 113, 113, 113, 338 | 113, 113, 113, 113, 113, 113, 113, 113, 339 | 113, 113, 113, 113, 113, 113, 113, 113, 340 | 113, 113, 113, 113, 113, 113, 113, 113, 341 | 113, 113, 113, 113, 113, 113, 113, 113, 342 | 113, 113, 113, 113, 113, 113, 113, 113, 343 | 113, 113, 113, 113, 113, 113, 113, 113, 344 | 113, 113, 113, 113, 113, 113, 113, 113, 345 | 113, 113, 113, 113, 113, 113, 113, 113, 346 | 113, 113, 113, 113, 113, 113, 113, 113, 347 | 113, 113, 113, 113, 113, 113, 113, 113, 348 | 113, 113, 113, 113, 113, 113, 113, 113, 349 | 113, 113, 113, 113, 113, 113, 113, 113, 350 | 113, 113, 113, 113, 113, 113, 113, 113, 351 | 113, 113, 113, 113, 113, 113, 113, 113, 352 | 113, 113, 113, 113, 113, 113, 113, 113, 353 | 113, 113, 113, 113, 113, 113, 113, 113, 354 | 113, 113, 113, 113, 113, 113, 113, 113, 355 | 113, 113, 113, 113, 113, 113, 113, 113, 356 | 113, 113, 113, 113, 113, 113, 113, 113, 357 | 113, 113, 113, 113, 113, 113, 113, 113, 358 | 113, 113, 113, 113, 113, 113, 113, 113, 359 | 113, 113, 113, 113, 113, 113, 113, 113, 360 | 113, 113, 113, 113, 113, 113, 113, 113, 361 | 113, 113, 113, 113, 113, 113, 113, 113, 362 | 113, 113, 113, 113, 113, 113, 113, 113, 363 | 113, 113, 113, 113, 113, 113, 113, 113, 364 | 113, 113, 113, 113, 113, 113, 113, 113, 365 | 113, 113, 113, 113, 113, 113, 113, 113, 366 | 113, 113, 113, 113, 113, 113, 113, 113, 367 | 113, 113, 113, 113, 113, 113, 113, 113, 368 | 113, 113, 113, 113, 113, 113, 113, 113, 369 | 113, 113, 113, 113, 113, 113, 113, 113, 370 | 113, 113, 113, 113, 113, 113, 113, 113, 371 | 113, 113, 113, 113, 113, 113, 113, 113, 372 | 113, 113, 113, 113, 113, 113, 113, 113, 373 | 113, 113, 113, 113, 113, 113, 113, 113, 374 | 113, 113, 113, 113, 113, 113, 113, 113, 375 | 113, 113, 113, 113, 113, 113, 113, 113, 376 | 113, 113, 113, 113, 113, 113, 113, 113, 377 | 113, 113, 113, 113, 113, 113, 113, 113, 378 | 113, 113, 113, 113, 113, 113, 113, 113, 379 | 113, 113, 113, 113, 113, 113, 113, 113, 380 | 113, 113, 113, 113, 113, 113, 113, 113, 381 | 113, 113, 113, 113, 113, 113, 113, 113, 382 | 113, 113, 113, 113, 113, 113, 113, 113, 383 | 113, 113, 113, 113, 113, 113, 113, 113, 384 | 113, 113, 113, 113, 113, 113, 113, 113, 385 | 113, 113, 113, 113, 113, 113, 113, 113, 386 | 113, 113, 113, 113, 113, 113, 113, 113, 387 | 113, 113, 113, 113, 113, 113, 113, 113, 388 | 113, 113, 113, 113, 113, 113, 113, 113, 389 | 113, 113, 113, 113, 113, 113, 113, 113, 390 | 113, 113, 113, 113, 113, 113, 113, 113, 391 | 113, 113, 113, 113, 113, 113, 113, 113, 392 | 113, 113, 113, 113, 113, 113, 113, 113, 393 | 113, 113, 113, 113, 113, 113, 113, 113, 394 | 113, 113, 113, 113, 113, 113, 113, 113, 395 | 113, 113, 113, 113, 113, 113, 113, 113, 396 | 113, 113, 113, 113, 113, 113, 113, 113, 397 | 113, 113, 113, 113, 113, 113, 113, 113, 398 | 113, 113, 113, 113, 113, 113, 113, 113, 399 | 113, 113, 113, 113, 113, 113, 113, 113, 400 | 113, 113, 113, 113, 113, 113, 113, 113, 401 | 113, 113, 113, 113, 113, 113, 113, 113, 402 | 113, 113, 113, 113, 113, 113, 113, 113, 403 | 113, 113, 113, 113, 113, 113, 113, 113, 404 | 113, 113, 113, 113, 113, 113, 113, 113, 405 | 113, 113, 113, 113, 113, 113, 113, 113, 406 | 113, 113, 113, 113, 113, 113, 113, 113, 407 | 113, 113, 113, 113, 113, 113, 113, 113, 408 | 113, 113, 113, 113, 113, 113, 113, 113, 409 | 113, 113, 113, 113, 113, 113, 113, 113, 410 | 113, 113, 113, 113, 113, 113, 113, 113, 411 | 113, 113, 113, 113, 113, 113, 113, 113, 412 | 113, 113, 113, 113, 113, 113, 113, 113, 413 | 113, 113, 113, 113, 113, 113, 113, 113, 414 | 113, 113, 113, 113, 113, 113, 113, 113, 415 | 113, 113, 113, 113, 113, 113, 113, 113, 416 | 113, 113, 113, 113, 113, 113, 113, 113, 417 | 113, 113, 113, 113, 113, 113, 113, 113, 418 | 113, 113, 113, 113, 113, 113, 113, 113, 419 | 113, 113, 113, 113, 113, 113, 113, 113, 420 | 113, 113, 113, 113, 113, 113, 113, 113, 421 | 113, 113, 113, 113, 113, 113, 113, 113, 422 | 113, 113, 113, 113, 113, 113, 113, 113, 423 | 113, 113, 113, 113, 113, 113, 113, 113, 424 | 113, 113, 113, 113, 113, 113, 113, 113, 425 | 113, 113, 113, 113, 113, 113, 113, 113, 426 | 113, 113, 113, 113, 113, 113, 113, 113, 427 | 113, 113, 113, 113, 113, 113, 113, 113, 428 | 113, 113, 113, 113, 113, 113, 113, 113, 429 | 113, 113, 113, 113, 113, 113, 113, 113, 430 | 113, 113, 113, 113, 113, 113, 113, 113, 431 | 113, 113, 113, 113, 113, 113, 113, 113, 432 | 113, 113, 113, 113, 113, 113, 113, 113, 433 | 113, 113, 113, 113, 113, 113, 113, 113, 434 | 113, 113, 113, 113, 113, 113, 113, 113, 435 | 113, 113, 113, 113, 113, 113, 113, 113, 436 | 113, 113, 113, 113, 113, 113, 113, 113, 437 | 113, 113, 113, 113, 113, 113, 113, 113, 438 | 113, 113, 113, 113, 113, 113, 113, 113, 439 | 113, 113, 113, 113, 113, 113, 113, 113, 440 | 113, 113, 113, 113, 113, 113, 113, 113, 441 | 113, 113, 113, 113, 113, 113, 113, 113, 442 | 113, 113, 113, 113, 113, 113, 113, 113, 443 | 113, 113, 113, 113, 113, 113, 113, 113, 444 | 113, 113, 113, 113, 113, 113, 113, 113, 445 | 113, 113, 113, 113, 113, 113, 113, 113, 446 | 113, 113, 113, 113, 113, 113, 113, 113, 447 | 113, 113, 113, 113, 113, 113, 113, 113, 448 | 113, 113, 113, 113, 113, 113, 113, 113, 449 | 113, 113, 113, 113, 113, 113, 113, 113, 450 | 113, 113, 113, 113, 113, 113, 113, 113, 451 | 113, 113, 113, 113, 113, 113, 113, 113, 452 | 113, 113, 113, 113, 113, 113, 113, 113, 453 | 113, 113, 113, 113, 113, 113, 113, 113, 454 | 113, 113, 113, 113, 113, 113, 113, 113, 455 | 113, 113, 113, 113, 113, 113, 113, 113, 456 | 113, 113, 113, 113, 113, 113, 113, 113, 457 | 113, 113, 113, 113, 113, 113, 113, 113, 458 | 113, 113, 113, 113, 113, 113, 113, 113, 459 | 113, 113, 113, 113, 113, 113, 113, 113, 460 | 113, 113, 113, 113, 113, 113, 113, 113, 461 | 113, 113, 113, 113, 113, 113, 113, 113, 462 | 113, 113, 113, 113, 113, 113, 113, 113, 463 | 113, 113, 113, 113, 113, 113, 113, 113, 464 | 113, 113, 113, 113, 113, 113, 113, 113, 465 | 113, 113, 113, 113, 113, 113, 113, 113, 466 | 113, 113, 113, 113, 113, 113, 113, 113, 467 | 113, 113, 113, 113, 113, 113, 113, 113, 468 | 113, 113, 113, 113, 113, 113, 113, 113, 469 | 113, 113, 113, 113, 113, 113, 113, 113, 470 | 113, 113, 113, 113, 113, 113, 113, 113, 471 | 113, 113, 113, 113, 113, 113, 113, 113, 472 | 113, 113, 113, 113, 113, 113, 113, 113, 473 | 113, 113, 113, 113, 113, 113, 113, 113, 474 | 113, 113, 113, 113, 113, 113, 113, 113, 475 | 113, 113, 113, 113, 113, 113, 113, 113, 476 | 113, 113, 113, 113, 113, 113, 113, 113, 477 | 113, 113, 113, 113, 113, 113, 113, 113, 478 | 113, 113, 113, 113, 113, 113, 113, 113, 479 | 113, 113, 113, 113, 113, 113, 113, 113, 480 | 113, 113, 113, 113, 113, 113, 113, 113, 481 | 113, 113, 113, 113, 113, 113, 113, 113, 482 | 113, 113, 113, 113, 113, 113, 113, 113, 483 | 113, 113, 113, 113, 113, 113, 113, 113, 484 | 113, 113, 113, 113, 113, 113, 113, 113, 485 | 113, 113, 113, 113, 113, 113, 113, 113, 486 | 113, 113, 113, 113, 113, 113, 113, 113, 487 | 113, 113, 113, 113, 113, 113, 113, 113, 488 | 113, 113, 113, 113, 113, 113, 113, 113, 489 | 113, 113, 113, 113, 113, 113, 113, 113, 490 | 113, 113, 113, 113, 113, 113, 113, 113, 491 | 113, 113, 113, 113, 113, 113, 113, 113, 492 | 113, 113, 113, 113, 113, 113, 113, 113, 493 | 113, 113, 113, 113, 113, 113, 113, 113, 494 | 113, 113, 113, 113, 113, 113, 113, 113, 495 | 113, 113, 113, 113, 113, 113, 113, 113, 496 | 113, 113, 113, 113, 113, 113, 113, 113, 497 | 113, 113, 113, 113, 113, 113, 113, 113, 498 | 113, 113, 113, 113, 113, 113, 113, 113, 499 | 113, 113, 113, 113, 113, 113, 113, 113, 500 | 113, 113, 113, 113, 113, 113, 113, 113, 501 | 113, 113, 113, 113, 113, 113, 113, 113, 502 | 113, 113, 113, 113, 113, 113, 113, 113, 503 | 113, 113, 113, 113, 113, 113, 113, 113, 504 | 113, 113, 113, 113, 113, 113, 113, 113, 505 | 113, 113, 113, 113, 113, 113, 113, 113, 506 | 113, 113, 113, 113, 113, 113, 113, 113, 507 | 113, 113, 113, 113, 113, 113, 113, 113, 508 | 113, 113, 113, 113, 113, 113, 113, 113, 509 | 113, 113, 113, 113, 113, 113, 113, 113, 510 | 113, 113, 113, 113, 113, 113, 113, 113, 511 | 113, 113, 113, 113, 113, 113, 113, 113, 512 | 113, 113, 113, 113, 113, 113, 113, 113, 513 | 113, 113, 113, 113, 113, 113, 113, 113, 514 | 113, 113, 113, 113, 113, 113, 113, 113, 515 | 113, 113, 113, 113, 113, 113, 113, 113, 516 | 113, 113, 113, 113, 113, 113, 113, 113, 517 | 113, 113, 113, 113, 113, 113, 113, 113, 518 | 113, 113, 113, 113, 113, 113, 113, 113, 519 | 113, 113, 113, 113, 113, 113, 113, 113, 520 | 113, 113, 113, 113, 113, 113, 113, 113, 521 | 113, 113, 113, 113, 113, 113, 113, 113, 522 | 113, 113, 113, 113, 113, 113, 113, 113, 523 | 113, 113, 113, 113, 113, 113, 113, 113, 524 | 113, 113, 113, 113, 113, 113, 113, 113, 525 | 113, 113, 113, 113, 113, 113, 113, 113, 526 | 113, 113, 113, 113, 113, 113, 113, 113, 527 | 113, 113, 113, 113, 113, 113, 113, 113, 528 | 113, 113, 113, 113, 113, 113, 113, 113, 529 | 113, 113, 113, 113, 113, 113, 113, 113, 530 | 113, 113, 113, 113, 113, 113, 113, 113, 531 | 113, 113, 113, 113, 113, 113, 113, 113, 532 | 113, 113, 113, 113, 113, 113, 113, 113, 533 | 113, 113, 113, 113, 113, 113, 113, 113, 534 | 113, 113, 113, 113, 113, 113, 113, 113, 535 | 113, 113, 113, 113, 113, 113, 113, 113, 536 | 113, 113, 113, 113, 113, 113, 113, 113, 537 | 113, 113, 113, 113, 113, 113, 113, 113, 538 | 113, 113, 113, 113, 113, 113, 113, 113, 539 | 113, 113, 113, 113, 113, 113, 113, 113, 540 | 113, 113, 113, 113, 113, 113, 113, 113, 541 | 113, 113, 113, 113, 113, 113, 113, 113, 542 | 113, 113, 113, 113, 113, 113, 113, 113, 543 | 113, 113, 113, 113, 113, 113, 113, 113, 544 | 113, 113, 113, 113, 113, 113, 113, 113, 545 | 113, 113, 113, 113, 113, 113, 113, 113, 546 | 113, 113, 113, 113, 113, 113, 113, 113, 547 | 113, 113, 113, 113, 113, 113, 113, 113, 548 | 113, 113, 113, 113, 113, 113, 113, 113, 549 | 113, 113, 113, 113, 113, 113, 113, 113, 550 | 113, 113, 113, 113, 113, 113, 113, 113, 551 | 113, 113, 113, 113, 113, 113, 113, 113, 552 | 113, 113, 113, 113, 113, 113, 113, 113, 553 | 113, 113, 113, 113, 113, 113, 113, 113, 554 | 113, 113, 113, 113, 113, 113, 113, 113, 555 | 113, 113, 113, 113, 113, 113, 113, 113, 556 | 113, 113, 113, 113, 113, 113, 113, 113, 557 | 113, 113, 113, 113, 113, 113, 113, 113, 558 | 113, 113, 113, 113, 113, 113, 113, 113, 559 | 113, 113, 113, 113, 113, 113, 113, 113, 560 | 113, 113, 113, 113, 113, 113, 113, 113, 561 | 113, 113, 113, 113, 113, 113, 113, 113, 562 | 113, 113, 113, 113, 113, 113, 113, 113, 563 | 113, 113, 113, 113, 113, 113, 113, 113, 564 | 113, 113, 113, 113, 113, 113, 113, 113, 565 | 113, 113, 113, 113, 113, 113, 113, 113, 566 | 113, 113, 113, 113, 113, 113, 113, 113, 567 | 113, 113, 113, 113, 113, 113, 113, 113, 568 | 113, 113, 113, 113, 113, 113, 113, 113, 569 | 113, 113, 113, 113, 113, 113, 113, 113, 570 | 113, 113, 113, 113, 113, 113, 113, 113, 571 | 113, 113, 113, 113, 113, 113, 113, 113, 572 | 113, 113, 113, 113, 113, 113, 113, 113, 573 | 113, 113, 113, 113, 113, 113, 113, 113, 574 | 113, 113, 113, 113, 113, 113, 113, 113, 575 | 113, 113, 113, 113, 113, 113, 113, 113, 576 | 113, 113, 113, 113, 113, 113, 113, 113, 577 | 113, 113, 113, 113, 113, 113, 113, 113, 578 | 113, 113, 113, 113, 113, 113, 113, 113, 579 | 113, 113, 113, 113, 113, 113, 113, 113, 580 | 113, 113, 113, 113, 113, 113, 113, 113, 581 | 113, 113, 113, 113, 113, 113, 113, 113, 582 | 113, 113, 113, 113, 113, 113, 113, 113, 583 | 113, 113, 113, 113, 113, 113, 113, 113, 584 | 113, 113, 113, 113, 113, 113, 113, 113, 585 | 113, 113, 113, 113, 113, 113, 113, 113, 586 | 113, 113, 113, 113, 113, 113, 113, 113, 587 | 113, 113, 113, 113, 113, 113, 113, 113, 588 | 113, 113, 113, 113, 113, 113, 113, 113, 589 | 113, 113, 113, 113, 113, 113, 113, 113, 590 | 113, 113, 113, 113, 113, 113, 113, 113, 591 | 113, 113, 113, 113, 113, 113, 113, 113, 592 | 113, 113, 113, 113, 113, 113, 113, 113, 593 | 113, 113, 113, 113, 113, 113, 113, 113, 594 | 113, 113, 113, 113, 113, 113, 113, 113, 595 | 113, 113, 113, 113, 113, 113, 113, 113, 596 | 113, 113, 113, 113, 113, 113, 113, 113, 597 | 113, 113, 113, 113, 113, 113, 113, 113, 598 | 113, 113, 113, 113, 113, 113, 113, 113, 599 | 113, 113, 113, 113, 113, 113, 113, 113, 600 | 113, 113, 113, 113, 113, 113, 113, 113, 601 | 113, 113, 113, 113, 113, 113, 113, 113, 602 | 113, 113, 113, 113, 113, 113, 113, 113, 603 | 113, 113, 113, 113, 113, 113, 113, 113, 604 | 113, 113, 113, 113, 113, 113, 113, 113, 605 | 113, 113, 113, 113, 113, 113, 113, 113, 606 | 113, 113, 113, 113, 113, 113, 113, 113, 607 | 113, 113, 113, 113, 113, 113, 113, 113, 608 | 113, 113, 113, 113, 113, 113, 113, 113, 609 | 113, 113, 113, 610 | ]; 611 | --------------------------------------------------------------------------------