integrate M-HT's neon scalers
[gpsp.git] / sound.c
CommitLineData
2823a4c8 1/* gameplaySP
2 *
3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21#include "common.h"
22#include <SDL.h>
23u32 global_enable_audio = 1;
24
25direct_sound_struct direct_sound_channel[2];
26gbc_sound_struct gbc_sound_channel[4];
27
2823a4c8 28u32 sound_frequency = 44100;
2823a4c8 29
2823a4c8 30SDL_mutex *sound_mutex;
bbba3209 31static SDL_cond *sound_cv;
2823a4c8 32
2455b6a3 33#ifdef PSP_BUILD
2823a4c8 34u32 audio_buffer_size_number = 1;
2455b6a3 35#else
36u32 audio_buffer_size_number = 8;
2823a4c8 37#endif
38
bbba3209 39u32 sound_on;
40static u32 audio_buffer_size;
41static s16 sound_buffer[BUFFER_SIZE];
42static u32 sound_buffer_base;
2823a4c8 43
bbba3209 44static u32 sound_last_cpu_ticks;
45static fixed16_16 gbc_sound_tick_step;
2823a4c8 46
bbba3209 47static u32 sound_exit_flag;
2455b6a3 48
2823a4c8 49// Queue 1, 2, or 4 samples to the top of the DS FIFO, wrap around circularly
50
51#define sound_timer_queue(size, value) \
52 *((s##size *)(ds->fifo + ds->fifo_top)) = value; \
53 ds->fifo_top = (ds->fifo_top + 1) % 32; \
54
55void sound_timer_queue8(u32 channel, u8 value)
56{
57 direct_sound_struct *ds = direct_sound_channel + channel;
58 sound_timer_queue(8, value);
59}
60
61void sound_timer_queue16(u32 channel, u16 value)
62{
63 direct_sound_struct *ds = direct_sound_channel + channel;
64 sound_timer_queue(8, value & 0xFF);
65 sound_timer_queue(8, value >> 8);
66}
67
68void sound_timer_queue32(u32 channel, u32 value)
69{
70 direct_sound_struct *ds = direct_sound_channel + channel;
71
72 sound_timer_queue(8, value & 0xFF);
73 sound_timer_queue(8, (value >> 8) & 0xFF);
74 sound_timer_queue(8, (value >> 16) & 0xFF);
75 sound_timer_queue(8, value >> 24);
76}
77
78// Unqueue 1 sample from the base of the DS FIFO and place it on the audio
79// buffer for as many samples as necessary. If the DS FIFO is 16 bytes or
80// smaller and if DMA is enabled for the sound channel initiate a DMA transfer
81// to the DS FIFO.
82
83#define render_sample_null() \
84
85#define render_sample_left() \
86 sound_buffer[buffer_index] += current_sample + \
2f1c528a 87 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)) \
2823a4c8 88
89#define render_sample_right() \
90 sound_buffer[buffer_index + 1] += current_sample + \
2f1c528a 91 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)) \
2823a4c8 92
93#define render_sample_both() \
94 dest_sample = current_sample + \
2f1c528a 95 fp16_16_to_u32((next_sample - current_sample) * (fifo_fractional >> 8)); \
2823a4c8 96 sound_buffer[buffer_index] += dest_sample; \
97 sound_buffer[buffer_index + 1] += dest_sample \
98
99#define render_samples(type) \
2f1c528a 100 while(fifo_fractional <= 0xFFFFFF) \
2823a4c8 101 { \
102 render_sample_##type(); \
103 fifo_fractional += frequency_step; \
104 buffer_index = (buffer_index + 2) % BUFFER_SIZE; \
105 } \
106
2f1c528a 107void sound_timer(fixed8_24 frequency_step, u32 channel)
2823a4c8 108{
109 direct_sound_struct *ds = direct_sound_channel + channel;
110
2f1c528a 111 fixed8_24 fifo_fractional = ds->fifo_fractional;
2823a4c8 112 u32 buffer_index = ds->buffer_index;
113 s16 current_sample, next_sample, dest_sample;
114
115 current_sample = ds->fifo[ds->fifo_base] << 4;
116 ds->fifo_base = (ds->fifo_base + 1) % 32;
117 next_sample = ds->fifo[ds->fifo_base] << 4;
118
119 if(sound_on == 1)
120 {
121 if(ds->volume == DIRECT_SOUND_VOLUME_50)
122 {
123 current_sample >>= 1;
124 next_sample >>= 1;
125 }
126
127 switch(ds->status)
128 {
129 case DIRECT_SOUND_INACTIVE:
130 render_samples(null);
131 break;
132
133 case DIRECT_SOUND_RIGHT:
134 render_samples(right);
135 break;
136
137 case DIRECT_SOUND_LEFT:
138 render_samples(left);
139 break;
140
141 case DIRECT_SOUND_LEFTRIGHT:
142 render_samples(both);
143 break;
144 }
145 }
146 else
147 {
148 render_samples(null);
149 }
150
151 ds->buffer_index = buffer_index;
2f1c528a 152 ds->fifo_fractional = fp8_24_fractional_part(fifo_fractional);
2823a4c8 153
154 if(((ds->fifo_top - ds->fifo_base) % 32) <= 16)
155 {
156 if(dma[1].direct_sound_channel == channel)
157 dma_transfer(dma + 1);
158
159 if(dma[2].direct_sound_channel == channel)
160 dma_transfer(dma + 2);
161 }
162}
163
164void sound_reset_fifo(u32 channel)
165{
166 direct_sound_struct *ds = direct_sound_channel;
167
168 memset(ds->fifo, 0, 32);
169}
170
171// Initial pattern data = 4bits (signed)
172// Channel volume = 12bits
173// Envelope volume = 14bits
174// Master volume = 2bits
175
176// Recalculate left and right volume as volume changes.
177// To calculate the current sample, use (sample * volume) >> 16
178
179// Square waves range from -8 (low) to 7 (high)
180
181s8 square_pattern_duty[4][8] =
182{
183 { 0xF8, 0xF8, 0xF8, 0xF8, 0x07, 0xF8, 0xF8, 0xF8 },
184 { 0xF8, 0xF8, 0xF8, 0xF8, 0x07, 0x07, 0xF8, 0xF8 },
185 { 0xF8, 0xF8, 0x07, 0x07, 0x07, 0x07, 0xF8, 0xF8 },
186 { 0x07, 0x07, 0x07, 0x07, 0xF8, 0xF8, 0x07, 0x07 },
187};
188
189s8 wave_samples[64];
190
191u32 noise_table15[1024];
192u32 noise_table7[4];
193
194u32 gbc_sound_master_volume_table[4] = { 1, 2, 4, 0 };
195
196u32 gbc_sound_channel_volume_table[8] =
197{
198 fixed_div(0, 7, 12),
199 fixed_div(1, 7, 12),
200 fixed_div(2, 7, 12),
201 fixed_div(3, 7, 12),
202 fixed_div(4, 7, 12),
203 fixed_div(5, 7, 12),
204 fixed_div(6, 7, 12),
205 fixed_div(7, 7, 12)
206};
207
208u32 gbc_sound_envelope_volume_table[16] =
209{
210 fixed_div(0, 15, 14),
211 fixed_div(1, 15, 14),
212 fixed_div(2, 15, 14),
213 fixed_div(3, 15, 14),
214 fixed_div(4, 15, 14),
215 fixed_div(5, 15, 14),
216 fixed_div(6, 15, 14),
217 fixed_div(7, 15, 14),
218 fixed_div(8, 15, 14),
219 fixed_div(9, 15, 14),
220 fixed_div(10, 15, 14),
221 fixed_div(11, 15, 14),
222 fixed_div(12, 15, 14),
223 fixed_div(13, 15, 14),
224 fixed_div(14, 15, 14),
225 fixed_div(15, 15, 14)
226};
227
228u32 gbc_sound_buffer_index = 0;
229u32 gbc_sound_last_cpu_ticks = 0;
230u32 gbc_sound_partial_ticks = 0;
231
232u32 gbc_sound_master_volume_left;
233u32 gbc_sound_master_volume_right;
234u32 gbc_sound_master_volume;
235
236#define update_volume_channel_envelope(channel) \
237 volume_##channel = gbc_sound_envelope_volume_table[envelope_volume] * \
238 gbc_sound_channel_volume_table[gbc_sound_master_volume_##channel] * \
239 gbc_sound_master_volume_table[gbc_sound_master_volume] \
240
241#define update_volume_channel_noenvelope(channel) \
242 volume_##channel = gs->wave_volume * \
243 gbc_sound_channel_volume_table[gbc_sound_master_volume_##channel] * \
244 gbc_sound_master_volume_table[gbc_sound_master_volume] \
245
246#define update_volume(type) \
247 update_volume_channel_##type(left); \
248 update_volume_channel_##type(right) \
249
250#define update_tone_sweep() \
251 if(gs->sweep_status) \
252 { \
253 u32 sweep_ticks = gs->sweep_ticks - 1; \
254 \
255 if(sweep_ticks == 0) \
256 { \
257 u32 rate = gs->rate; \
258 \
259 if(gs->sweep_direction) \
260 rate = rate - (rate >> gs->sweep_shift); \
261 else \
262 rate = rate + (rate >> gs->sweep_shift); \
263 \
264 if(rate > 2048) \
265 rate = 2048; \
266 \
2f1c528a 267 frequency_step = float_to_fp16_16(((131072.0f / (2048 - rate)) * 8.0f) \
268 / sound_frequency); \
2823a4c8 269 \
270 gs->frequency_step = frequency_step; \
271 gs->rate = rate; \
272 \
273 sweep_ticks = gs->sweep_initial_ticks; \
274 } \
275 gs->sweep_ticks = sweep_ticks; \
276 } \
277
278#define update_tone_nosweep() \
279
280#define update_tone_envelope() \
281 if(gs->envelope_status) \
282 { \
283 u32 envelope_ticks = gs->envelope_ticks - 1; \
284 envelope_volume = gs->envelope_volume; \
285 \
286 if(envelope_ticks == 0) \
287 { \
288 if(gs->envelope_direction) \
289 { \
290 if(envelope_volume != 15) \
291 envelope_volume = gs->envelope_volume + 1; \
292 } \
293 else \
294 { \
295 if(envelope_volume != 0) \
296 envelope_volume = gs->envelope_volume - 1; \
297 } \
298 \
299 update_volume(envelope); \
300 \
301 gs->envelope_volume = envelope_volume; \
302 gs->envelope_ticks = gs->envelope_initial_ticks; \
303 } \
304 else \
305 { \
306 gs->envelope_ticks = envelope_ticks; \
307 } \
308 } \
309
310#define update_tone_noenvelope() \
311
2823a4c8 312#define update_tone_counters(envelope_op, sweep_op) \
313 tick_counter += gbc_sound_tick_step; \
314 if(tick_counter > 0xFFFF) \
315 { \
316 if(gs->length_status) \
317 { \
318 u32 length_ticks = gs->length_ticks - 1; \
319 gs->length_ticks = length_ticks; \
320 \
321 if(length_ticks == 0) \
322 { \
323 gs->active_flag = 0; \
324 break; \
325 } \
326 } \
327 \
328 update_tone_##envelope_op(); \
329 update_tone_##sweep_op(); \
330 \
331 tick_counter &= 0xFFFF; \
332 } \
333
334#define gbc_sound_render_sample_right() \
335 sound_buffer[buffer_index + 1] += (current_sample * volume_right) >> 22 \
336
337#define gbc_sound_render_sample_left() \
338 sound_buffer[buffer_index] += (current_sample * volume_left) >> 22 \
339
340#define gbc_sound_render_sample_both() \
341 gbc_sound_render_sample_right(); \
342 gbc_sound_render_sample_left() \
343
344#define gbc_sound_render_samples(type, sample_length, envelope_op, sweep_op) \
345 for(i = 0; i < buffer_ticks; i++) \
346 { \
347 current_sample = \
348 sample_data[fp16_16_to_u32(sample_index) % sample_length]; \
349 gbc_sound_render_sample_##type(); \
350 \
351 sample_index += frequency_step; \
352 buffer_index = (buffer_index + 2) % BUFFER_SIZE; \
353 \
354 update_tone_counters(envelope_op, sweep_op); \
355 } \
356
357#define gbc_noise_wrap_full 32767
358
359#define gbc_noise_wrap_half 126
360
361#define get_noise_sample_full() \
362 current_sample = \
363 ((s32)(noise_table15[fp16_16_to_u32(sample_index) >> 5] << \
364 (fp16_16_to_u32(sample_index) & 0x1F)) >> 31) & 0x0F \
365
366#define get_noise_sample_half() \
367 current_sample = \
368 ((s32)(noise_table7[fp16_16_to_u32(sample_index) >> 5] << \
369 (fp16_16_to_u32(sample_index) & 0x1F)) >> 31) & 0x0F \
370
371#define gbc_sound_render_noise(type, noise_type, envelope_op, sweep_op) \
372 for(i = 0; i < buffer_ticks; i++) \
373 { \
374 get_noise_sample_##noise_type(); \
375 gbc_sound_render_sample_##type(); \
376 \
377 sample_index += frequency_step; \
378 \
379 if(sample_index >= u32_to_fp16_16(gbc_noise_wrap_##noise_type)) \
380 sample_index -= u32_to_fp16_16(gbc_noise_wrap_##noise_type); \
381 \
382 buffer_index = (buffer_index + 2) % BUFFER_SIZE; \
383 update_tone_counters(envelope_op, sweep_op); \
384 } \
385
386#define gbc_sound_render_channel(type, sample_length, envelope_op, sweep_op) \
387 buffer_index = gbc_sound_buffer_index; \
388 sample_index = gs->sample_index; \
389 frequency_step = gs->frequency_step; \
390 tick_counter = gs->tick_counter; \
391 \
392 update_volume(envelope_op); \
393 \
394 switch(gs->status) \
395 { \
396 case GBC_SOUND_INACTIVE: \
397 break; \
398 \
399 case GBC_SOUND_LEFT: \
400 gbc_sound_render_##type(left, sample_length, envelope_op, sweep_op); \
401 break; \
402 \
403 case GBC_SOUND_RIGHT: \
404 gbc_sound_render_##type(right, sample_length, envelope_op, sweep_op); \
405 break; \
406 \
407 case GBC_SOUND_LEFTRIGHT: \
408 gbc_sound_render_##type(both, sample_length, envelope_op, sweep_op); \
409 break; \
410 } \
411 \
412 gs->sample_index = sample_index; \
413 gs->tick_counter = tick_counter; \
414
415#define gbc_sound_load_wave_ram(bank) \
416 wave_bank = wave_samples + (bank * 32); \
417 for(i = 0, i2 = 0; i < 16; i++, i2 += 2) \
418 { \
419 current_sample = wave_ram[i]; \
420 wave_bank[i2] = (((current_sample >> 4) & 0x0F) - 8); \
421 wave_bank[i2 + 1] = ((current_sample & 0x0F) - 8); \
422 } \
423
2823a4c8 424void update_gbc_sound(u32 cpu_ticks)
425{
2f1c528a 426 fixed16_16 buffer_ticks = float_to_fp16_16((float)(cpu_ticks -
427 gbc_sound_last_cpu_ticks) * sound_frequency / GBC_BASE_RATE);
2823a4c8 428 u32 i, i2;
429 gbc_sound_struct *gs = gbc_sound_channel;
430 fixed16_16 sample_index, frequency_step;
431 fixed16_16 tick_counter;
432 u32 buffer_index;
433 s32 volume_left, volume_right;
434 u32 envelope_volume;
435 s32 current_sample;
436 u32 sound_status = address16(io_registers, 0x84) & 0xFFF0;
437 s8 *sample_data;
438 s8 *wave_bank;
439 u8 *wave_ram = ((u8 *)io_registers) + 0x90;
440
441 gbc_sound_partial_ticks += fp16_16_fractional_part(buffer_ticks);
442 buffer_ticks = fp16_16_to_u32(buffer_ticks);
443
444 if(gbc_sound_partial_ticks > 0xFFFF)
445 {
446 buffer_ticks += 1;
447 gbc_sound_partial_ticks &= 0xFFFF;
448 }
449
450 SDL_LockMutex(sound_mutex);
451 if(synchronize_flag)
452 {
2f1c528a 453 if(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) >=
454 (audio_buffer_size * 2))
2823a4c8 455 {
456 while(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) >
457 (audio_buffer_size * 3 / 2))
458 {
459 SDL_CondWait(sound_cv, sound_mutex);
460 }
461
462#ifdef PSP_BUILD
463 if(current_frameskip_type == auto_frameskip)
464 {
465 sceDisplayWaitVblankStart();
466 real_frame_count = 0;
467 virtual_frame_count = 0;
468 }
2455b6a3 469#else
2823a4c8 470 if(current_frameskip_type == auto_frameskip)
471 {
2455b6a3 472/*
2823a4c8 473 u64 current_ticks;
474 u64 next_ticks;
475 get_ticks_us(&current_ticks);
476
477 next_ticks = ((current_ticks + 16666) / 16667) * 16667;
478 delay_us(next_ticks - current_ticks);
479
480 get_ticks_us(&frame_count_initial_timestamp);
2455b6a3 481*/
482 /* prevent frameskip, or it will cause more audio,
483 * then more waiting here, then frame skip again, ... */
484 num_skipped_frames = 100;
2823a4c8 485 }
486#endif
487
2823a4c8 488 }
489 }
490 if(sound_on == 1)
491 {
492 gs = gbc_sound_channel + 0;
493 if(gs->active_flag)
494 {
495 sound_status |= 0x01;
496 sample_data = gs->sample_data;
497 envelope_volume = gs->envelope_volume;
498 gbc_sound_render_channel(samples, 8, envelope, sweep);
499 }
500
501 gs = gbc_sound_channel + 1;
502 if(gs->active_flag)
503 {
504 sound_status |= 0x02;
505 sample_data = gs->sample_data;
506 envelope_volume = gs->envelope_volume;
507 gbc_sound_render_channel(samples, 8, envelope, nosweep);
508 }
509
510 gs = gbc_sound_channel + 2;
511 if(gbc_sound_wave_update)
512 {
513 if(gs->wave_bank == 1)
514 {
515 gbc_sound_load_wave_ram(1);
516 }
517 else
518 {
519 gbc_sound_load_wave_ram(0);
520 }
521
522 gbc_sound_wave_update = 0;
523 }
524
525 if((gs->active_flag) && (gs->master_enable))
526 {
527 sound_status |= 0x04;
528 sample_data = wave_samples;
529 if(gs->wave_type == 0)
530 {
531 if(gs->wave_bank == 1)
532 sample_data += 32;
533
534 gbc_sound_render_channel(samples, 32, noenvelope, nosweep);
535 }
536 else
537 {
538 gbc_sound_render_channel(samples, 64, noenvelope, nosweep);
539 }
540 }
541
542 gs = gbc_sound_channel + 3;
543 if(gs->active_flag)
544 {
545 sound_status |= 0x08;
546 envelope_volume = gs->envelope_volume;
547
548 if(gs->noise_type == 1)
549 {
550 gbc_sound_render_channel(noise, half, envelope, nosweep);
551 }
552 else
553 {
554 gbc_sound_render_channel(noise, full, envelope, nosweep);
555 }
556 }
557 }
558
559 address16(io_registers, 0x84) = sound_status;
560
2823a4c8 561 gbc_sound_last_cpu_ticks = cpu_ticks;
562 gbc_sound_buffer_index =
563 (gbc_sound_buffer_index + (buffer_ticks * 2)) % BUFFER_SIZE;
e9c7b137 564
565 SDL_UnlockMutex(sound_mutex);
566
567 SDL_CondSignal(sound_cv);
2823a4c8 568}
569
570#define sound_copy_normal() \
571 current_sample = source[i] \
572
573#define sound_copy(source_offset, length, render_type) \
574 _length = (length) / 2; \
575 source = (s16 *)(sound_buffer + source_offset); \
576 for(i = 0; i < _length; i++) \
577 { \
578 sound_copy_##render_type(); \
579 if(current_sample > 2047) \
580 current_sample = 2047; \
581 if(current_sample < -2048) \
582 current_sample = -2048; \
583 \
584 stream_base[i] = current_sample << 4; \
585 source[i] = 0; \
586 } \
587
588#define sound_copy_null(source_offset, length) \
589 _length = (length) / 2; \
590 source = (s16 *)(sound_buffer + source_offset); \
591 for(i = 0; i < _length; i++) \
592 { \
593 stream_base[i] = 0; \
594 source[i] = 0; \
595 } \
596
597
598void sound_callback(void *userdata, Uint8 *stream, int length)
599{
600 u32 sample_length = length / 2;
601 u32 _length;
602 u32 i;
603 s16 *stream_base = (s16 *)stream;
604 s16 *source;
605 s32 current_sample;
606
607 SDL_LockMutex(sound_mutex);
608
609 while(((gbc_sound_buffer_index - sound_buffer_base) % BUFFER_SIZE) <
2455b6a3 610 length && !sound_exit_flag)
2823a4c8 611 {
612 SDL_CondWait(sound_cv, sound_mutex);
613 }
614
615 if(global_enable_audio)
616 {
617 if((sound_buffer_base + sample_length) >= BUFFER_SIZE)
618 {
619 u32 partial_length = (BUFFER_SIZE - sound_buffer_base) * 2;
620 sound_copy(sound_buffer_base, partial_length, normal);
621 source = (s16 *)sound_buffer;
622 sound_copy(0, length - partial_length, normal);
623 sound_buffer_base = (length - partial_length) / 2;
624 }
625 else
626 {
627 sound_copy(sound_buffer_base, length, normal);
628 sound_buffer_base += sample_length;
629 }
630 }
631 else
632 {
633 if((sound_buffer_base + sample_length) >= BUFFER_SIZE)
634 {
635 u32 partial_length = (BUFFER_SIZE - sound_buffer_base) * 2;
636 sound_copy_null(sound_buffer_base, partial_length);
637 source = (s16 *)sound_buffer;
638 sound_copy(0, length - partial_length, normal);
639 sound_buffer_base = (length - partial_length) / 2;
640 }
641 else
642 {
643 sound_copy_null(sound_buffer_base, length);
644 sound_buffer_base += sample_length;
645 }
646 }
647
648 SDL_CondSignal(sound_cv);
649
650 SDL_UnlockMutex(sound_mutex);
651}
652
653// Special thanks to blarrg for the LSFR frequency used in Meridian, as posted
654// on the forum at http://meridian.overclocked.org:
655// http://meridian.overclocked.org/cgi-bin/wwwthreads/showpost.pl?Board=merid
656// angeneraldiscussion&Number=2069&page=0&view=expanded&mode=threaded&sb=4
657// Hope you don't mind me borrowing it ^_-
658
659void init_noise_table(u32 *table, u32 period, u32 bit_length)
660{
661 u32 shift_register = 0xFF;
662 u32 mask = ~(1 << bit_length);
663 s32 table_pos, bit_pos;
664 u32 current_entry;
665 u32 table_period = (period + 31) / 32;
666
667 // Bits are stored in reverse order so they can be more easily moved to
668 // bit 31, for sign extended shift down.
669
670 for(table_pos = 0; table_pos < table_period; table_pos++)
671 {
672 current_entry = 0;
673 for(bit_pos = 31; bit_pos >= 0; bit_pos--)
674 {
675 current_entry |= (shift_register & 0x01) << bit_pos;
676
677 shift_register =
678 ((1 & (shift_register ^ (shift_register >> 1))) << bit_length) |
679 ((shift_register >> 1) & mask);
680 }
681
682 table[table_pos] = current_entry;
683 }
684}
685
686void reset_sound()
687{
688 direct_sound_struct *ds = direct_sound_channel;
689 gbc_sound_struct *gs = gbc_sound_channel;
690 u32 i;
691
2f1c528a 692 SDL_LockMutex(sound_mutex);
693
2823a4c8 694 sound_on = 0;
695 sound_buffer_base = 0;
696 sound_last_cpu_ticks = 0;
2f1c528a 697 memset(sound_buffer, 0, sizeof(sound_buffer));
2823a4c8 698
699 for(i = 0; i < 2; i++, ds++)
700 {
701 ds->buffer_index = 0;
702 ds->status = DIRECT_SOUND_INACTIVE;
703 ds->fifo_top = 0;
704 ds->fifo_base = 0;
705 ds->fifo_fractional = 0;
706 ds->last_cpu_ticks = 0;
707 memset(ds->fifo, 0, 32);
708 }
709
710 gbc_sound_buffer_index = 0;
711 gbc_sound_last_cpu_ticks = 0;
712 gbc_sound_partial_ticks = 0;
713
714 gbc_sound_master_volume_left = 0;
715 gbc_sound_master_volume_right = 0;
716 gbc_sound_master_volume = 0;
717 memset(wave_samples, 0, 64);
718
719 for(i = 0; i < 4; i++, gs++)
720 {
721 gs->status = GBC_SOUND_INACTIVE;
722 gs->sample_data = square_pattern_duty[2];
723 gs->active_flag = 0;
724 }
2f1c528a 725
726 SDL_UnlockMutex(sound_mutex);
2823a4c8 727}
728
729void sound_exit()
730{
731 gbc_sound_buffer_index =
732 (sound_buffer_base + audio_buffer_size) % BUFFER_SIZE;
733 SDL_PauseAudio(1);
2455b6a3 734 sound_exit_flag = 1;
2823a4c8 735 SDL_CondSignal(sound_cv);
2455b6a3 736 SDL_CloseAudio();
2823a4c8 737}
738
739void init_sound()
740{
bbba3209 741 SDL_AudioSpec sound_settings;
742
2823a4c8 743#ifdef PSP_BUILD
744 audio_buffer_size = (audio_buffer_size_number * 1024) + 3072;
2455b6a3 745#else
2823a4c8 746 audio_buffer_size = 16 << audio_buffer_size_number;
747// audio_buffer_size = 16384;
2823a4c8 748#endif
749
750 SDL_AudioSpec desired_spec =
751 {
752 sound_frequency,
753 AUDIO_S16,
754 2,
755 0,
756 audio_buffer_size / 4,
757 0,
758 0,
759 sound_callback,
760 NULL
761 };
762
2823a4c8 763 sound_mutex = SDL_CreateMutex();
764 sound_cv = SDL_CreateCond();
2455b6a3 765
766 SDL_OpenAudio(&desired_spec, &sound_settings);
767 sound_frequency = sound_settings.freq;
768 audio_buffer_size = sound_settings.size;
769 u32 i = audio_buffer_size / 16;
770 for (audio_buffer_size_number = 0; i && (i & 1) == 0; i >>= 1)
771 audio_buffer_size_number++;
772#ifndef PSP_BUILD
773 printf("audio: freq %d, size %d\n", sound_frequency, audio_buffer_size);
774#endif
775
2f1c528a 776 gbc_sound_tick_step =
777 float_to_fp16_16(256.0f / sound_frequency);
778
779 init_noise_table(noise_table15, 32767, 14);
780 init_noise_table(noise_table7, 127, 6);
781
782 reset_sound();
783
2823a4c8 784 SDL_PauseAudio(0);
785}
786
787#define sound_savestate_builder(type) \
788void sound_##type##_savestate(file_tag_type savestate_file) \
789{ \
790 file_##type##_variable(savestate_file, sound_on); \
791 file_##type##_variable(savestate_file, sound_buffer_base); \
792 file_##type##_variable(savestate_file, sound_last_cpu_ticks); \
793 file_##type##_variable(savestate_file, gbc_sound_buffer_index); \
794 file_##type##_variable(savestate_file, gbc_sound_last_cpu_ticks); \
795 file_##type##_variable(savestate_file, gbc_sound_partial_ticks); \
796 file_##type##_variable(savestate_file, gbc_sound_master_volume_left); \
797 file_##type##_variable(savestate_file, gbc_sound_master_volume_right); \
798 file_##type##_variable(savestate_file, gbc_sound_master_volume); \
799 file_##type##_array(savestate_file, wave_samples); \
800 file_##type##_array(savestate_file, direct_sound_channel); \
801 file_##type##_array(savestate_file, gbc_sound_channel); \
802} \
803
804sound_savestate_builder(read);
805sound_savestate_builder(write_mem);
806