dont understand audio :(

This commit is contained in:
Samuel Walker 2025-02-02 22:56:07 -07:00
parent 8493ff5fea
commit d4c6f05fb8
Signed by: piwalker
GPG Key ID: 616B1928705EA4C9
5 changed files with 89 additions and 45 deletions

View File

@ -40,7 +40,7 @@ typedef struct {
u8 sq1_env_pace;
u8 sq1_env_timer;
u8 sq1_sweep_step;
u8 sq1_audio_buffer[4096];
float sq1_audio_buffer[4096];
u32 sq1_write_head;
u32 sq1_read_head;
@ -59,7 +59,7 @@ typedef struct {
u8 sq2_env_pace;
u8 sq2_env_timer;
u8 sq2_sweep_step;
u8 sq2_audio_buffer[4096];
float sq2_audio_buffer[4096];
u32 sq2_write_head;
u32 sq2_read_head;

View File

@ -26,7 +26,8 @@ static int sq2_timer = 0;
static audio_context ctx;
HANDLE mutex;
HANDLE data_to_read;
HANDLE data_to_write;
const u8 square_sample[8] = {
0x0,
@ -74,12 +75,20 @@ static int audio_callback(const void* input_uffer, void *output_buffer,
float left = 0;
float right = 0;
for(int i = 0; i < framesPerBuffer; i++) {
if(!ctx.audio_enabled) {
*out++ = 0;
*out++ = 0;
continue;
}
if(WaitForSingleObject(data_to_read, INFINITE) == WAIT_TIMEOUT) {
continue;
}
if(ctx.sq1_write_head != ctx.sq1_read_head) {
if(ctx.ch1_left){
left = (float)(ctx.sq1_volume * ctx.sq1_audio_buffer[ctx.sq1_read_head])/15.0f;
//left = ((float)(ctx.sq1_volume * ctx.sq1_audio_buffer[ctx.sq1_read_head])/15.0f) - 0.5f;
}
if(ctx.ch1_right){
right = (float)(ctx.sq1_volume * ctx.sq1_audio_buffer[ctx.sq1_read_head])/15.0f;
//right = ((float)(ctx.sq1_volume * ctx.sq1_audio_buffer[ctx.sq1_read_head])/15.0f) - 0.5f;
}
ctx.sq1_read_head++;
if (ctx.sq1_read_head >= 4096) {
@ -87,30 +96,36 @@ static int audio_callback(const void* input_uffer, void *output_buffer,
}
}
if(ctx.sq2_write_head != ctx.sq2_read_head) {
//if(ctx.sq2_write_head != ctx.sq2_read_head) {
if(ctx.ch2_left){
left += (float)(ctx.sq2_volume * ctx.sq2_audio_buffer[ctx.sq2_read_head])/15.0f;
left = ctx.sq2_audio_buffer[ctx.sq2_read_head];
//printf("audio: %d\n", ctx.sq2_audio_buffer[ctx.sq2_read_head]);
//left = ((float)(ctx.sq2_volume * square_sample[ctx.sq2_sample])/15.0f) - 0.5f;
}
if(ctx.ch2_right){
right += (float)(ctx.sq2_volume * ctx.sq2_audio_buffer[ctx.sq2_read_head])/15.0f;
//right += ((float)(ctx.sq2_volume * ctx.sq2_audio_buffer[ctx.sq2_read_head])/15.0f) - 0.5f;
}
ctx.sq2_read_head++;
if (ctx.sq2_read_head >= 4096) {
ctx.sq2_read_head = 0;
}
}
//}
left *= (float)ctx.volume_left/8.0f;
right *= (float)ctx.volume_right/8.0f;
*out++ = left;
*out++ = right;
ReleaseSemaphore(data_to_write, 1, NULL);
}
return paContinue;
}
const int semaphore_count = 128;
static PaStream *stream;
void audio_init(){
mutex = CreateMutex(NULL, FALSE, NULL);
data_to_read = CreateSemaphore(NULL, 0, semaphore_count, NULL);
data_to_write = CreateSemaphore(NULL, semaphore_count, semaphore_count, NULL);
PaStreamParameters output_parameters;
PaStream *stream;
PaError err;
ctx.sq1_volume = 1;
@ -120,14 +135,21 @@ void audio_init(){
ctx.sq2_volume = 1;
ctx.sq2_duty = 0.5;
ctx.sq2_freq = 400;
ctx.audio_enabled = true;
ctx.sq1_period_reset = 0x100;
ctx.sq1_period_timer = 0x100;
ctx.sq2_period_reset = 0x700;
ctx.sq2_period_timer = 0x700;
ctx.sq2_enable = true;
ctx.sq2_len_enable = false;
ctx.ch2_left = true;
ctx.volume_left = 8;
ctx.sq2_volume = 1;
ctx.sq1_value = -1;
ctx.sq1_write_head = 0;
ctx.sq1_read_head = 0;
ctx.sq2_read_head = 0;
ctx.sq2_write_head = 0;
ctx.sq2_env_pace = 0;
for(int i = 0; i < TABLE_SIZE; i++) {
sine[i] = (float) sin(((double)i/(double)TABLE_SIZE) * M_PI * 2.);
@ -150,7 +172,7 @@ void audio_init(){
&output_parameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
NULL,
paClipOff,
audio_callback,
&ctx);
if(err != paNoError) goto error;
@ -180,7 +202,6 @@ void audio_tick(){
ctx.sq2_len++;
if(ctx.sq2_len >= 64) {
ctx.sq2_enable = false;
printf("sq2 timer");
}
}
}
@ -214,12 +235,18 @@ void audio_tick(){
}
static u32 updates;
static u32 last;
void audio_period_tick(){
updates++;
//DWORD dwaitResult = WaitForSingleObject(mutex, INFINITE);
//if(dwaitResult == WAIT_ABANDONED)
// return;
u32 now = get_ticks();
if(now - last >= 1000) {
printf("Updates: %d\n", updates);
updates = 0;
last = now;
}
ctx.sq1_period_timer++;
ctx.sq2_period_timer++;
@ -235,9 +262,14 @@ void audio_period_tick(){
ctx.sq2_sample = (ctx.sq2_sample + 1) % 8;
//ctx.sq1_value = (float)square_sample[ctx.sq1_sample];///15.0f;
//ctx.ready = true;
if(ctx.sq2_sample == 0) {
updates++;
}
if(updates >= 24) {
updates = 0;
}
DWORD result = WaitForSingleObject(data_to_write, 0);
if(result != WAIT_TIMEOUT) {
//updates++;
//updates = 0;
//u32 read = ctx.read_head;
//u32 write = ctx.write_head;
//if(read > write) {
@ -247,17 +279,24 @@ void audio_period_tick(){
// return;
//}
if(ctx.sq1_enable){
ctx.sq1_audio_buffer[ctx.sq1_write_head++] = square_sample[ctx.sq1_sample];
ctx.sq1_audio_buffer[ctx.sq1_write_head++] = ((float)(ctx.sq2_volume * square_sample[ctx.sq1_sample])/7.5f) - 1.0f;
} else {
ctx.sq1_audio_buffer[ctx.sq1_write_head++] = 0x0;
}
if(ctx.sq1_write_head >= 4096) {
ctx.sq1_write_head = 0;
}
}
if(ctx.sq2_enable){
ctx.sq2_audio_buffer[ctx.sq2_write_head++] = square_sample[ctx.sq2_sample];
ctx.sq2_audio_buffer[ctx.sq2_write_head++] = ((float)(ctx.sq2_volume * (square_sample[ctx.sq2_sample] - .5f))/7.5f);
//printf("Audio: %f\n", ctx.sq2_audio_buffer[ctx.sq2_write_head - 1]);
} else {
ctx.sq2_audio_buffer[ctx.sq2_write_head++] = 0.0f;
}
if(ctx.sq2_write_head >= 4096) {
ctx.sq2_write_head = 0;
}
}
ReleaseSemaphore(data_to_read, 1, NULL);
}
//ReleaseMutex(mutex);
}
@ -269,17 +308,18 @@ void enable_square1() {
}
ctx.sq1_volume = ctx.sq1_initial_volume;
ctx.sq1_env_timer = 0;
}
void enable_square2() {
//ctx.sq2_enable = true;
ctx.sq2_enable = true;
if(ctx.sq2_len >= 64) {
ctx.sq2_len = ctx.sq2_initial_len;
}
ctx.sq2_volume = ctx.sq2_initial_volume;
ctx.sq2_env_timer = 0;
ctx.sq2_sample = 0;
//printf("Channel 2 enabled, Timer: %d\n", ctx.sq2_len_enable);
}
u8 audio_read(u16 address) {
@ -287,6 +327,7 @@ u8 audio_read(u16 address) {
}
void audio_write(u16 address, u8 value){
return;
if(address == 0xFF26) {
ctx.audio_enabled = value & 0x80;
}
@ -343,6 +384,9 @@ void audio_write(u16 address, u8 value){
ctx.sq2_initial_volume = value >> 4;
ctx.sq2_env_direction = value & 0x8;
ctx.sq2_env_pace = value * 0b111;
if(!ctx.sq2_env_direction && !ctx.sq2_initial_volume) {
ctx.sq2_enable = false;
}
}
if(address == 0xFF18) {
ctx.sq2_period_reset = (ctx.sq2_period_reset & 0xF0) | value;

View File

@ -48,7 +48,7 @@ void io_write(u16 address, u8 value){
}
if(address == 0xFF01) {
serial_data[0] = value;
printf("%c", value);
//printf("%c", value);
return;
}

View File

@ -156,14 +156,14 @@ void ppu_mode_hblank() {
u32 frame_time = end - prev_frame_time;
if(frame_time < target_frame_time) {
delay((target_frame_time - frame_time));
//delay((target_frame_time - frame_time));
}
if (end - start_timer >= 1000) {
u32 fps = frame_count;
start_timer = end;
frame_count = 0;
printf("FPS: %ld\n", fps);
//printf("FPS: %ld\n", fps);
if(cart_need_save()){
cart_battery_save();
}

View File

@ -15,16 +15,16 @@ void timer_init() {
ctx.div = 0XAC00;
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
counts_per_cycle = freq.QuadPart / (1 << 19);
counts_per_cycle = freq.QuadPart / (1 << 22);
}
void timer_tick() {
//while(now - last < counts_per_cycle){
// LARGE_INTEGER current;
// QueryPerformanceCounter(&current);
// now = current.QuadPart;
// //printf("Last-now: %lld, counts: %lld\n", now - last, counts_per_cycle);
//}
while(now - last < counts_per_cycle){
LARGE_INTEGER current;
QueryPerformanceCounter(&current);
now = current.QuadPart;
//printf("Last-now: %lld, counts: %lld\n", now - last, counts_per_cycle);
}
last = now;
u16 prev_div = ctx.div;
ctx.div++;