Passing audio test 1.
This commit is contained in:
parent
0518c079cc
commit
91b7d704cd
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -5,6 +5,8 @@
|
|||||||
"string.h": "c",
|
"string.h": "c",
|
||||||
"common.h": "c",
|
"common.h": "c",
|
||||||
"ppu.h": "c",
|
"ppu.h": "c",
|
||||||
"profileapi.h": "c"
|
"profileapi.h": "c",
|
||||||
|
"type_traits": "c",
|
||||||
|
"xtr1common": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,6 +17,8 @@ typedef struct {
|
|||||||
|
|
||||||
u8 volume_left;
|
u8 volume_left;
|
||||||
u8 volume_right;
|
u8 volume_right;
|
||||||
|
bool vin_left;
|
||||||
|
bool vin_right;
|
||||||
|
|
||||||
u8 sq1_duty;
|
u8 sq1_duty;
|
||||||
u8 sq1_volume;
|
u8 sq1_volume;
|
||||||
@ -59,6 +61,7 @@ typedef struct {
|
|||||||
u8 sq2_env_timer;
|
u8 sq2_env_timer;
|
||||||
|
|
||||||
bool ch3_enable;
|
bool ch3_enable;
|
||||||
|
bool ch3_dac;
|
||||||
u8 ch3_initial_len;
|
u8 ch3_initial_len;
|
||||||
u8 ch3_len;
|
u8 ch3_len;
|
||||||
u8 ch3_volume;
|
u8 ch3_volume;
|
||||||
|
243
lib/audio.c
243
lib/audio.c
@ -161,9 +161,10 @@ static int audio_callback(const void* input_uffer, void *output_buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
u8 left_vol = ctx.volume_left == 0 ? 1 : ctx.volume_left;
|
||||||
left *= (float)ctx.volume_left/7.0f;
|
u8 right_vol = ctx.volume_right == 0 ? 1 : ctx.volume_right;
|
||||||
right *= (float)ctx.volume_right/7.0f;
|
left *= (float)left_vol/7.0f;
|
||||||
|
right *= (float)right_vol/7.0f;
|
||||||
|
|
||||||
left /= 4;
|
left /= 4;
|
||||||
right /= 4;
|
right /= 4;
|
||||||
@ -280,6 +281,7 @@ void audio_tick(){
|
|||||||
if(ctx.sq1_len >= 64) {
|
if(ctx.sq1_len >= 64) {
|
||||||
ctx.sq1_enable = false;
|
ctx.sq1_enable = false;
|
||||||
}
|
}
|
||||||
|
printf("Len: %02X\n", ctx.sq1_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx.sq2_len_enable) {
|
if(ctx.sq2_len_enable) {
|
||||||
@ -291,7 +293,7 @@ void audio_tick(){
|
|||||||
|
|
||||||
if(ctx.ch3_len_enable) {
|
if(ctx.ch3_len_enable) {
|
||||||
ctx.ch3_len++;
|
ctx.ch3_len++;
|
||||||
if(ctx.ch3_len >= 64) {
|
if(ctx.ch3_len >= 256) {
|
||||||
ctx.ch3_enable = false;
|
ctx.ch3_enable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,7 +401,7 @@ void enable_square2() {
|
|||||||
|
|
||||||
void enable_wave() {
|
void enable_wave() {
|
||||||
ctx.ch3_enable = true;
|
ctx.ch3_enable = true;
|
||||||
if(ctx.ch3_len >= 64) {
|
if(ctx.ch3_len >= 256) {
|
||||||
ctx.ch3_len = ctx.ch3_initial_len;
|
ctx.ch3_len = ctx.ch3_initial_len;
|
||||||
}
|
}
|
||||||
ctx.ch3_sample = 0;
|
ctx.ch3_sample = 0;
|
||||||
@ -420,13 +422,216 @@ void enable_noise() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u8 audio_read(u16 address) {
|
u8 audio_read(u16 address) {
|
||||||
return 0x00;
|
printf("read at %02X\n", address);
|
||||||
|
if(address == 0xFF26) {
|
||||||
|
u8 value = (ctx.audio_enabled << 7) | (ctx.ch4_enable << 3) | (ctx.ch3_enable << 2) | (ctx.sq2_enable << 1) | (ctx.sq1_enable);
|
||||||
|
return value | 0b01110000;
|
||||||
|
}
|
||||||
|
if(address == 0xFF25) {
|
||||||
|
u8 value;
|
||||||
|
value |= ctx.ch4_left << 7;
|
||||||
|
value |= ctx.ch3_left << 6;
|
||||||
|
value |= ctx.ch2_left << 5;
|
||||||
|
value |= ctx.ch1_left << 4;
|
||||||
|
|
||||||
|
value |= ctx.ch4_right << 3;
|
||||||
|
value |= ctx.ch3_right << 2;
|
||||||
|
value |= ctx.ch2_right << 1;
|
||||||
|
value |= ctx.ch1_right;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF24) {
|
||||||
|
u8 value = (ctx.volume_left & 0b111) << 4;
|
||||||
|
value |= (ctx.volume_right & 0b111);
|
||||||
|
value |= (ctx.vin_left << 7);
|
||||||
|
value |= (ctx.vin_right << 3);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF10) {
|
||||||
|
u8 value = (ctx.sq1_sweep_pace & 0b111) << 4;
|
||||||
|
value |= (ctx.sq1_sweep_direction) << 3;
|
||||||
|
value |= ctx.sq1_sweep_step & 0b111;
|
||||||
|
return value | 0x80;
|
||||||
|
}
|
||||||
|
if(address == 0xFF11) {
|
||||||
|
u8 value = (ctx.sq1_duty & 0b11) << 6;
|
||||||
|
return value | 0b00111111;
|
||||||
|
}
|
||||||
|
if(address == 0xFF12) {
|
||||||
|
u8 value = (ctx.sq1_initial_volume & 0b1111) << 4;
|
||||||
|
value |= ctx.sq1_env_direction_buffer << 3;
|
||||||
|
value |= (ctx.sq1_env_pace_buffer & 0b111);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if(address == 0xFF13) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
if(address == 0xFF14) {
|
||||||
|
return (ctx.sq1_len_enable << 6) | 0b10111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(address == 0xFF16) {
|
||||||
|
u8 value = (ctx.sq2_duty & 0b11) << 6;
|
||||||
|
return value | 0b00111111;
|
||||||
|
}
|
||||||
|
if(address == 0xFF17) {
|
||||||
|
u8 value = (ctx.sq2_initial_volume & 0b1111) << 4;
|
||||||
|
value |= ctx.sq2_env_direction_buffer << 3;
|
||||||
|
value |= (ctx.sq2_env_pace_buffer & 0b111);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if(address == 0xFF18) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
if(address == 0xFF19) {
|
||||||
|
return (ctx.sq2_len_enable << 6) | 0b10111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF1A) {
|
||||||
|
return (ctx.ch3_dac << 7) | 0b01111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF1B) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF1C) {
|
||||||
|
return ((ctx.ch3_initial_volume & 0b11) << 5) | 0b10011111;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF1D) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF1E) {
|
||||||
|
return (ctx.ch3_len_enable << 6) | 0b10111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF20) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF21) {
|
||||||
|
u8 value = (ctx.ch4_initial_volume & 0b1111) << 4;
|
||||||
|
value |= ctx.ch4_env_direction_buffer << 3;
|
||||||
|
value |= (ctx.ch4_env_pace_buffer & 0b111);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF22) {
|
||||||
|
u8 value = (ctx.ch4_clock_shift & 0xF) << 4;
|
||||||
|
value |= ctx.ch4_lfsr_width << 3;
|
||||||
|
value |= (ctx.ch4_clock_divider & 0b111);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(address == 0xFF23) {
|
||||||
|
return (ctx.ch4_len_enable << 6) | 0b10111111;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
|
||||||
|
return ctx.wave_ram[address - 0xFF30];
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_buffers(){
|
||||||
|
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.volume_left = 0;
|
||||||
|
ctx.volume_right = 0;
|
||||||
|
ctx.vin_left = 0;
|
||||||
|
ctx.vin_right = 0;
|
||||||
|
ctx.sq1_duty = 0;
|
||||||
|
ctx.sq1_volume = 0;
|
||||||
|
ctx.sq1_sample = 0;
|
||||||
|
ctx.sq1_period_reset = 0;
|
||||||
|
ctx.sq1_period_timer = 0;
|
||||||
|
ctx.sq1_enable = 0;
|
||||||
|
ctx.sq1_len_enable = 0;
|
||||||
|
ctx.sq1_sweep_pace = 0;
|
||||||
|
ctx.sq1_sweep_direction = 0;
|
||||||
|
ctx.sq1_initial_len = 0;
|
||||||
|
ctx.sq1_len = 0;
|
||||||
|
ctx.sq1_initial_volume = 0;
|
||||||
|
ctx.sq1_env_direction = 0;
|
||||||
|
ctx.sq1_env_direction_buffer = 0;
|
||||||
|
ctx.sq1_env_pace = 0;
|
||||||
|
ctx.sq1_env_pace_buffer = 0;
|
||||||
|
ctx.sq1_env_timer = 0;
|
||||||
|
ctx.sq1_sweep_step = 0;
|
||||||
|
ctx.sq1_sweep_timer = 0;
|
||||||
|
ctx.sq1_sweep_enabled = 0;
|
||||||
|
ctx.sq1_sweep_period = 0;
|
||||||
|
ctx.sq1_calc_period = 0;
|
||||||
|
ctx.sq2_duty = 0;
|
||||||
|
ctx.sq2_volume = 0;
|
||||||
|
ctx.sq2_sample = 0;
|
||||||
|
ctx.sq2_period_reset = 0;
|
||||||
|
ctx.sq2_period_timer = 0;
|
||||||
|
ctx.sq2_enable = 0;
|
||||||
|
ctx.sq2_len_enable = 0;
|
||||||
|
ctx.sq2_initial_len = 0;
|
||||||
|
ctx.sq2_len = 0;
|
||||||
|
ctx.sq2_initial_volume = 0;
|
||||||
|
ctx.sq2_env_direction = 0;
|
||||||
|
ctx.sq2_env_direction_buffer = 0;
|
||||||
|
ctx.sq2_env_pace = 0;
|
||||||
|
ctx.sq2_env_pace_buffer = 0;
|
||||||
|
ctx.sq2_env_timer = 0;
|
||||||
|
ctx.ch3_enable = 0;
|
||||||
|
ctx.ch3_dac = 0;
|
||||||
|
ctx.ch3_initial_len = 0;
|
||||||
|
ctx.ch3_len = 0;
|
||||||
|
ctx.ch3_volume = 0;
|
||||||
|
ctx.ch3_initial_volume = 0;
|
||||||
|
ctx.ch3_period_timer = 0;
|
||||||
|
ctx.ch3_period_reset = 0;
|
||||||
|
ctx.ch3_len_enable = 0;
|
||||||
|
ctx.ch3_last_sample = 0;
|
||||||
|
ctx.ch3_sample = 0;
|
||||||
|
ctx.ch4_enable = 0;
|
||||||
|
ctx.ch4_initial_len = 0;
|
||||||
|
ctx.ch4_len = 0;
|
||||||
|
ctx.ch4_initial_volume = 0;
|
||||||
|
ctx.ch4_volume = 0;
|
||||||
|
ctx.ch4_env_pace = 0;
|
||||||
|
ctx.ch4_env_pace_buffer = 0;
|
||||||
|
ctx.ch4_env_timer = 0;
|
||||||
|
ctx.ch4_env_direction = 0;
|
||||||
|
ctx.ch4_env_direction_buffer = 0;
|
||||||
|
ctx.ch4_clock_shift = 0;
|
||||||
|
ctx.ch4_lfsr_width = 0;
|
||||||
|
ctx.ch4_clock_divider = 0;
|
||||||
|
ctx.ch4_len_enable = 0;
|
||||||
|
ctx.ch4_lfsr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_write(u16 address, u8 value){
|
void audio_write(u16 address, u8 value){
|
||||||
|
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
|
||||||
|
ctx.wave_ram[address - 0xFF30] = value;
|
||||||
|
}
|
||||||
|
|
||||||
if(address == 0xFF26) {
|
if(address == 0xFF26) {
|
||||||
ctx.audio_enabled = value & 0x80;
|
ctx.audio_enabled = value & 0x80;
|
||||||
|
if(!ctx.audio_enabled) {
|
||||||
|
reset_buffers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!ctx.audio_enabled){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(address == 0xFF25) {
|
if(address == 0xFF25) {
|
||||||
ctx.ch4_left = value & 0b10000000;
|
ctx.ch4_left = value & 0b10000000;
|
||||||
ctx.ch3_left = value & 0b01000000;
|
ctx.ch3_left = value & 0b01000000;
|
||||||
@ -441,9 +646,11 @@ void audio_write(u16 address, u8 value){
|
|||||||
|
|
||||||
if(address == 0xFF24) {
|
if(address == 0xFF24) {
|
||||||
ctx.volume_left = (value >> 4) & 0b111;
|
ctx.volume_left = (value >> 4) & 0b111;
|
||||||
if(ctx.volume_left == 0) ctx.volume_left = 1;
|
//if(ctx.volume_left == 0) ctx.volume_left = 1;
|
||||||
ctx.volume_right = value & 0b111;
|
ctx.volume_right = value & 0b111;
|
||||||
if(ctx.volume_right == 0) ctx.volume_right = 1;
|
//if(ctx.volume_right == 0) ctx.volume_right = 1;
|
||||||
|
ctx.vin_left = value & 0x80;
|
||||||
|
ctx.vin_right = value & 0x8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF10) {
|
if(address == 0xFF10) {
|
||||||
@ -454,10 +661,12 @@ void audio_write(u16 address, u8 value){
|
|||||||
if(address == 0xFF11) {
|
if(address == 0xFF11) {
|
||||||
ctx.sq1_duty = value >> 6;
|
ctx.sq1_duty = value >> 6;
|
||||||
ctx.sq1_initial_len = value & 0x3F;
|
ctx.sq1_initial_len = value & 0x3F;
|
||||||
|
ctx.sq1_len = ctx.sq1_initial_len;
|
||||||
|
printf("initial len: %02X\n", ctx.sq1_initial_len);
|
||||||
}
|
}
|
||||||
if(address == 0xFF12) {
|
if(address == 0xFF12) {
|
||||||
ctx.sq1_initial_volume = (value >> 4) & 0x0F;
|
ctx.sq1_initial_volume = (value >> 4) & 0x0F;
|
||||||
ctx.sq1_env_direction_buffer = (value & 0x8) == 0x80;
|
ctx.sq1_env_direction_buffer = (value & 0x8) == 0x8;
|
||||||
ctx.sq1_env_pace_buffer = value & 0b111;
|
ctx.sq1_env_pace_buffer = value & 0b111;
|
||||||
}
|
}
|
||||||
if(address == 0xFF13) {
|
if(address == 0xFF13) {
|
||||||
@ -475,10 +684,11 @@ void audio_write(u16 address, u8 value){
|
|||||||
if(address == 0xFF16) {
|
if(address == 0xFF16) {
|
||||||
ctx.sq2_duty = value >> 6;
|
ctx.sq2_duty = value >> 6;
|
||||||
ctx.sq2_initial_len = value & 0x3F;
|
ctx.sq2_initial_len = value & 0x3F;
|
||||||
|
ctx.sq2_len = ctx.sq2_initial_len;
|
||||||
}
|
}
|
||||||
if(address == 0xFF17) {
|
if(address == 0xFF17) {
|
||||||
ctx.sq2_initial_volume = (value >> 4) & 0x0F;
|
ctx.sq2_initial_volume = (value >> 4) & 0x0F;
|
||||||
ctx.sq2_env_direction_buffer = (value & 0x8) == 0x80;
|
ctx.sq2_env_direction_buffer = (value & 0x8) == 0x8;
|
||||||
ctx.sq2_env_pace_buffer = value & 0b111;
|
ctx.sq2_env_pace_buffer = value & 0b111;
|
||||||
if(ctx.sq2_env_direction == 0 && ctx.sq2_initial_volume == 0) {
|
if(ctx.sq2_env_direction == 0 && ctx.sq2_initial_volume == 0) {
|
||||||
ctx.sq2_enable = false;
|
ctx.sq2_enable = false;
|
||||||
@ -498,11 +708,15 @@ void audio_write(u16 address, u8 value){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF1A) {
|
if(address == 0xFF1A) {
|
||||||
//ctx.ch3_enable = (value & 0x80) == 0x80;
|
ctx.ch3_dac = value & 0x80;
|
||||||
|
if(!ctx.ch3_dac){
|
||||||
|
ctx.ch3_enable = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF1B) {
|
if(address == 0xFF1B) {
|
||||||
ctx.ch3_initial_len = value;
|
ctx.ch3_initial_len = value;
|
||||||
|
ctx.ch3_len = ctx.ch3_initial_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF1C) {
|
if(address == 0xFF1C) {
|
||||||
@ -523,11 +737,12 @@ void audio_write(u16 address, u8 value){
|
|||||||
|
|
||||||
if(address == 0xFF20) {
|
if(address == 0xFF20) {
|
||||||
ctx.ch4_initial_len = value & 0b111111;
|
ctx.ch4_initial_len = value & 0b111111;
|
||||||
|
ctx.ch4_len = ctx.ch4_initial_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(address == 0xFF21) {
|
if(address == 0xFF21) {
|
||||||
ctx.ch4_initial_volume = (value >> 4) & 0x0F;
|
ctx.ch4_initial_volume = (value >> 4) & 0x0F;
|
||||||
ctx.ch4_env_direction_buffer = (value & 0x8) == 0x80;
|
ctx.ch4_env_direction_buffer = (value & 0x8) == 0x8;
|
||||||
ctx.ch4_env_pace_buffer = value & 0b111;
|
ctx.ch4_env_pace_buffer = value & 0b111;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,8 +761,4 @@ void audio_write(u16 address, u8 value){
|
|||||||
enable_noise();
|
enable_noise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(BETWEEN(address, 0xFF30, 0xFF3F)) {
|
|
||||||
ctx.wave_ram[address - 0xFF30] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user