fixed audio buffer.
This commit is contained in:
parent
d3bc68924c
commit
2af25cc87c
@ -133,6 +133,7 @@ typedef struct {
|
|||||||
void audio_init();
|
void audio_init();
|
||||||
void audio_tick();
|
void audio_tick();
|
||||||
void audio_period_tick();
|
void audio_period_tick();
|
||||||
|
void lfsr_tick();
|
||||||
|
|
||||||
u8 audio_read(u16 address);
|
u8 audio_read(u16 address);
|
||||||
void audio_write(u16 address, u8 value);
|
void audio_write(u16 address, u8 value);
|
||||||
|
123
lib/audio.c
123
lib/audio.c
@ -15,7 +15,7 @@
|
|||||||
#define AUDIO_TICKS_PER_SAMPLE 2157281.28 / SAMPLE_RATE
|
#define AUDIO_TICKS_PER_SAMPLE 2157281.28 / SAMPLE_RATE
|
||||||
#define TIME_PER_WAVE_TICK 1.0f / (2104718.0f/1000.0f/1000.0f)
|
#define TIME_PER_WAVE_TICK 1.0f / (2104718.0f/1000.0f/1000.0f)
|
||||||
#define LFSR_BASE_CLOCK 262144.0f
|
#define LFSR_BASE_CLOCK 262144.0f
|
||||||
#define AUDIO_BUFFER_SIZE 102400
|
#define AUDIO_BUFFER_SIZE 10240
|
||||||
|
|
||||||
static audio_context ctx;
|
static audio_context ctx;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ audio_context *audio_get_context() {
|
|||||||
|
|
||||||
static float audio_time = 0;
|
static float audio_time = 0;
|
||||||
static float wave_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 = LFSR_BASE_CLOCK;
|
||||||
static float lfsr_clock_buffer = 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,
|
PaStreamCallbackFlags status_flags,
|
||||||
void *userData ) {
|
void *userData ) {
|
||||||
float *out = (float *)output_buffer;
|
float *out = (float *)output_buffer;
|
||||||
|
//while(ctx.buffer_cnt < framesPerBuffer*AUDIO_TICKS_PER_SAMPLE) {
|
||||||
|
// delay(1);
|
||||||
|
//}
|
||||||
for(int i = 0; i < framesPerBuffer; i++) {
|
for(int i = 0; i < framesPerBuffer; i++) {
|
||||||
samples_occured = samples_occured + AUDIO_TICKS_PER_SAMPLE;
|
//samples_occured = samples_occured + AUDIO_TICKS_PER_SAMPLE-1;
|
||||||
if(ctx.buffer_cnt < (u8)samples_occured) {
|
while(ctx.buffer_cnt == 0) {
|
||||||
|
//delay(1);
|
||||||
|
}
|
||||||
|
if(ctx.buffer_cnt == 0) {
|
||||||
//samples_occured = samples_occured - ((int)samples_occured - ctx.buffer_cnt);
|
//samples_occured = samples_occured - ((int)samples_occured - ctx.buffer_cnt);
|
||||||
//ctx.sq1_read_index = ctx.sq1_write_index-1;
|
//ctx.sq1_read_index = ctx.sq1_write_index-1;
|
||||||
//printf("buffer underflow\n");
|
//printf("buffer underflow\n");
|
||||||
|
return paContinue;
|
||||||
} else {
|
} else {
|
||||||
ctx.buffer_cnt -= (u8)samples_occured;
|
//ctx.buffer_cnt -= (u8)samples_occured;
|
||||||
ctx.sq1_read_index += (u8)samples_occured;
|
//ctx.sq1_read_index += (u8)samples_occured;
|
||||||
ctx.sq1_read_index %= AUDIO_BUFFER_SIZE;
|
//ctx.sq1_read_index %= AUDIO_BUFFER_SIZE;
|
||||||
samples_occured -= (u8)samples_occured;
|
//samples_occured -= (u8)samples_occured;
|
||||||
|
ctx.buffer_cnt--;
|
||||||
}
|
}
|
||||||
if(ppu_get_context()->paused) {
|
if(ppu_get_context()->paused) {
|
||||||
*out++ = 0;
|
*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];
|
left = ctx.sq1_audio_buffer[ctx.sq1_read_index];
|
||||||
right = ctx.sq2_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;
|
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;
|
right_out = 1;
|
||||||
}
|
}
|
||||||
history_timer++;
|
history_timer++;
|
||||||
if(history_timer >= history_interval){
|
if(history_timer >= 5){
|
||||||
history_timer = 0;
|
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;
|
ctx.left_history[ctx.left_index++] = left_out;
|
||||||
if (ctx.left_index == 384) {
|
if (ctx.left_index == 384) {
|
||||||
ctx.left_index = 0;
|
ctx.left_index = 0;
|
||||||
@ -338,9 +329,9 @@ void audio_init(){
|
|||||||
ctx.sq2_env_direction = false;
|
ctx.sq2_env_direction = false;
|
||||||
ctx.sq2_env_pace = 0x0;
|
ctx.sq2_env_pace = 0x0;
|
||||||
ctx.sq2_env_timer = 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.sq1_read_index = 0;
|
||||||
ctx.buffer_cnt = AUDIO_BUFFER_SIZE / 2;
|
ctx.buffer_cnt = 0;
|
||||||
|
|
||||||
err = Pa_Initialize();
|
err = Pa_Initialize();
|
||||||
if (err != paNoError) goto error;
|
if (err != paNoError) goto error;
|
||||||
@ -388,6 +379,21 @@ static u32 start = 0;
|
|||||||
static u32 period_tick;
|
static u32 period_tick;
|
||||||
static u32 samples_per_sec = 0;
|
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() {
|
void audio_period_tick() {
|
||||||
period_tick++;
|
period_tick++;
|
||||||
@ -432,18 +438,6 @@ void audio_period_tick() {
|
|||||||
ctx.ch3_last_sample = ctx.wave_ram[ctx.ch3_sample >> 1] >> 4;
|
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 left = 0;
|
||||||
float right = 0;
|
float right = 0;
|
||||||
@ -537,15 +531,40 @@ void audio_period_tick() {
|
|||||||
left *= (float)left_vol/7.0f;
|
left *= (float)left_vol/7.0f;
|
||||||
right *= (float)right_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.sq1_audio_buffer[(ctx.sq1_write_index)] = left;
|
||||||
ctx.sq2_audio_buffer[(ctx.sq1_write_index)] = right;
|
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.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.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.sq1_write_index = (ctx.sq1_write_index + 1) % AUDIO_BUFFER_SIZE;
|
||||||
ctx.buffer_cnt++;
|
ctx.buffer_cnt++;
|
||||||
} else {
|
|
||||||
//printf("buffer overflow\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,9 +711,6 @@ void enable_wave() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void enable_noise() {
|
void enable_noise() {
|
||||||
if(!ctx.ch4_dac){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ctx.ch4_enable = true;
|
ctx.ch4_enable = true;
|
||||||
ctx.ch4_env_timer = ctx.ch4_env_pace_buffer != 0 ? ctx.ch4_env_pace_buffer : 8;
|
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;
|
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_volume = ctx.ch4_initial_volume;
|
||||||
ctx.ch4_lfsr = 0;
|
ctx.ch4_lfsr = 0;
|
||||||
lfsr_clock = lfsr_clock_buffer;
|
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) {
|
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_clock_shift = (value >> 4) & 0xF;
|
||||||
ctx.ch4_lfsr_width = (value & 0x08);
|
ctx.ch4_lfsr_width = (value & 0x08);
|
||||||
ctx.ch4_clock_divider = value & 0b111;
|
ctx.ch4_clock_divider = value & 0b111;
|
||||||
float div = (ctx.ch4_clock_divider == 0 ? 0.5f : (float)ctx.ch4_clock_divider);
|
//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));
|
//float lfsr_rate = (LFSR_BASE_CLOCK) / (div * (float)(1 << ctx.ch4_clock_shift));
|
||||||
lfsr_clock_buffer = 1.0f / (lfsr_rate/1000.0f/1000.0f);
|
//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("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);
|
//printf("Write Ch4 Clock: %02X\n", value);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ void timer_tick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lfsr_tick();
|
||||||
|
|
||||||
if((prev_div & (1 << 12)) && (!(ctx.div & (1 << 12)))){
|
if((prev_div & (1 << 12)) && (!(ctx.div & (1 << 12)))){
|
||||||
audio_tick();
|
audio_tick();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user