diff --git a/include/audio.h b/include/audio.h index 20ef058..001d83c 100644 --- a/include/audio.h +++ b/include/audio.h @@ -133,6 +133,7 @@ typedef struct { void audio_init(); void audio_tick(); void audio_period_tick(); +void lfsr_tick(); u8 audio_read(u16 address); void audio_write(u16 address, u8 value); diff --git a/lib/audio.c b/lib/audio.c index f1f4b3b..faa9cb4 100644 --- a/lib/audio.c +++ b/lib/audio.c @@ -15,7 +15,7 @@ #define AUDIO_TICKS_PER_SAMPLE 2157281.28 / SAMPLE_RATE #define TIME_PER_WAVE_TICK 1.0f / (2104718.0f/1000.0f/1000.0f) #define LFSR_BASE_CLOCK 262144.0f -#define AUDIO_BUFFER_SIZE 102400 +#define AUDIO_BUFFER_SIZE 10240 static audio_context ctx; @@ -25,7 +25,7 @@ audio_context *audio_get_context() { static float audio_time = 0; static float wave_time = 0; -static float lfsr_timer = 0; +static u32 lfsr_timer = 0; static float lfsr_clock = LFSR_BASE_CLOCK; static float lfsr_clock_buffer = LFSR_BASE_CLOCK; @@ -94,17 +94,25 @@ static int audio_callback(const void* input_uffer, void *output_buffer, PaStreamCallbackFlags status_flags, void *userData ) { float *out = (float *)output_buffer; + //while(ctx.buffer_cnt < framesPerBuffer*AUDIO_TICKS_PER_SAMPLE) { + // delay(1); + //} for(int i = 0; i < framesPerBuffer; i++) { - samples_occured = samples_occured + AUDIO_TICKS_PER_SAMPLE; - if(ctx.buffer_cnt < (u8)samples_occured) { + //samples_occured = samples_occured + AUDIO_TICKS_PER_SAMPLE-1; + while(ctx.buffer_cnt == 0) { + //delay(1); + } + if(ctx.buffer_cnt == 0) { //samples_occured = samples_occured - ((int)samples_occured - ctx.buffer_cnt); //ctx.sq1_read_index = ctx.sq1_write_index-1; //printf("buffer underflow\n"); + return paContinue; } else { - ctx.buffer_cnt -= (u8)samples_occured; - ctx.sq1_read_index += (u8)samples_occured; - ctx.sq1_read_index %= AUDIO_BUFFER_SIZE; - samples_occured -= (u8)samples_occured; + //ctx.buffer_cnt -= (u8)samples_occured; + //ctx.sq1_read_index += (u8)samples_occured; + //ctx.sq1_read_index %= AUDIO_BUFFER_SIZE; + //samples_occured -= (u8)samples_occured; + ctx.buffer_cnt--; } if(ppu_get_context()->paused) { *out++ = 0; @@ -211,6 +219,8 @@ static int audio_callback(const void* input_uffer, void *output_buffer, left = ctx.sq1_audio_buffer[ctx.sq1_read_index]; right = ctx.sq2_audio_buffer[ctx.sq1_read_index]; + ctx.sq1_read_index++; + ctx.sq1_read_index %= AUDIO_BUFFER_SIZE; bool dacs = ctx.ch1_dac || ctx.ch2_dac || ctx.ch3_dac || ctx.ch4_dac; @@ -240,27 +250,8 @@ static int audio_callback(const void* input_uffer, void *output_buffer, right_out = 1; } history_timer++; - if(history_timer >= history_interval){ + if(history_timer >= 5){ history_timer = 0; - ctx.sq1_history[ctx.sq1_index++] = sq1_val; - if (ctx.sq1_index == 384) { - ctx.sq1_index = 0; - } - - ctx.sq2_history[ctx.sq2_index++] = sq2_val; - if (ctx.sq2_index == 384) { - ctx.sq2_index = 0; - } - - ctx.ch3_history[ctx.ch3_index++] = ch3_val; - if (ctx.ch3_index == 384) { - ctx.ch3_index = 0; - } - - ctx.ch4_history[ctx.ch4_index++] = ch4_val; - if (ctx.ch4_index == 384) { - ctx.ch4_index = 0; - } ctx.left_history[ctx.left_index++] = left_out; if (ctx.left_index == 384) { ctx.left_index = 0; @@ -338,9 +329,9 @@ void audio_init(){ ctx.sq2_env_direction = false; ctx.sq2_env_pace = 0x0; ctx.sq2_env_timer = 0x0; - ctx.sq1_write_index = AUDIO_BUFFER_SIZE / 2; + ctx.sq1_write_index = 0; ctx.sq1_read_index = 0; - ctx.buffer_cnt = AUDIO_BUFFER_SIZE / 2; + ctx.buffer_cnt = 0; err = Pa_Initialize(); if (err != paNoError) goto error; @@ -388,6 +379,21 @@ static u32 start = 0; static u32 period_tick; static u32 samples_per_sec = 0; +void lfsr_tick() { + lfsr_timer--; + if(lfsr_timer == 0) { + lfsr_timer = (ctx.ch4_clock_divider > 0 ? (ctx.ch4_clock_divider << 4) : 8) << ctx.ch4_clock_shift; + unsigned bit_mask = ctx.ch4_lfsr_width ? 0x4040 : 0x4000; + bool new_bit = (ctx.ch4_lfsr ^ (ctx.ch4_lfsr >> 1) ^ 1) & 1; + ctx.ch4_lfsr >>= 1; + if(new_bit) { + ctx.ch4_lfsr |= bit_mask; + } else { + ctx.ch4_lfsr &= ~bit_mask; + } + } +} + void audio_period_tick() { period_tick++; @@ -432,18 +438,6 @@ void audio_period_tick() { ctx.ch3_last_sample = ctx.wave_ram[ctx.ch3_sample >> 1] >> 4; } } - lfsr_timer--; - if(lfsr_timer == 0) { - lfsr_timer = (ctx.ch4_clock_divider > 0 ? (ctx.ch4_clock_divider << 4) : 8) << ctx.ch4_clock_shift; - unsigned bit_mask = ctx.ch4_lfsr_width ? 0x4040 : 0x4000; - bool new_bit = (ctx.ch4_lfsr ^ (ctx.ch4_lfsr >> 1) ^ 1) & 1; - ctx.ch4_lfsr >>= 1; - if(new_bit) { - ctx.ch4_lfsr |= bit_mask; - } else { - ctx.ch4_lfsr &= ~bit_mask; - } - } float left = 0; float right = 0; @@ -537,15 +531,40 @@ void audio_period_tick() { left *= (float)left_vol/7.0f; right *= (float)right_vol/7.0f; - if(ctx.buffer_cnt < AUDIO_BUFFER_SIZE){ + if(period_tick % 100 == 0){ + ctx.sq1_history[ctx.sq1_index++] = sq1_val; + if (ctx.sq1_index == 384) { + ctx.sq1_index = 0; + } + + ctx.sq2_history[ctx.sq2_index++] = sq2_val; + if (ctx.sq2_index == 384) { + ctx.sq2_index = 0; + } + + ctx.ch3_history[ctx.ch3_index++] = ch3_val; + if (ctx.ch3_index == 384) { + ctx.ch3_index = 0; + } + + ctx.ch4_history[ctx.ch4_index++] = ch4_val; + if (ctx.ch4_index == 384) { + ctx.ch4_index = 0; + } + } + + if((period_tick % (int)(AUDIO_TICKS_PER_SAMPLE)) == 0){ + //printf("tick\n"); + while(ctx.buffer_cnt == AUDIO_BUFFER_SIZE){ + //delay(1); + //printf("overflow\n"); + } ctx.sq1_audio_buffer[(ctx.sq1_write_index)] = left; ctx.sq2_audio_buffer[(ctx.sq1_write_index)] = right; //ctx.ch3_audio_buffer[(ctx.sq1_write_index)] = (((float)(ctx.ch3_last_sample >> shift)-7.5f)/7.5f); //ctx.ch4_audio_buffer[(ctx.sq1_write_index)] = (ctx.ch4_lfsr & 0b1) ? (float)(ctx.ch4_volume-7.5f)/7.5f : -1.0f; ctx.sq1_write_index = (ctx.sq1_write_index + 1) % AUDIO_BUFFER_SIZE; ctx.buffer_cnt++; - } else { - //printf("buffer overflow\n"); } } @@ -692,9 +711,6 @@ void enable_wave() { } void enable_noise() { - if(!ctx.ch4_dac){ - return; - } ctx.ch4_enable = true; ctx.ch4_env_timer = ctx.ch4_env_pace_buffer != 0 ? ctx.ch4_env_pace_buffer : 8; ctx.ch4_env_direction = ctx.ch4_env_direction_buffer; @@ -702,7 +718,10 @@ void enable_noise() { ctx.ch4_volume = ctx.ch4_initial_volume; ctx.ch4_lfsr = 0; lfsr_clock = lfsr_clock_buffer; - lfsr_timer = (ctx.ch4_clock_divider > 0 ? (ctx.ch4_clock_divider << 8) : 8) << ctx.ch4_clock_shift; + lfsr_timer = (ctx.ch4_clock_divider > 0 ? (ctx.ch4_clock_divider << 4) : 8) << ctx.ch4_clock_shift; + if(!ctx.ch4_dac){ + ctx.ch4_enable = false; + } } u8 audio_read(u16 address) { @@ -1117,9 +1136,9 @@ void audio_write(u16 address, u8 value){ ctx.ch4_clock_shift = (value >> 4) & 0xF; ctx.ch4_lfsr_width = (value & 0x08); ctx.ch4_clock_divider = value & 0b111; - float div = (ctx.ch4_clock_divider == 0 ? 0.5f : (float)ctx.ch4_clock_divider); - float lfsr_rate = (LFSR_BASE_CLOCK) / (div * (float)(1 << ctx.ch4_clock_shift)); - lfsr_clock_buffer = 1.0f / (lfsr_rate/1000.0f/1000.0f); + //float div = (ctx.ch4_clock_divider == 0 ? 0.5f : (float)ctx.ch4_clock_divider); + //float lfsr_rate = (LFSR_BASE_CLOCK) / (div * (float)(1 << ctx.ch4_clock_shift)); + //lfsr_clock_buffer = 1.0f / (lfsr_rate/1000.0f/1000.0f); //printf("Ch4 clock: Shift: %01X, Width: %d, Div: %f (%01X), Rate: %f, Clock %f\n", ctx.ch4_clock_shift, ctx.ch4_lfsr_width, div, ctx.ch4_clock_divider, lfsr_rate, lfsr_clock); //printf("Write Ch4 Clock: %02X\n", value); } diff --git a/lib/timer.c b/lib/timer.c index 41346f5..46a5139 100644 --- a/lib/timer.c +++ b/lib/timer.c @@ -39,6 +39,8 @@ void timer_tick() { } } + lfsr_tick(); + if((prev_div & (1 << 12)) && (!(ctx.div & (1 << 12)))){ audio_tick(); }