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