diff --git a/src/ay.c b/src/ay.c index 70f4959..3fe0e81 100644 --- a/src/ay.c +++ b/src/ay.c @@ -3,6 +3,15 @@ #include "machine.h" static void ay_process_sample(AY_t *ay) +{ + ayumi_process(&ay->ayumi); + ayumi_remove_dc(&ay->ayumi); + ay->buf[ay->buf_pos] = 0.3 * ay->ayumi.left; + ay->buf[ay->buf_pos+1] = 0.3 * ay->ayumi.right; + ay->buf_pos += 2; +} + +static void ay_process_sample_fast(AY_t *ay) { ayumi_process_fast(&ay->ayumi); ayumi_remove_dc(&ay->ayumi); @@ -68,6 +77,13 @@ void ay_set_pan(AY_t *ay, double a, double b, double c, int equal_power) ayumi_set_pan(&ay->ayumi, 2, clamp(c, 0.0, 1.0), equal_power); } +void ay_set_quality(AY_t *ay, int high_quality) +{ + if (ay == NULL) return; + + ay->is_hq = high_quality; +} + void ay_reset(AY_t *ay) { if (ay == NULL) return; @@ -130,8 +146,15 @@ void ay_write_data(AY_t *ay, uint8_t value) } uint64_t write = ay->ctx->cpu.cycles / ay->samples_ratio; - for ( ; ay->last_write < write; ay->last_write++) { - ay_process_sample(ay); + + if (ay->is_hq) { + for ( ; ay->last_write < write; ay->last_write++) { + ay_process_sample(ay); + } + } else { + for ( ; ay->last_write < write; ay->last_write++) { + ay_process_sample_fast(ay); + } } } @@ -146,8 +169,14 @@ void ay_process_frame(AY_t *ay) { if (ay == NULL) return; - for ( ; ay->last_write < ay->samples_frame; ay->last_write++) { - ay_process_sample(ay); + if (ay->is_hq) { + for ( ; ay->last_write < ay->samples_frame; ay->last_write++) { + ay_process_sample(ay); + } + } else { + for ( ; ay->last_write < ay->samples_frame; ay->last_write++) { + ay_process_sample_fast(ay); + } } ay->last_write = 0; diff --git a/src/ay.h b/src/ay.h index d45a94e..07d243e 100644 --- a/src/ay.h +++ b/src/ay.h @@ -19,11 +19,13 @@ typedef struct AY size_t buf_pos; float *buf; struct Machine *ctx; + int is_hq; } AY_t; AY_t *ay_init(struct Machine *ctx, int sample_rate, double clock); void ay_deinit(AY_t *ay); void ay_set_pan(AY_t *ay, double a, double b, double c, int equal_power); +void ay_set_quality(AY_t *ay, int high_quality); void ay_reset(AY_t *ay); void ay_write_address(AY_t *ay, uint8_t value); void ay_write_data(AY_t *ay, uint8_t value); diff --git a/src/config.c b/src/config.c index 072085d..764bb2c 100644 --- a/src/config.c +++ b/src/config.c @@ -11,6 +11,7 @@ static struct CfgField fields[] = { {"ay-pan-b", CFG_FLOAT, NULL }, {"ay-pan-c", CFG_FLOAT, NULL }, {"ay-pan-equal-power", CFG_INT, NULL }, + {"ay-high-quality", CFG_INT, NULL }, }; CfgData_t g_config = { @@ -29,6 +30,7 @@ void config_defaults() config_set_float(&g_config, "ay-pan-b", 0.5); config_set_float(&g_config, "ay-pan-c", 0.75); config_set_int(&g_config, "ay-pan-equal-power", 1); + config_set_int(&g_config, "ay-high-quality", 0); } void config_init() diff --git a/src/main.c b/src/main.c index 2c90209..3d9c12a 100644 --- a/src/main.c +++ b/src/main.c @@ -112,6 +112,10 @@ int main(int argc, char *argv[]) config_get_int(&g_config, "ay-pan-equal-power", &pan_equal_power); ay_set_pan(m.ay, pan_a, pan_b, pan_c, pan_equal_power); + int ay_hq; + config_get_int(&g_config, "ay-high-quality", &ay_hq); + ay_set_quality(m.ay, ay_hq); + beeper_init(&m.beeper, &m, sample_rate); audio_sdl_init(sample_rate);