X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=gpsp.git;a=blobdiff_plain;f=sound.c;h=5593bbeea80945fbb38ca9aeb4aab94a85197602;hp=44177ff182a57775aded5afa1b1e729870c215bd;hb=108c704a364e89d071c67f929a292f05d019236a;hpb=e9c7b1376a93375f3ebbc5b58c9b69c065b17060 diff --git a/sound.c b/sound.c index 44177ff..5593bbe 100644 --- a/sound.c +++ b/sound.c @@ -25,29 +25,26 @@ u32 global_enable_audio = 1; direct_sound_struct direct_sound_channel[2]; gbc_sound_struct gbc_sound_channel[4]; -#if defined(GP2X_BUILD) || defined(TAVI_BUILD) u32 sound_frequency = 44100; -#else -u32 sound_frequency = 44100; -#endif -SDL_AudioSpec sound_settings; SDL_mutex *sound_mutex; -SDL_cond *sound_cv; +static SDL_cond *sound_cv; -#ifndef PSP_BUILD -u32 audio_buffer_size_number = 7; -#else +#ifdef PSP_BUILD u32 audio_buffer_size_number = 1; +#else +u32 audio_buffer_size_number = 8; #endif -u32 audio_buffer_size; -u32 sound_on = 0; -s16 sound_buffer[BUFFER_SIZE]; -u32 sound_buffer_base = 0; +u32 sound_on; +static u32 audio_buffer_size; +static s16 sound_buffer[BUFFER_SIZE]; +static u32 sound_buffer_base; + +static u32 sound_last_cpu_ticks; +static fixed16_16 gbc_sound_tick_step; -u32 sound_last_cpu_ticks = 0; -fixed16_16 gbc_sound_tick_step; +static u32 sound_exit_flag; // Queue 1, 2, or 4 samples to the top of the DS FIFO, wrap around circularly @@ -87,31 +84,31 @@ void sound_timer_queue32(u32 channel, u32 value) #define render_sample_left() \ sound_buffer[buffer_index] += current_sample + \ - fp16_16_to_u32((next_sample - current_sample) * fifo_fractional) \ + fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)) \ #define render_sample_right() \ sound_buffer[buffer_index + 1] += current_sample + \ - fp16_16_to_u32((next_sample - current_sample) * fifo_fractional) \ + fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)) \ #define render_sample_both() \ dest_sample = current_sample + \ - fp16_16_to_u32((next_sample - current_sample) * fifo_fractional); \ + fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)); \ sound_buffer[buffer_index] += dest_sample; \ sound_buffer[buffer_index + 1] += dest_sample \ #define render_samples(type) \ - while(fifo_fractional <= 0xFFFF) \ + while(fifo_fractional <= 0xFFFFFF) \ { \ render_sample_##type(); \ fifo_fractional += frequency_step; \ buffer_index = (buffer_index + 2) % BUFFER_SIZE; \ } \ -void sound_timer(fixed16_16 frequency_step, u32 channel) +void sound_timer(fixed8_24 frequency_step, u32 channel) { direct_sound_struct *ds = direct_sound_channel + channel; - fixed16_16 fifo_fractional = ds->fifo_fractional; + fixed8_24 fifo_fractional = ds->fifo_fractional; u32 buffer_index = ds->buffer_index; s16 current_sample, next_sample, dest_sample; @@ -152,7 +149,7 @@ void sound_timer(fixed16_16 frequency_step, u32 channel) } ds->buffer_index = buffer_index; - ds->fifo_fractional = fp16_16_fractional_part(fifo_fractional); + ds->fifo_fractional = fp8_24_fractional_part(fifo_fractional); if(((ds->fifo_top - ds->fifo_base) % 32) <= 16) { @@ -267,8 +264,8 @@ u32 gbc_sound_master_volume; if(rate > 2048) \ rate = 2048; \ \ - frequency_step = float_to_fp16_16(((131072.0 / (2048 - rate)) * 8.0) / \ - sound_frequency); \ + frequency_step = float_to_fp16_16(((131072.0f / (2048 - rate)) * 8.0f) \ + / sound_frequency); \ \ gs->frequency_step = frequency_step; \ gs->rate = rate; \ @@ -312,13 +309,6 @@ u32 gbc_sound_master_volume; #define update_tone_noenvelope() \ -#define gbc_sound_synchronize() \ - while(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) > \ - (audio_buffer_size * 2)) \ - { \ - SDL_CondWait(sound_cv, sound_mutex); \ - } \ - #define update_tone_counters(envelope_op, sweep_op) \ tick_counter += gbc_sound_tick_step; \ if(tick_counter > 0xFFFF) \ @@ -431,19 +421,10 @@ u32 gbc_sound_master_volume; wave_bank[i2 + 1] = ((current_sample & 0x0F) - 8); \ } \ -void synchronize_sound() -{ - SDL_LockMutex(sound_mutex); - - gbc_sound_synchronize(); - - SDL_UnlockMutex(sound_mutex); -} - void update_gbc_sound(u32 cpu_ticks) { - fixed16_16 buffer_ticks = float_to_fp16_16(((float)(cpu_ticks - - gbc_sound_last_cpu_ticks) * sound_frequency) / 16777216.0); + fixed16_16 buffer_ticks = float_to_fp16_16((float)(cpu_ticks - + gbc_sound_last_cpu_ticks) * sound_frequency / GBC_BASE_RATE); u32 i, i2; gbc_sound_struct *gs = gbc_sound_channel; fixed16_16 sample_index, frequency_step; @@ -469,8 +450,8 @@ void update_gbc_sound(u32 cpu_ticks) SDL_LockMutex(sound_mutex); if(synchronize_flag) { - if(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) > - (audio_buffer_size * 3 / 2)) + if(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) >= + (audio_buffer_size * 2)) { while(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) > (audio_buffer_size * 3 / 2)) @@ -485,13 +466,10 @@ void update_gbc_sound(u32 cpu_ticks) real_frame_count = 0; virtual_frame_count = 0; } -#endif - -/* - -#ifdef GP2X_BUILD +#else if(current_frameskip_type == auto_frameskip) { +/* u64 current_ticks; u64 next_ticks; get_ticks_us(¤t_ticks); @@ -500,12 +478,13 @@ void update_gbc_sound(u32 cpu_ticks) delay_us(next_ticks - current_ticks); get_ticks_us(&frame_count_initial_timestamp); - real_frame_count = 0; - virtual_frame_count = 0; +*/ + /* prevent frameskip, or it will cause more audio, + * then more waiting here, then frame skip again, ... */ + num_skipped_frames = 100; } #endif -*/ } } if(sound_on == 1) @@ -628,7 +607,7 @@ void sound_callback(void *userdata, Uint8 *stream, int length) SDL_LockMutex(sound_mutex); while(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) < - length) + length && !sound_exit_flag) { SDL_CondWait(sound_cv, sound_mutex); } @@ -710,10 +689,12 @@ void reset_sound() gbc_sound_struct *gs = gbc_sound_channel; u32 i; + SDL_LockMutex(sound_mutex); + sound_on = 0; sound_buffer_base = 0; sound_last_cpu_ticks = 0; - memset(sound_buffer, 0, audio_buffer_size); + memset(sound_buffer, 0, sizeof(sound_buffer)); for(i = 0; i < 2; i++, ds++) { @@ -741,6 +722,8 @@ void reset_sound() gs->sample_data = square_pattern_duty[2]; gs->active_flag = 0; } + + SDL_UnlockMutex(sound_mutex); } void sound_exit() @@ -748,18 +731,26 @@ void sound_exit() gbc_sound_buffer_index = (sound_buffer_base + audio_buffer_size) % BUFFER_SIZE; SDL_PauseAudio(1); + sound_exit_flag = 1; SDL_CondSignal(sound_cv); + SDL_CloseAudio(); + SDL_Delay(200); + SDL_DestroyMutex(sound_mutex); + sound_mutex = NULL; + SDL_DestroyCond(sound_cv); + sound_cv = NULL; } -void init_sound() +void init_sound(int need_reset) { + SDL_AudioSpec sound_settings; + + sound_exit_flag = 0; #ifdef PSP_BUILD audio_buffer_size = (audio_buffer_size_number * 1024) + 3072; -#elif defined(TAVI_BUILD) || defined(ARM_ARCH) +#else audio_buffer_size = 16 << audio_buffer_size_number; // audio_buffer_size = 16384; -#else - audio_buffer_size = 16384; #endif SDL_AudioSpec desired_spec = @@ -775,18 +766,28 @@ void init_sound() NULL }; + sound_mutex = SDL_CreateMutex(); + sound_cv = SDL_CreateCond(); + + SDL_OpenAudio(&desired_spec, &sound_settings); + sound_frequency = sound_settings.freq; + audio_buffer_size = sound_settings.size; + u32 i = audio_buffer_size / 16; + for (audio_buffer_size_number = 0; i && (i & 1) == 0; i >>= 1) + audio_buffer_size_number++; +#ifndef PSP_BUILD + printf("audio: freq %d, size %d\n", sound_frequency, audio_buffer_size); +#endif + gbc_sound_tick_step = - float_to_fp16_16(256.0 / sound_frequency); + float_to_fp16_16(256.0f / sound_frequency); init_noise_table(noise_table15, 32767, 14); init_noise_table(noise_table7, 127, 6); - reset_sound(); + if (need_reset) + reset_sound(); - SDL_OpenAudio(&desired_spec, &sound_settings); - sound_frequency = sound_settings.freq; - sound_mutex = SDL_CreateMutex(); - sound_cv = SDL_CreateCond(); SDL_PauseAudio(0); }