#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;
}
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)
{
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; \
#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) \
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;
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))
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++)
{
gs->sample_data = square_pattern_duty[2];
gs->active_flag = 0;
}
+
+ SDL_UnlockMutex(sound_mutex);
}
void sound_exit()
NULL
};
- gbc_sound_tick_step =
- float_to_fp16_16(256.0 / sound_frequency);
-
- init_noise_table(noise_table15, 32767, 14);
- init_noise_table(noise_table7, 127, 6);
-
- reset_sound();
-
sound_mutex = SDL_CreateMutex();
sound_cv = SDL_CreateCond();
printf("audio: freq %d, size %d\n", sound_frequency, audio_buffer_size);
#endif
+ gbc_sound_tick_step =
+ float_to_fp16_16(256.0f / sound_frequency);
+
+ init_noise_table(noise_table15, 32767, 14);
+ init_noise_table(noise_table7, 127, 6);
+
+ reset_sound();
+
SDL_PauseAudio(0);
}
#define BUFFER_SIZE 65536
-// A lot of sound cards on PC can't handle such small buffers but this
-// seems to work well on PSP.
-
-#ifdef PSP_BUILD
-
-#define SOUND_BUFFER_SIZE 4096
+#define GBA_XTAL 16777216.0f
+#define GBA_60HZ_RATE 16853760.0f /* 228*(272+960)*60 */
+#if !defined(PSP_BUILD) && !defined(WIZ_BUILD)
+ // run GBA at 60Hz (~0.5% faster) to better match host display
+ #define GBC_BASE_RATE GBA_60HZ_RATE
#else
-
-#define SOUND_BUFFER_SIZE 16384
-
+ #define GBC_BASE_RATE GBA_XTAL
#endif
typedef enum
s8 fifo[32];
u32 fifo_base;
u32 fifo_top;
- fixed16_16 fifo_fractional;
+ fixed8_24 fifo_fractional;
// The + 1 is to give some extra room for linear interpolation
// when wrapping around.
u32 buffer_index;
extern u32 gbc_sound_master_volume_left;
extern u32 gbc_sound_master_volume_right;
extern u32 gbc_sound_master_volume;
+extern u32 gbc_sound_buffer_index;
+extern u32 gbc_sound_last_cpu_ticks;
extern u32 sound_frequency;
extern u32 sound_on;
void sound_timer_queue8(u32 channel, u8 value);
void sound_timer_queue16(u32 channel, u16 value);
void sound_timer_queue32(u32 channel, u32 value);
-void sound_timer(fixed16_16 frequency_step, u32 channel);
+void sound_timer(fixed8_24 frequency_step, u32 channel);
void sound_reset_fifo(u32 channel);
void update_gbc_sound(u32 cpu_ticks);
void init_sound();
#define sound_update_frequency_step(timer_number) \
timer[timer_number].frequency_step = \
- float_to_fp16_16(16777216.0 / (timer_reload * sound_frequency)) \
+ float_to_fp8_24(GBC_BASE_RATE / (timer_reload * sound_frequency)) \
#endif // IN_MEMORY_C