public class SID extends Object
| Modifier and Type | Class and Description |
|---|---|
static class |
SID.CycleCount |
static class |
SID.FCPoints |
static class |
SID.State
Read/Write State.
|
| Modifier and Type | Field and Description |
|---|---|
static boolean |
ANTTI_LANKILA_PATCH
This is a patch against ReSID
engine in libsidplay2-2.1.1 to make its sound closer to 6581R4
chip.
|
protected int |
bus_value |
protected int |
bus_value_ttl |
protected double |
clock_frequency |
protected int |
cycles_per_sample
Sampling variables.
|
protected int |
ext_in
External audio input.
|
protected ExternalFilter |
extfilt |
Filter |
filter |
protected short[] |
fir
FIR_RES filter tables (FIR_N*FIR_RES).
|
protected int |
fir_N
Sampling variables.
|
protected static int |
FIR_N
Resampling constants.
|
protected int |
fir_RES
Sampling variables.
|
protected static int |
FIR_RES_FAST
Resampling constants.
|
protected static int |
FIR_RES_INTERPOLATE
Resampling constants.
|
protected static int |
FIR_SHIFT
Resampling constants.
|
protected static int |
FIXP_MASK
Fixpoint constants (16.16 bits).
|
protected static int |
FIXP_SHIFT
Fixpoint constants (16.16 bits).
|
protected Potentiometer |
potx |
protected Potentiometer |
poty |
protected static int |
RINGSIZE
Resampling constants.
|
protected short[] |
sample
Ring buffer with overflow for contiguous storage of RINGSIZE samples.
|
protected int |
sample_index
Sampling variables.
|
protected int |
sample_offset
Sampling variables.
|
protected short |
sample_prev
Sampling variables.
|
protected ISIDDefs.sampling_method |
sampling
Sampling variables.
|
protected Voice[] |
voice |
| Constructor and Description |
|---|
SID()
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
void |
adjust_sampling_frequency(double sample_freq)
Adjustment of SID sampling frequency.
|
protected int |
clock_fast(SID.CycleCount delta_t,
short[] buf,
int n,
int interleave)
SID clocking with audio sampling - delta clocking picking nearest sample.
|
protected int |
clock_interpolate(SID.CycleCount delta_t,
short[] buf,
int n,
int interleave)
SID clocking with audio sampling - cycle based with linear sample
interpolation.
|
protected int |
clock_resample_fast(SID.CycleCount delta_t,
short[] buf,
int n,
int interleave)
SID clocking with audio sampling - cycle based with audio resampling.
|
protected int |
clock_resample_interpolate(SID.CycleCount delta_t,
short[] buf,
int n,
int interleave)
SID clocking with audio sampling - cycle based with audio resampling.
|
void |
clock()
SID clocking - 1 cycle.
|
void |
clock(int delta_t)
SID clocking - delta_t cycles.
|
int |
clock(SID.CycleCount delta_t,
short[] buf,
int n,
int interleave)
SID clocking with audio sampling.
|
void |
enable_external_filter(boolean enable)
Enable external filter.
|
void |
enable_filter(boolean enable)
Enable filter.
|
void |
fc_default(SID.FCPoints fcp) |
PointPlotter |
fc_plotter()
Return FC spline plotter object.
|
protected double |
I0(double x)
I0() computes the 0th order modified Bessel function of the first kind.
|
void |
input(int sample)
16-bit input (EXT IN).
|
void |
mute(int channel,
boolean enable)
SID voice muting.
|
int |
output()
16-bit output (AUDIO OUT).
|
int |
output(int bits)
n-bit output.
|
SID.State |
read_state()
Read state.
|
int |
read(int offset)
Read registers.
|
void |
reset()
SID reset.
|
void |
set_chip_model(ISIDDefs.chip_model model)
Set chip model.
|
void |
set_distortion_properties(int Lt,
int Ls,
int Ll,
int Lb,
int Lh,
int Ht,
int Hs,
int Hl,
int Hb,
int Hh) |
boolean |
set_sampling_parameters(double clock_freq,
ISIDDefs.sampling_method method,
double sample_freq,
double pass_freq,
double filter_scale)
Setting of SID sampling parameters.
|
void |
write_state(SID.State state)
Write state.
|
void |
write(int offset,
int value)
Write registers.
|
public static boolean ANTTI_LANKILA_PATCH
Good simulation of strong lead and bass distortion. Tel's leads, Jeff's bass, Mechanicus's extreme distortion: it all seems to reproduce quite nicely.
Good simulation of advanced effects peculiar to 6581, especially on Jeff's songs that target 6581R4.
Parameters are now in sidplay2.ini file. No recompile is necessary when testing alternative parameters.
Bugs in some songs, especially related to lowpass filter output. The middle part of Spaceman Salutes Commodore and intro for Snake Disco are incorrectly rendered. (ReSID's linear filter is totally wrong with them too.) Vendetta probably gets too much edge in the bass, too. It seems that some kind of additional low-pass filtering needs to happen during so far unknown filter conditions.
protected Voice[] voice
public Filter filter
protected ExternalFilter extfilt
protected Potentiometer potx
protected Potentiometer poty
protected int bus_value
protected int bus_value_ttl
protected double clock_frequency
protected int ext_in
protected static final int FIR_N
protected static final int FIR_RES_INTERPOLATE
protected static final int FIR_RES_FAST
protected static final int FIR_SHIFT
protected static final int RINGSIZE
protected static final int FIXP_SHIFT
protected static final int FIXP_MASK
protected ISIDDefs.sampling_method sampling
protected int cycles_per_sample
protected int sample_offset
protected int sample_index
protected short sample_prev
protected int fir_N
protected int fir_RES
protected short[] sample
protected short[] fir
public void set_chip_model(ISIDDefs.chip_model model)
model - public void set_distortion_properties(int Lt,
int Ls,
int Ll,
int Lb,
int Lh,
int Ht,
int Hs,
int Hl,
int Hb,
int Hh)
public void reset()
public void input(int sample)
sample - public int output()
public int output(int bits)
bits - public int read(int offset)
Reading a write only register returns the last byte written to any SID register. The individual bits in this value start to fade down towards zero after a few cycles. All bits reach zero within approximately $2000 - $4000 cycles. It has been claimed that this fading happens in an orderly fashion, however sampling of write only registers reveals that this is not the case. NB! This is not correctly modeled. The actual use of write only registers has largely been made in the belief that all SID registers are readable. To support this belief the read would have to be done immediately after a write to the same register (remember that an intermediate write to another register would yield that value instead). With this in mind we return the last value written to any SID register for $2000 cycles without modeling the bit fading.
offset - public void write(int offset,
int value)
offset - value - public void mute(int channel,
boolean enable)
channel - enable - public SID.State read_state()
public void write_state(SID.State state)
state - public void enable_filter(boolean enable)
enable - public void enable_external_filter(boolean enable)
enable - protected double I0(double x)
x - public boolean set_sampling_parameters(double clock_freq,
ISIDDefs.sampling_method method,
double sample_freq,
double pass_freq,
double filter_scale)
Use a clock freqency of 985248Hz for PAL C64, 1022730Hz for NTSC C64. The default end of passband frequency is pass_freq = 0.9*sample_freq/2 for sample frequencies up to ~ 44.1kHz, and 20kHz for higher sample frequencies.
For resampling, the ratio between the clock frequency and the sample frequency is limited as follows: 125*clock_freq/sample_freq < 16384 E.g. provided a clock frequency of ~ 1MHz, the sample frequency can not be set lower than ~ 8kHz. A lower sample frequency would make the resampling code overfill its 16k sample ring buffer.
The end of passband frequency is also limited: pass_freq <= 0.9*sample_freq/2
E.g. for a 44.1kHz sampling rate the end of passband frequency is limited to slightly below 20kHz. This constraint ensures that the FIR table is not overfilled.
clock_freq - method - sample_freq - pass_freq - filter_scale - public void adjust_sampling_frequency(double sample_freq)
In some applications, e.g. a C64 emulator, it can be desirable to synchronize sound with a timer source. This is supported by adjustment of the SID sampling frequency.
NB! Adjustment of the sampling frequency may lead to noticeable shifts in frequency, and should only be used for interactive applications. Note also that any adjustment of the sampling frequency will change the characteristics of the resampling filter, since the filter is not rebuilt.
sample_freq - public void fc_default(SID.FCPoints fcp)
public PointPlotter fc_plotter()
public void clock()
public void clock(int delta_t)
delta_t - public int clock(SID.CycleCount delta_t, short[] buf, int n, int interleave)
The example below shows how to clock the SID a specified amount of cycles while producing audio output:
while (delta_t) {
bufindex += sid.clock(delta_t, buf + bufindex, buflength - bufindex);
write(dsp, buf, bufindex * 2);
bufindex = 0;
}
protected int clock_fast(SID.CycleCount delta_t, short[] buf, int n, int interleave)
protected int clock_interpolate(SID.CycleCount delta_t, short[] buf, int n, int interleave)
Here the chip is clocked every cycle. This yields higher quality sound since the samples are linearly interpolated, and since the external filter attenuates frequencies above 16kHz, thus reducing sampling noise.
protected int clock_resample_interpolate(SID.CycleCount delta_t, short[] buf, int n, int interleave)
This is the theoretically correct (and computationally intensive) audio sample generation. The samples are generated by resampling to the specified sampling frequency. The work rate is inversely proportional to the percentage of the bandwidth allocated to the filter transition band.
This implementation is based on the paper "A Flexible Sampling-Rate Conversion Method", by J. O. Smith and P. Gosset, or rather on the expanded tutorial on the "Digital Audio Resampling Home Page": http://www-ccrma.stanford.edu/~jos/resample/
By building shifted FIR tables with samples according to the sampling frequency, this implementation dramatically reduces the computational effort in the filter convolutions, without any loss of accuracy. The filter convolutions are also vectorizable on current hardware.
Further possible optimizations are: * An equiripple filter design could yield a lower filter order, see http://www.mwrf.com/Articles/ArticleID/7229/7229.html * The Convolution Theorem could be used to bring the complexity of convolution down from O(n*n) to O(n*log(n)) using the Fast Fourier Transform, see http://en.wikipedia.org/wiki/Convolution_theorem * Simply resampling in two steps can also yield computational savings, since the transition band will be wider in the first step and the required filter order is thus lower in this step. Laurent Ganier has found the optimal intermediate sampling frequency to be (via derivation of sum of two steps): 2 * pass_freq + sqrt [ 2 * pass_freq * orig_sample_freq * (dest_sample_freq - 2 * pass_freq) / dest_sample_freq ]
protected int clock_resample_fast(SID.CycleCount delta_t, short[] buf, int n, int interleave)
Copyright © 2014. All rights reserved.