diff options
author | Karl Kurbjun <kkurbjun@gmail.com> | 2007-06-24 16:00:55 +0000 |
---|---|---|
committer | Karl Kurbjun <kkurbjun@gmail.com> | 2007-06-24 16:00:55 +0000 |
commit | 78c45530fff6100240d08be77858350632000de9 (patch) | |
tree | 38d312e754cf87e1ea45ca1faf72fdd2d546fde2 /apps/plugins/rockboy/sound.c | |
parent | 16ca78db033f86c482cceb25dd1eee32aae2ecfc (diff) | |
download | rockbox-78c45530fff6100240d08be77858350632000de9.tar.gz rockbox-78c45530fff6100240d08be77858350632000de9.zip |
Sound improvements for rockboy - players now sync the sound (The gigabeat now plays at a steady 60 fps as long as the frameskip is set properly). If a new sample is not available a blank buffer is used. All devices use 44.1 kHz for gameboy sound now so no more high pitched sounds. Added a screen rotation option. Removed unscaled code for devices with a screensize smaller than the gameboy. All buttons are now configurable. Scroll wheel devices still have button configuration problems though.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13698 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/rockboy/sound.c')
-rw-r--r-- | apps/plugins/rockboy/sound.c | 129 |
1 files changed, 80 insertions, 49 deletions
diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c index 516b9c3f71..aba7f924b4 100644 --- a/apps/plugins/rockboy/sound.c +++ b/apps/plugins/rockboy/sound.c | |||
@@ -7,26 +7,41 @@ | |||
7 | #include "regs.h" | 7 | #include "regs.h" |
8 | #include "noise.h" | 8 | #include "noise.h" |
9 | 9 | ||
10 | static const byte dmgwave[16] = | ||
11 | { | ||
12 | 0xac, 0xdd, 0xda, 0x48, | ||
13 | 0x36, 0x02, 0xcf, 0x16, | ||
14 | 0x2c, 0x04, 0xe5, 0x2c, | ||
15 | 0xac, 0xdd, 0xda, 0x48 | ||
16 | }; | ||
17 | |||
18 | static const byte cgbwave[16] = | ||
19 | { | ||
20 | 0x00, 0xff, 0x00, 0xff, | ||
21 | 0x00, 0xff, 0x00, 0xff, | ||
22 | 0x00, 0xff, 0x00, 0xff, | ||
23 | 0x00, 0xff, 0x00, 0xff, | ||
24 | }; | ||
10 | 25 | ||
11 | static const byte sqwave[4][8] = | 26 | static const byte sqwave[4][8] = |
12 | { | 27 | { |
13 | { 0, 0,-1, 0, 0, 0, 0, 0 }, | 28 | { 0, 0,-1, 0, 0, 0, 0, 0 }, |
14 | { 0,-1,-1, 0, 0, 0, 0, 0 }, | 29 | { 0,-1,-1, 0, 0, 0, 0, 0 }, |
15 | { 0,-1,-1,-1,-1, 0, 0, 0 }, | 30 | { -1,-1,-1,-1, 0, 0, 0, 0 }, |
16 | { -1, 0, 0,-1,-1,-1,-1,-1 } | 31 | { -1, 0, 0,-1,-1,-1,-1,-1 } |
17 | }; | 32 | }; |
18 | 33 | ||
19 | static const int freqtab[8] = | 34 | static const int freqtab[8] = |
20 | { | 35 | { |
21 | (1<<18)*2, | 36 | (1<<14)*2, |
22 | (1<<18), | 37 | (1<<14), |
23 | (1<<18)/2, | 38 | (1<<14)/2, |
24 | (1<<18)/3, | 39 | (1<<14)/3, |
25 | (1<<18)/4, | 40 | (1<<14)/4, |
26 | (1<<18)/5, | 41 | (1<<14)/5, |
27 | (1<<18)/6, | 42 | (1<<14)/6, |
28 | (1<<18)/7 | 43 | (1<<14)/7 |
29 | }; | 44 | }; |
30 | 45 | ||
31 | struct snd snd IBSS_ATTR; | 46 | struct snd snd IBSS_ATTR; |
32 | 47 | ||
@@ -58,13 +73,14 @@ static void s2_freq(void) | |||
58 | static void s3_freq(void) | 73 | static void s3_freq(void) |
59 | { | 74 | { |
60 | int d = 2048 - (((R_NR34&7)<<8) + R_NR33); | 75 | int d = 2048 - (((R_NR34&7)<<8) + R_NR33); |
61 | if (RATE > d) S3.freq = 0; | 76 | if (RATE > (d<<3)) S3.freq = 0; |
62 | else S3.freq = (RATE << 21)/d; | 77 | else S3.freq = (RATE << 21)/d; |
63 | } | 78 | } |
64 | 79 | ||
65 | static void s4_freq(void) | 80 | static void s4_freq(void) |
66 | { | 81 | { |
67 | S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; | 82 | S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; |
83 | if (S4.freq >> 18) S4.freq = 1<<18; | ||
68 | } | 84 | } |
69 | 85 | ||
70 | void sound_dirty(void) | 86 | void sound_dirty(void) |
@@ -74,13 +90,13 @@ void sound_dirty(void) | |||
74 | S1.envol = R_NR12 >> 4; | 90 | S1.envol = R_NR12 >> 4; |
75 | S1.endir = (R_NR12>>3) & 1; | 91 | S1.endir = (R_NR12>>3) & 1; |
76 | S1.endir |= S1.endir - 1; | 92 | S1.endir |= S1.endir - 1; |
77 | S1.enlen = (R_NR12 & 3) << 15; | 93 | S1.enlen = (R_NR12 & 7) << 15; |
78 | s1_freq(); | 94 | s1_freq(); |
79 | S2.len = (64-(R_NR21&63)) << 13; | 95 | S2.len = (64-(R_NR21&63)) << 13; |
80 | S2.envol = R_NR22 >> 4; | 96 | S2.envol = R_NR22 >> 4; |
81 | S2.endir = (R_NR22>>3) & 1; | 97 | S2.endir = (R_NR22>>3) & 1; |
82 | S2.endir |= S2.endir - 1; | 98 | S2.endir |= S2.endir - 1; |
83 | S2.enlen = (R_NR22 & 3) << 15; | 99 | S2.enlen = (R_NR22 & 7) << 15; |
84 | s2_freq(); | 100 | s2_freq(); |
85 | S3.len = (256-R_NR31) << 20; | 101 | S3.len = (256-R_NR31) << 20; |
86 | s3_freq(); | 102 | s3_freq(); |
@@ -88,13 +104,12 @@ void sound_dirty(void) | |||
88 | S4.envol = R_NR42 >> 4; | 104 | S4.envol = R_NR42 >> 4; |
89 | S4.endir = (R_NR42>>3) & 1; | 105 | S4.endir = (R_NR42>>3) & 1; |
90 | S4.endir |= S4.endir - 1; | 106 | S4.endir |= S4.endir - 1; |
91 | S4.enlen = (R_NR42 & 3) << 15; | 107 | S4.enlen = (R_NR42 & 7) << 15; |
92 | s4_freq(); | 108 | s4_freq(); |
93 | } | 109 | } |
94 | 110 | ||
95 | void sound_reset(void) | 111 | void sound_off(void) |
96 | { | 112 | { |
97 | int i; | ||
98 | memset(&snd, 0, sizeof snd); | 113 | memset(&snd, 0, sizeof snd); |
99 | if (pcm.hz) snd.rate = (1<<21) / pcm.hz; | 114 | if (pcm.hz) snd.rate = (1<<21) / pcm.hz; |
100 | else snd.rate = 0; | 115 | else snd.rate = 0; |
@@ -115,11 +130,22 @@ void sound_reset(void) | |||
115 | R_NR44 = 0xBF; | 130 | R_NR44 = 0xBF; |
116 | R_NR50 = 0x77; | 131 | R_NR50 = 0x77; |
117 | R_NR51 = 0xF3; | 132 | R_NR51 = 0xF3; |
118 | R_NR52 = 0xF1; | 133 | R_NR52 = 0x70; |
119 | for (i = 0; i < 16; i++) WAVE[i] = -(i&1); | 134 | // for (i = 0; i < 16; i++) WAVE[i] = -(i&1); |
120 | sound_dirty(); | 135 | sound_dirty(); |
121 | } | 136 | } |
122 | 137 | ||
138 | void sound_reset() | ||
139 | { | ||
140 | memset(&snd, 0, sizeof snd); | ||
141 | if (pcm.hz) snd.rate = (1<<21) / pcm.hz; | ||
142 | else snd.rate = 0; | ||
143 | memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16); | ||
144 | memcpy(ram.hi+0x30, WAVE, 16); | ||
145 | sound_off(); | ||
146 | R_NR52 = 0xF1; | ||
147 | } | ||
148 | |||
123 | void sound_mix(void) | 149 | void sound_mix(void) |
124 | { | 150 | { |
125 | int s, l, r, f, n; | 151 | int s, l, r, f, n; |
@@ -145,7 +171,8 @@ void sound_mix(void) | |||
145 | } | 171 | } |
146 | if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) | 172 | if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) |
147 | { | 173 | { |
148 | f = ((R_NR14 & 7) << 8) + R_NR13; | 174 | S1.swcnt -= S1.swlen; |
175 | f = S1.swfreq; | ||
149 | n = (R_NR10 & 7); | 176 | n = (R_NR10 & 7); |
150 | if (R_NR10 & 8) f -= (f >> n); | 177 | if (R_NR10 & 8) f -= (f >> n); |
151 | else f += (f >> n); | 178 | else f += (f >> n); |
@@ -153,14 +180,15 @@ void sound_mix(void) | |||
153 | S1.on = 0; | 180 | S1.on = 0; |
154 | else | 181 | else |
155 | { | 182 | { |
183 | S1.swfreq = f; | ||
156 | R_NR13 = f; | 184 | R_NR13 = f; |
157 | R_NR14 = (R_NR14 & 0xF8) | (f>>8); | 185 | R_NR14 = (R_NR14 & 0xF8) | (f>>8); |
158 | s1_freq_d(2048 - f); | 186 | s1_freq_d(2048 - f); |
159 | } | 187 | } |
160 | } | 188 | } |
161 | s <<= 2; | 189 | s <<= 2; |
162 | if (R_NR51 & 1) l += s; | 190 | if (R_NR51 & 1) r += s; |
163 | if (R_NR51 & 16) r += s; | 191 | if (R_NR51 & 16) l += s; |
164 | } | 192 | } |
165 | 193 | ||
166 | if (S2.on) | 194 | if (S2.on) |
@@ -177,8 +205,8 @@ void sound_mix(void) | |||
177 | if (S2.envol > 15) S2.envol = 15; | 205 | if (S2.envol > 15) S2.envol = 15; |
178 | } | 206 | } |
179 | s <<= 2; | 207 | s <<= 2; |
180 | if (R_NR51 & 2) l += s; | 208 | if (R_NR51 & 2) r += s; |
181 | if (R_NR51 & 32) r += s; | 209 | if (R_NR51 & 32) l += s; |
182 | } | 210 | } |
183 | 211 | ||
184 | if (S3.on) | 212 | if (S3.on) |
@@ -192,16 +220,16 @@ void sound_mix(void) | |||
192 | S3.on = 0; | 220 | S3.on = 0; |
193 | if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); | 221 | if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); |
194 | else s = 0; | 222 | else s = 0; |
195 | if (R_NR51 & 4) l += s; | 223 | if (R_NR51 & 4) r += s; |
196 | if (R_NR51 & 64) r += s; | 224 | if (R_NR51 & 64) l += s; |
197 | } | 225 | } |
198 | 226 | ||
199 | if (S4.on) | 227 | if (S4.on) |
200 | { | 228 | { |
201 | if (R_NR43 & 8) s = 1 & (noise7[ | 229 | if (R_NR43 & 8) s = 1 & (noise7[ |
202 | (S4.pos>>24)&15] >> ((S4.pos>>21)&7)); | 230 | (S4.pos>>20)&15] >> (7-((S4.pos>>17)&7))); |
203 | else s = 1 & (noise15[ | 231 | else s = 1 & (noise15[ |
204 | (S4.pos>>24)&4095] >> ((S4.pos>>21)&7)); | 232 | (S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7))); |
205 | s = (-s) & S4.envol; | 233 | s = (-s) & S4.envol; |
206 | S4.pos += S4.freq; | 234 | S4.pos += S4.freq; |
207 | if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) | 235 | if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) |
@@ -213,9 +241,9 @@ void sound_mix(void) | |||
213 | if (S4.envol < 0) S4.envol = 0; | 241 | if (S4.envol < 0) S4.envol = 0; |
214 | if (S4.envol > 15) S4.envol = 15; | 242 | if (S4.envol > 15) S4.envol = 15; |
215 | } | 243 | } |
216 | s <<= 2; | 244 | s += s << 1; |
217 | if (R_NR51 & 8) l += s; | 245 | if (R_NR51 & 8) r += s; |
218 | if (R_NR51 & 128) r += s; | 246 | if (R_NR51 & 128) l += s; |
219 | } | 247 | } |
220 | 248 | ||
221 | l *= (R_NR50 & 0x07); | 249 | l *= (R_NR50 & 0x07); |
@@ -234,10 +262,10 @@ void sound_mix(void) | |||
234 | pcm_submit(); | 262 | pcm_submit(); |
235 | if (pcm.stereo) | 263 | if (pcm.stereo) |
236 | { | 264 | { |
237 | pcm.buf[pcm.pos++] = l+128; | 265 | pcm.buf[pcm.pos++] = ((signed char)(l))<<7; |
238 | pcm.buf[pcm.pos++] = r+128; | 266 | pcm.buf[pcm.pos++] = ((signed char)(r))<<7; |
239 | } | 267 | } |
240 | else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; | 268 | else pcm.buf[pcm.pos++] = ((signed char)((l+r)>>1))<<7; |
241 | } | 269 | } |
242 | } | 270 | } |
243 | R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); | 271 | R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); |
@@ -256,12 +284,13 @@ byte sound_read(byte r) | |||
256 | void s1_init(void) | 284 | void s1_init(void) |
257 | { | 285 | { |
258 | S1.swcnt = 0; | 286 | S1.swcnt = 0; |
287 | S1.swfreq = ((R_NR14&7)<<8) + R_NR13; | ||
259 | S1.envol = R_NR12 >> 4; | 288 | S1.envol = R_NR12 >> 4; |
260 | S1.endir = (R_NR12>>3) & 1; | 289 | S1.endir = (R_NR12>>3) & 1; |
261 | S1.endir |= S1.endir - 1; | 290 | S1.endir |= S1.endir - 1; |
262 | S1.enlen = (R_NR12 & 7) << 15; | 291 | S1.enlen = (R_NR12 & 7) << 15; |
292 | if (!S1.on) S1.pos = 0; | ||
263 | S1.on = 1; | 293 | S1.on = 1; |
264 | S1.pos = 0; | ||
265 | S1.cnt = 0; | 294 | S1.cnt = 0; |
266 | S1.encnt = 0; | 295 | S1.encnt = 0; |
267 | } | 296 | } |
@@ -272,17 +301,20 @@ void s2_init(void) | |||
272 | S2.endir = (R_NR22>>3) & 1; | 301 | S2.endir = (R_NR22>>3) & 1; |
273 | S2.endir |= S2.endir - 1; | 302 | S2.endir |= S2.endir - 1; |
274 | S2.enlen = (R_NR22 & 7) << 15; | 303 | S2.enlen = (R_NR22 & 7) << 15; |
304 | if (!S2.on) S2.pos = 0; | ||
275 | S2.on = 1; | 305 | S2.on = 1; |
276 | S2.pos = 0; | ||
277 | S2.cnt = 0; | 306 | S2.cnt = 0; |
278 | S2.encnt = 0; | 307 | S2.encnt = 0; |
279 | } | 308 | } |
280 | 309 | ||
281 | void s3_init(void) | 310 | void s3_init(void) |
282 | { | 311 | { |
283 | S3.pos = 0; | 312 | int i; |
313 | if (!S3.on) S3.pos = 0; | ||
284 | S3.cnt = 0; | 314 | S3.cnt = 0; |
285 | S3.on = R_NR30 >> 7; | 315 | S3.on = R_NR30 >> 7; |
316 | if (S3.on) for (i = 0; i < 16; i++) | ||
317 | ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31]; | ||
286 | } | 318 | } |
287 | 319 | ||
288 | void s4_init(void) | 320 | void s4_init(void) |
@@ -306,7 +338,8 @@ void sound_write(byte r, byte b) | |||
306 | if ((r & 0xF0) == 0x30) | 338 | if ((r & 0xF0) == 0x30) |
307 | { | 339 | { |
308 | if (S3.on) sound_mix(); | 340 | if (S3.on) sound_mix(); |
309 | if (!S3.on) WAVE[r - 0x30] = b; | 341 | if (!S3.on) |
342 | WAVE[r-0x30] = ram.hi[r] = b; | ||
310 | return; | 343 | return; |
311 | } | 344 | } |
312 | sound_mix(); | 345 | sound_mix(); |
@@ -314,6 +347,8 @@ void sound_write(byte r, byte b) | |||
314 | { | 347 | { |
315 | case RI_NR10: | 348 | case RI_NR10: |
316 | R_NR10 = b; | 349 | R_NR10 = b; |
350 | S1.swlen = ((R_NR10>>4) & 7) << 14; | ||
351 | S1.swfreq = ((R_NR14&7)<<8) + R_NR13; | ||
317 | break; | 352 | break; |
318 | case RI_NR11: | 353 | case RI_NR11: |
319 | R_NR11 = b; | 354 | R_NR11 = b; |
@@ -361,7 +396,7 @@ void sound_write(byte r, byte b) | |||
361 | break; | 396 | break; |
362 | case RI_NR31: | 397 | case RI_NR31: |
363 | R_NR31 = b; | 398 | R_NR31 = b; |
364 | S3.len = (256-R_NR31) << 20; | 399 | S3.len = (256-R_NR31) << 13; |
365 | break; | 400 | break; |
366 | case RI_NR32: | 401 | case RI_NR32: |
367 | R_NR32 = b; | 402 | R_NR32 = b; |
@@ -403,13 +438,9 @@ void sound_write(byte r, byte b) | |||
403 | case RI_NR52: | 438 | case RI_NR52: |
404 | R_NR52 = b; | 439 | R_NR52 = b; |
405 | if (!(R_NR52 & 128)) | 440 | if (!(R_NR52 & 128)) |
406 | sound_reset(); | 441 | sound_off(); |
407 | break; | 442 | break; |
408 | default: | 443 | default: |
409 | return; | 444 | return; |
410 | } | 445 | } |
411 | } | 446 | } |
412 | |||
413 | |||
414 | |||
415 | |||