2024-07-30 04:15:50 -04:00
|
|
|
#ifndef SID3_H
|
|
|
|
#define SID3_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
#define SID3_NUM_CHANNELS 7
|
|
|
|
#define SID3_NUM_FILTERS 4
|
2024-07-30 05:00:05 -04:00
|
|
|
#define SID3_REGISTERS_PER_CHANNEL 32
|
|
|
|
#define SID3_NUM_REGISTERS (SID3_NUM_CHANNELS * SID3_REGISTERS_PER_CHANNEL)
|
2024-07-30 04:15:50 -04:00
|
|
|
#define SID3_MAX_VOL 255
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
#define SID3_WAVETABLE_LENGTH 256
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
#define SID3_NUM_SPECIAL_WAVES 28
|
|
|
|
#define SID3_SPECIAL_WAVE_LENGTH 16384
|
|
|
|
|
2024-07-30 14:01:17 -04:00
|
|
|
#define SID3_ACC_BITS 30
|
|
|
|
#define SID3_ACC_MASK ((1UL << SID3_ACC_BITS) - 1)
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
SID3_CHAN_ENABLE_GATE = 1,
|
|
|
|
SID3_CHAN_ENABLE_RING_MOD = 2,
|
|
|
|
SID3_CHAN_ENABLE_HARD_SYNC = 4,
|
|
|
|
SID3_CHAN_ENABLE_PHASE_MOD = 8,
|
|
|
|
SID3_CHAN_PHASE_RESET = 16,
|
|
|
|
SID3_CHAN_ENV_RESET = 32,
|
|
|
|
SID3_CHAN_NOISE_PHASE_RESET = 64,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Waveforms
|
|
|
|
{
|
|
|
|
SID3_WAVE_TRIANGLE = 1,
|
|
|
|
SID3_WAVE_SAW = 2,
|
|
|
|
SID3_WAVE_PULSE = 4,
|
|
|
|
SID3_WAVE_NOISE = 8,
|
|
|
|
SID3_WAVE_SPECIAL = 16,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Mixmodes
|
|
|
|
{
|
|
|
|
SID3_MIX_8580 = 0,
|
|
|
|
SID3_MIX_8580_WITH_NOISE = 1,
|
|
|
|
SID3_MIX_AND = 2,
|
|
|
|
SID3_MIX_OR = 3,
|
|
|
|
SID3_MIX_XOR = 4,
|
|
|
|
SID3_MIX_SUM = 5,
|
|
|
|
};
|
2024-07-30 04:15:50 -04:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2024-07-31 02:21:09 -04:00
|
|
|
int32_t input;
|
|
|
|
int32_t output;
|
2024-07-30 04:15:50 -04:00
|
|
|
|
|
|
|
// State of filter.
|
|
|
|
float Vhp; // highpass
|
|
|
|
float Vbp; // bandpass
|
|
|
|
float Vlp; // lowpass
|
|
|
|
|
|
|
|
// Cutoff frequency, resonance.
|
|
|
|
float w0, w0_ceil_1;
|
|
|
|
float _1024_div_Q;
|
2024-07-30 04:30:39 -04:00
|
|
|
|
|
|
|
uint16_t cutoff;
|
|
|
|
uint8_t resonance;
|
2024-07-30 05:15:33 -04:00
|
|
|
uint8_t distortion_level;
|
2024-07-30 11:15:08 -04:00
|
|
|
|
|
|
|
uint8_t mode;
|
|
|
|
|
|
|
|
bool channel_output; //output to the channel master output
|
2024-07-30 04:15:50 -04:00
|
|
|
} sid3_filter;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
sid3_filter filt[SID3_NUM_FILTERS];
|
|
|
|
uint32_t connection_matrix;
|
|
|
|
} sid3_filters_block;
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t a, d, s, sr, r, vol, state;
|
|
|
|
|
|
|
|
uint32_t rate_counter;
|
|
|
|
uint32_t rate_period;
|
|
|
|
uint16_t exponential_counter;
|
|
|
|
uint16_t exponential_counter_period;
|
|
|
|
uint8_t envelope_counter;
|
|
|
|
bool hold_zero;
|
2024-07-30 04:30:39 -04:00
|
|
|
} sid3_channel_adsr;
|
|
|
|
|
2024-07-30 04:15:50 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t accumulator;
|
2024-07-30 14:01:17 -04:00
|
|
|
uint8_t sync_bit;
|
2024-07-30 04:15:50 -04:00
|
|
|
uint32_t frequency;
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
uint32_t noise_accumulator;
|
|
|
|
uint32_t noise_frequency;
|
|
|
|
|
|
|
|
uint32_t lfsr, lfsr_taps;
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t waveform;
|
|
|
|
uint8_t special_wave;
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
uint16_t pw;
|
|
|
|
|
|
|
|
uint8_t mix_mode;
|
|
|
|
|
|
|
|
sid3_channel_adsr adsr;
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t flags;
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
uint8_t ring_mod_src;
|
|
|
|
uint8_t hard_sync_src;
|
|
|
|
uint8_t phase_mod_source;
|
|
|
|
|
2024-07-30 04:15:50 -04:00
|
|
|
sid3_filters_block filt;
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t panning_left, panning_right;
|
2024-07-31 02:21:09 -04:00
|
|
|
bool invert_left, invert_right; //invert channel signal
|
2024-07-30 04:15:50 -04:00
|
|
|
} sid3_channel;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t accumulator;
|
2024-07-30 14:01:17 -04:00
|
|
|
uint8_t sync_bit;
|
2024-07-30 04:15:50 -04:00
|
|
|
uint32_t frequency;
|
|
|
|
|
|
|
|
uint16_t streamed_sample;
|
|
|
|
uint8_t wavetable[SID3_WAVETABLE_LENGTH];
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t wave_address;
|
|
|
|
|
2024-07-30 04:30:39 -04:00
|
|
|
sid3_channel_adsr adsr;
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t flags;
|
|
|
|
uint8_t mode;
|
|
|
|
|
2024-07-30 04:15:50 -04:00
|
|
|
sid3_filters_block filt;
|
|
|
|
|
2024-07-30 11:15:08 -04:00
|
|
|
uint8_t panning_left, panning_right;
|
2024-07-31 02:21:09 -04:00
|
|
|
bool invert_left, invert_right; //invert channel signal
|
2024-07-30 04:15:50 -04:00
|
|
|
} sid3_wavetable_chan;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2024-07-30 11:15:08 -04:00
|
|
|
uint16_t special_waves[SID3_NUM_SPECIAL_WAVES][SID3_SPECIAL_WAVE_LENGTH]; //sine wave and OPL3-ish waves + OPZ and YMF825 waves!
|
2024-07-30 04:30:39 -04:00
|
|
|
|
2024-07-30 04:15:50 -04:00
|
|
|
sid3_channel chan[SID3_NUM_CHANNELS - 1];
|
|
|
|
sid3_wavetable_chan wave_chan;
|
|
|
|
|
2024-07-31 02:21:09 -04:00
|
|
|
int32_t output_l, output_r;
|
|
|
|
|
|
|
|
int32_t channel_output[SID3_NUM_CHANNELS];
|
2024-07-30 04:15:50 -04:00
|
|
|
|
|
|
|
//emulation-only helpers
|
|
|
|
bool muted[SID3_NUM_CHANNELS];
|
|
|
|
} SID3;
|
|
|
|
|
|
|
|
SID3* sid3_create();
|
|
|
|
void sid3_reset(SID3* sid3);
|
|
|
|
void sid3_write(SID3* sid3, uint8_t address, uint8_t data);
|
|
|
|
void sid3_clock(SID3* sid3);
|
|
|
|
void sid3_set_is_muted(SID3* sid3, uint8_t ch, bool mute);
|
|
|
|
void sid3_free(SID3* sid3);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|