From d576bbca55613cd442a36e285adec1d88abf38b9 Mon Sep 17 00:00:00 2001 From: Samuel Walker Date: Wed, 5 Feb 2025 15:49:53 -0700 Subject: [PATCH] passing audio test 4 --- include/audio.h | 3 ++ lib/audio.c | 125 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 90 insertions(+), 38 deletions(-) diff --git a/include/audio.h b/include/audio.h index 2625ada..a99a309 100644 --- a/include/audio.h +++ b/include/audio.h @@ -20,6 +20,9 @@ typedef struct { bool ch4_dac; bool ch1_len_fz; + bool ch2_len_fz; + bool ch3_len_fz; + bool ch4_len_fz; u8 volume_left; u8 volume_right; diff --git a/lib/audio.c b/lib/audio.c index 75d0198..23f0a9b 100644 --- a/lib/audio.c +++ b/lib/audio.c @@ -182,8 +182,8 @@ static int audio_callback(const void* input_uffer, void *output_buffer, if(dacs) { left_out = left - left_cap; right_out = right - right_cap; - left_cap = left - left_out * 0.996; - right_cap = right - right_out * 0.996; + left_cap = left - left_out * 0.996f; + right_cap = right - right_out * 0.996f; } *out++ = left_out; @@ -278,7 +278,7 @@ void sq1_sweep() { step = ctx.sq1_sweep_direction ? -step : step; ctx.sq1_calc_period = ctx.sq1_sweep_period + step; //overflow check - if(ctx.sq1_calc_period > 0x7FFF) { + if(ctx.sq1_calc_period > 0x7FF) { ctx.sq1_enable = false; } } @@ -304,6 +304,7 @@ void audio_tick(){ if(ctx.sq2_len >= 64) { ctx.sq2_len = 0; ctx.sq2_enable = false; + ctx.ch2_len_fz = true; } } @@ -311,6 +312,7 @@ void audio_tick(){ ctx.ch3_len++; if(ctx.ch3_len == 0) { ctx.ch3_enable = false; + ctx.ch3_len_fz = true; } } @@ -319,11 +321,12 @@ void audio_tick(){ if(ctx.ch4_len >= 64) { ctx.ch4_len = 0; ctx.ch4_enable = false; + ctx.ch4_len_fz = true; } } } - if((prev_ticks & (1 << 3)) && !(ticks & (1 << 3))) { + if((prev_ticks & (1 << 2)) && !(ticks & (1 << 2))) { if(ctx.sq1_env_pace != 0){ ctx.sq1_env_timer++; if(ctx.sq1_env_timer >= ctx.sq1_env_pace) { @@ -370,17 +373,17 @@ void audio_tick(){ } - if((prev_ticks & (1 << 2)) && !(ticks & (1 << 2))) { + if((prev_ticks & (1 << 1)) && !(ticks & (1 << 1))) { ctx.sq1_sweep_timer++; if(ctx.sq1_sweep_timer >= ctx.sq1_sweep_pace) { ctx.sq1_sweep_timer = 0; - if(ctx.sq1_enable && ctx.sq1_sweep_pace){ + if(ctx.sq1_enable && ctx.sq1_sweep_pace > 0 && ctx.sq1_sweep_enabled){ sq1_sweep(); - if(ctx.sq1_calc_period <= 0x7FFF && ctx.sq1_sweep_step != 0) { + if(ctx.sq1_calc_period <= 0x7FF && ctx.sq1_sweep_step != 0) { ctx.sq1_sweep_period = ctx.sq1_calc_period; ctx.sq1_period_reset = ctx.sq1_calc_period; + sq1_sweep(); } - sq1_sweep(); } } } @@ -396,8 +399,8 @@ void enable_square1() { ctx.sq1_sweep_timer = 0; ctx.sq1_env_direction = ctx.sq1_env_direction_buffer; ctx.sq1_env_pace = ctx.sq1_env_pace_buffer; - ctx.sq1_sweep_enabled = (ctx.sq1_sweep_pace || ctx.sq1_sweep_step); - if(ctx.sq1_sweep_step) { + ctx.sq1_sweep_enabled = ((ctx.sq1_sweep_pace != 0) || (ctx.sq1_sweep_step != 0)); + if(ctx.sq1_sweep_step != 0) { sq1_sweep(); } } @@ -407,9 +410,6 @@ void enable_square2() { return; } ctx.sq2_enable = true; - if(ctx.sq2_len >= 64) { - ctx.sq2_len = 0; - } ctx.sq2_volume = ctx.sq2_initial_volume; ctx.sq2_env_timer = 0; ctx.sq2_sample = 0; @@ -423,13 +423,9 @@ void enable_wave() { return; } ctx.ch3_enable = true; - if(ctx.ch3_len == 255) { - ctx.ch3_len = 0; - } ctx.ch3_sample = 0; ctx.ch3_volume = ctx.ch3_initial_volume; ctx.ch3_period_timer = ctx.ch3_period_reset; - printf("channel 3 enabled\n"); } void enable_noise() { @@ -437,9 +433,6 @@ void enable_noise() { return; } ctx.ch4_enable = true; - if(ctx.ch4_len >= 64) { - ctx.ch4_len = 0; - } ctx.ch4_env_timer = 0; ctx.ch4_env_direction = ctx.ch4_env_direction_buffer; ctx.ch4_env_pace = ctx.ch4_env_pace_buffer; @@ -454,7 +447,7 @@ u8 audio_read(u16 address) { return value | 0b01110000; } if(address == 0xFF25) { - u8 value; + u8 value = 0x0; value |= ctx.ch4_left << 7; value |= ctx.ch3_left << 6; value |= ctx.ch2_left << 5; @@ -464,6 +457,7 @@ u8 audio_read(u16 address) { value |= ctx.ch3_right << 2; value |= ctx.ch2_right << 1; value |= ctx.ch1_right; + //printf("read at %02X; Value: %02X\n", address, value); return value; } @@ -568,14 +562,14 @@ void reset_buffers(){ ctx.ch1_dac = 0; ctx.ch2_dac = 0; ctx.ch3_dac = 0; - ctx.ch1_left = 0; - ctx.ch1_right = 0; - ctx.ch2_left = 0; - ctx.ch2_right = 0; - ctx.ch3_left = 0; - ctx.ch3_right = 0; - ctx.ch4_left = 0; - ctx.ch4_right = 0; + ctx.ch1_left = false; + ctx.ch1_right = false; + ctx.ch2_left = false; + ctx.ch2_right = false; + ctx.ch3_left = false; + ctx.ch3_right = false; + ctx.ch4_left = false; + ctx.ch4_right = false; ctx.volume_left = 0; ctx.volume_right = 0; ctx.vin_left = 0; @@ -651,8 +645,9 @@ void audio_write(u16 address, u8 value){ } if(address == 0xFF26) { - ctx.audio_enabled = value & 0x80; + ctx.audio_enabled = (value & 0x80) == 0x80; if(!ctx.audio_enabled) { + //printf("audio disabled\n"); reset_buffers(); } } @@ -671,6 +666,7 @@ void audio_write(u16 address, u8 value){ ctx.ch3_right = value & 0b00000100; ctx.ch2_right = value & 0b00000010; ctx.ch1_right = value & 0b00000001; + //printf("write at %02X; Value: %02X\n", address, value); } if(address == 0xFF24) { @@ -691,8 +687,7 @@ void audio_write(u16 address, u8 value){ ctx.sq1_duty = value >> 6; ctx.sq1_initial_len = value & 0x3F; ctx.sq1_len = ctx.sq1_initial_len; - static bool unfreeze; - unfreeze = true; + ctx.ch1_len_fz = false; //printf("initial len: %02X\n", ctx.sq1_initial_len); } if(address == 0xFF12) { @@ -729,7 +724,6 @@ void audio_write(u16 address, u8 value){ ctx.sq1_len++; } } - printf("Value: %02X\n", value); ctx.sq1_len_enable = len_en; if(value & 0x80) { enable_square1(); @@ -741,6 +735,7 @@ void audio_write(u16 address, u8 value){ ctx.sq2_duty = value >> 6; ctx.sq2_initial_len = value & 0x3F; ctx.sq2_len = ctx.sq2_initial_len; + ctx.ch2_len_fz = false; } if(address == 0xFF17) { ctx.sq2_initial_volume = (value >> 4) & 0x0F; @@ -759,9 +754,27 @@ void audio_write(u16 address, u8 value){ //printf("period: %03X, old_period: %03X\n", ctx.sq2_period_reset, prev_period); } if(address == 0xFF19) { + if(ctx.sq2_len == 64) { + ctx.sq2_len = 0; + } ctx.sq2_period_reset = (ctx.sq2_period_reset & 0x0FF) | ((value & 0b111) << 8); - ctx.sq2_len_enable = (value & 0x40) == 0x40; - if((value & 0x80) == 0x80) { + bool len_en = (value & 0x40) == 0x40; + if((ticks % 2) == 0 && !ctx.ch2_len_fz && !ctx.sq2_len_enable && len_en){ + ctx.sq2_len++; + if(ctx.sq2_len >= 64) { + ctx.sq2_len = 0; + ctx.sq2_enable = false; + ctx.ch2_len_fz = true; + } + } + if((ticks % 2) == 0 && ctx.ch2_len_fz && (value & 0x80) == 0x80){ + ctx.ch2_len_fz = false; + if(len_en){ + ctx.sq2_len++; + } + } + ctx.sq2_len_enable = len_en; + if(value & 0x80) { enable_square2(); } } @@ -776,6 +789,7 @@ void audio_write(u16 address, u8 value){ if(address == 0xFF1B) { ctx.ch3_initial_len = value; ctx.ch3_len = ctx.ch3_initial_len; + ctx.ch3_len_fz = false; } if(address == 0xFF1C) { @@ -788,7 +802,23 @@ void audio_write(u16 address, u8 value){ if(address == 0xFF1E) { ctx.ch3_period_reset = (ctx.ch3_period_reset & 0x0FF) | ((value & 0b111) << 8); - ctx.ch3_len_enable = (value & 0x40) == 0x40; + bool len_en = (value & 0x40) == 0x40; + if((ticks % 2) == 0 && !ctx.ch3_len_fz && !ctx.ch3_len_enable && len_en){ + if(ctx.ch3_len >= 255) { + ctx.ch3_len = 0; + ctx.ch3_enable = false; + ctx.ch3_len_fz = true; + } else { + ctx.ch3_len++; + } + } + if((ticks % 2) == 0 && ctx.ch3_len_fz && (value & 0x80) == 0x80){ + ctx.ch3_len_fz = false; + if(len_en){ + ctx.ch3_len++; + } + } + ctx.ch3_len_enable = len_en; if(value & 0x80) { enable_wave(); } @@ -797,6 +827,7 @@ void audio_write(u16 address, u8 value){ if(address == 0xFF20) { ctx.ch4_initial_len = value & 0b111111; ctx.ch4_len = ctx.ch4_initial_len; + ctx.ch4_len_fz = false; } if(address == 0xFF21) { @@ -821,8 +852,26 @@ void audio_write(u16 address, u8 value){ } if(address == 0xFF23) { - ctx.ch4_len_enable = (value & 0x40) == 0x40; - if((value & 0x80) == 0x80) { + if(ctx.ch4_len == 64) { + ctx.ch4_len = 0; + } + bool len_en = (value & 0x40) == 0x40; + if((ticks % 2) == 0 && !ctx.ch4_len_fz && !ctx.ch4_len_enable && len_en){ + ctx.ch4_len++; + if(ctx.ch4_len >= 64) { + ctx.ch4_len = 0; + ctx.ch4_enable = false; + ctx.ch4_len_fz = true; + } + } + if((ticks % 2) == 0 && ctx.ch4_len_fz && (value & 0x80) == 0x80){ + ctx.ch4_len_fz = false; + if(len_en){ + ctx.ch4_len++; + } + } + ctx.ch4_len_enable = len_en; + if(value & 0x80) { enable_noise(); } }