dont understand audio :(
This commit is contained in:
parent
8493ff5fea
commit
d4c6f05fb8
@ -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;
|
||||
|
||||
|
88
lib/audio.c
88
lib/audio.c
@ -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;
|
||||
|
2
lib/io.c
2
lib/io.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
14
lib/timer.c
14
lib/timer.c
@ -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(¤t);
|
||||
// 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(¤t);
|
||||
now = current.QuadPart;
|
||||
//printf("Last-now: %lld, counts: %lld\n", now - last, counts_per_cycle);
|
||||
}
|
||||
last = now;
|
||||
u16 prev_div = ctx.div;
|
||||
ctx.div++;
|
||||
|
Loading…
Reference in New Issue
Block a user