Mercurial > sdl-ios-xcode
comparison src/audio/dc/aica.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 11775724e3fe |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
40 irq_restore(OLD); \ | 40 irq_restore(OLD); \ |
41 } while(0) | 41 } while(0) |
42 | 42 |
43 | 43 |
44 void | 44 void |
45 aica_init () | 45 aica_init() |
46 { | 46 { |
47 int i, j, old = 0; | 47 int i, j, old = 0; |
48 | 48 |
49 /* Initialize AICA channels */ | 49 /* Initialize AICA channels */ |
50 G2_LOCK (old); | 50 G2_LOCK(old); |
51 SNDREG32 (0x2800) = 0x0000; | 51 SNDREG32(0x2800) = 0x0000; |
52 | 52 |
53 for (i = 0; i < 64; i++) { | 53 for (i = 0; i < 64; i++) { |
54 for (j = 0; j < 0x80; j += 4) { | 54 for (j = 0; j < 0x80; j += 4) { |
55 if ((j & 31) == 0) | 55 if ((j & 31) == 0) |
56 g2_fifo_wait (); | 56 g2_fifo_wait(); |
57 CHNREG32 (i, j) = 0; | 57 CHNREG32(i, j) = 0; |
58 } | 58 } |
59 g2_fifo_wait (); | 59 g2_fifo_wait(); |
60 CHNREG32 (i, 0) = 0x8000; | 60 CHNREG32(i, 0) = 0x8000; |
61 CHNREG32 (i, 20) = 0x1f; | 61 CHNREG32(i, 20) = 0x1f; |
62 } | 62 } |
63 | 63 |
64 SNDREG32 (0x2800) = 0x000f; | 64 SNDREG32(0x2800) = 0x000f; |
65 g2_fifo_wait (); | 65 g2_fifo_wait(); |
66 G2_UNLOCK (old); | 66 G2_UNLOCK(old); |
67 } | 67 } |
68 | 68 |
69 /* Translates a volume from linear form to logarithmic form (required by | 69 /* Translates a volume from linear form to logarithmic form (required by |
70 the AICA chip */ | 70 the AICA chip */ |
71 /* int logs[] = { | 71 /* int logs[] = { |
117 #define AICA_PAN(x) ((x)==0x80?(0):((x)<0x80?(0x1f):(0x0f))) | 117 #define AICA_PAN(x) ((x)==0x80?(0):((x)<0x80?(0x1f):(0x0f))) |
118 #define AICA_VOL(x) (0xff - logs[128 + (((x) & 0xff) / 2)]) | 118 #define AICA_VOL(x) (0xff - logs[128 + (((x) & 0xff) / 2)]) |
119 //#define AICA_VOL(x) (0xff - logs[x&255]) | 119 //#define AICA_VOL(x) (0xff - logs[x&255]) |
120 | 120 |
121 static inline unsigned | 121 static inline unsigned |
122 AICA_FREQ (unsigned freq) | 122 AICA_FREQ(unsigned freq) |
123 { | 123 { |
124 unsigned long freq_lo, freq_base = 5644800; | 124 unsigned long freq_lo, freq_base = 5644800; |
125 int freq_hi = 7; | 125 int freq_hi = 7; |
126 | 126 |
127 /* Need to convert frequency to floating point format | 127 /* Need to convert frequency to floating point format |
154 pan is a panning constant -- 0 is left, 128 is center, 255 is right. | 154 pan is a panning constant -- 0 is left, 128 is center, 255 is right. |
155 | 155 |
156 This routine (and the similar ones) owe a lot to Marcus' sound example -- | 156 This routine (and the similar ones) owe a lot to Marcus' sound example -- |
157 I hadn't gotten quite this far into dissecting the individual regs yet. */ | 157 I hadn't gotten quite this far into dissecting the individual regs yet. */ |
158 void | 158 void |
159 aica_play (int ch, int mode, unsigned long smpptr, int loopst, int loopend, | 159 aica_play(int ch, int mode, unsigned long smpptr, int loopst, int loopend, |
160 int freq, int vol, int pan, int loopflag) | 160 int freq, int vol, int pan, int loopflag) |
161 { | 161 { |
162 /* int i; | 162 /* int i; |
163 */ | 163 */ |
164 int val; | 164 int val; |
165 int old = 0; | 165 int old = 0; |
166 | 166 |
167 /* Stop the channel (if it's already playing) */ | 167 /* Stop the channel (if it's already playing) */ |
168 aica_stop (ch); | 168 aica_stop(ch); |
169 /* doesn't seem to be needed, but it's here just in case */ | 169 /* doesn't seem to be needed, but it's here just in case */ |
170 /* | 170 /* |
171 for (i=0; i<256; i++) { | 171 for (i=0; i<256; i++) { |
172 asm("nop"); | 172 asm("nop"); |
173 asm("nop"); | 173 asm("nop"); |
174 asm("nop"); | 174 asm("nop"); |
175 asm("nop"); | 175 asm("nop"); |
176 } | 176 } |
177 */ | 177 */ |
178 G2_LOCK (old); | 178 G2_LOCK(old); |
179 /* Envelope setup. The first of these is the loop point, | 179 /* Envelope setup. The first of these is the loop point, |
180 e.g., where the sample starts over when it loops. The second | 180 e.g., where the sample starts over when it loops. The second |
181 is the loop end. This is the full length of the sample when | 181 is the loop end. This is the full length of the sample when |
182 you are not looping, or the loop end point when you are (though | 182 you are not looping, or the loop end point when you are (though |
183 storing more than that is a waste of memory if you're not doing | 183 storing more than that is a waste of memory if you're not doing |
184 volume enveloping). */ | 184 volume enveloping). */ |
185 CHNREG32 (ch, 8) = loopst & 0xffff; | 185 CHNREG32(ch, 8) = loopst & 0xffff; |
186 CHNREG32 (ch, 12) = loopend & 0xffff; | 186 CHNREG32(ch, 12) = loopend & 0xffff; |
187 | 187 |
188 /* Write resulting values */ | 188 /* Write resulting values */ |
189 CHNREG32 (ch, 24) = AICA_FREQ (freq); | 189 CHNREG32(ch, 24) = AICA_FREQ(freq); |
190 | 190 |
191 /* Set volume, pan, and some other things that we don't know what | 191 /* Set volume, pan, and some other things that we don't know what |
192 they do =) */ | 192 they do =) */ |
193 CHNREG32 (ch, 36) = AICA_PAN (pan) | (0xf << 8); | 193 CHNREG32(ch, 36) = AICA_PAN(pan) | (0xf << 8); |
194 /* Convert the incoming volume and pan into hardware values */ | 194 /* Convert the incoming volume and pan into hardware values */ |
195 /* Vol starts at zero so we can ramp */ | 195 /* Vol starts at zero so we can ramp */ |
196 vol = AICA_VOL (vol); | 196 vol = AICA_VOL(vol); |
197 CHNREG32 (ch, 40) = 0x24 | (vol << 8); | 197 CHNREG32(ch, 40) = 0x24 | (vol << 8); |
198 /* Convert the incoming volume and pan into hardware values */ | 198 /* Convert the incoming volume and pan into hardware values */ |
199 /* Vol starts at zero so we can ramp */ | 199 /* Vol starts at zero so we can ramp */ |
200 | 200 |
201 /* If we supported volume envelopes (which we don't yet) then | 201 /* If we supported volume envelopes (which we don't yet) then |
202 this value would set that up. The top 4 bits determine the | 202 this value would set that up. The top 4 bits determine the |
203 envelope speed. f is the fastest, 1 is the slowest, and 0 | 203 envelope speed. f is the fastest, 1 is the slowest, and 0 |
204 seems to be an invalid value and does weird things). The | 204 seems to be an invalid value and does weird things). The |
205 default (below) sets it into normal mode (play and terminate/loop). | 205 default (below) sets it into normal mode (play and terminate/loop). |
206 CHNREG32(ch, 16) = 0xf010; | 206 CHNREG32(ch, 16) = 0xf010; |
207 */ | 207 */ |
208 CHNREG32 (ch, 16) = 0x1f; /* No volume envelope */ | 208 CHNREG32(ch, 16) = 0x1f; /* No volume envelope */ |
209 | 209 |
210 | 210 |
211 /* Set sample format, buffer address, and looping control. If | 211 /* Set sample format, buffer address, and looping control. If |
212 0x0200 mask is set on reg 0, the sample loops infinitely. If | 212 0x0200 mask is set on reg 0, the sample loops infinitely. If |
213 it's not set, the sample plays once and terminates. We'll | 213 it's not set, the sample plays once and terminates. We'll |
214 also set the bits to start playback here. */ | 214 also set the bits to start playback here. */ |
215 CHNREG32 (ch, 4) = smpptr & 0xffff; | 215 CHNREG32(ch, 4) = smpptr & 0xffff; |
216 val = 0xc000 | 0x0000 | (mode << 7) | (smpptr >> 16); | 216 val = 0xc000 | 0x0000 | (mode << 7) | (smpptr >> 16); |
217 if (loopflag) | 217 if (loopflag) |
218 val |= 0x200; | 218 val |= 0x200; |
219 | 219 |
220 CHNREG32 (ch, 0) = val; | 220 CHNREG32(ch, 0) = val; |
221 | 221 |
222 G2_UNLOCK (old); | 222 G2_UNLOCK(old); |
223 | 223 |
224 /* Enable playback */ | 224 /* Enable playback */ |
225 /* CHNREG32(ch, 0) |= 0xc000; */ | 225 /* CHNREG32(ch, 0) |= 0xc000; */ |
226 g2_fifo_wait (); | 226 g2_fifo_wait(); |
227 | 227 |
228 #if 0 | 228 #if 0 |
229 for (i = 0xff; i >= vol; i--) { | 229 for (i = 0xff; i >= vol; i--) { |
230 if ((i & 7) == 0) | 230 if ((i & 7) == 0) |
231 g2_fifo_wait (); | 231 g2_fifo_wait(); |
232 CHNREG32 (ch, 40) = 0x24 | (i << 8);; | 232 CHNREG32(ch, 40) = 0x24 | (i << 8);; |
233 } | 233 } |
234 | 234 |
235 g2_fifo_wait (); | 235 g2_fifo_wait(); |
236 #endif | 236 #endif |
237 } | 237 } |
238 | 238 |
239 /* Stop the sound on a given channel */ | 239 /* Stop the sound on a given channel */ |
240 void | 240 void |
241 aica_stop (int ch) | 241 aica_stop(int ch) |
242 { | 242 { |
243 g2_write_32 (CHNREGADDR (ch, 0), | 243 g2_write_32(CHNREGADDR(ch, 0), |
244 (g2_read_32 (CHNREGADDR (ch, 0)) & ~0x4000) | 0x8000); | 244 (g2_read_32(CHNREGADDR(ch, 0)) & ~0x4000) | 0x8000); |
245 g2_fifo_wait (); | 245 g2_fifo_wait(); |
246 } | 246 } |
247 | 247 |
248 | 248 |
249 /* The rest of these routines can change the channel in mid-stride so you | 249 /* The rest of these routines can change the channel in mid-stride so you |
250 can do things like vibrato and panning effects. */ | 250 can do things like vibrato and panning effects. */ |
251 | 251 |
252 /* Set channel volume */ | 252 /* Set channel volume */ |
253 void | 253 void |
254 aica_vol (int ch, int vol) | 254 aica_vol(int ch, int vol) |
255 { | 255 { |
256 // g2_write_8(CHNREGADDR(ch, 41),AICA_VOL(vol)); | 256 // g2_write_8(CHNREGADDR(ch, 41),AICA_VOL(vol)); |
257 g2_write_32 (CHNREGADDR (ch, 40), | 257 g2_write_32(CHNREGADDR(ch, 40), |
258 (g2_read_32 (CHNREGADDR (ch, 40)) & 0xffff00ff) | | 258 (g2_read_32(CHNREGADDR(ch, 40)) & 0xffff00ff) | |
259 (AICA_VOL (vol) << 8)); | 259 (AICA_VOL(vol) << 8)); |
260 g2_fifo_wait (); | 260 g2_fifo_wait(); |
261 } | 261 } |
262 | 262 |
263 /* Set channel pan */ | 263 /* Set channel pan */ |
264 void | 264 void |
265 aica_pan (int ch, int pan) | 265 aica_pan(int ch, int pan) |
266 { | 266 { |
267 // g2_write_8(CHNREGADDR(ch, 36),AICA_PAN(pan)); | 267 // g2_write_8(CHNREGADDR(ch, 36),AICA_PAN(pan)); |
268 g2_write_32 (CHNREGADDR (ch, 36), | 268 g2_write_32(CHNREGADDR(ch, 36), |
269 (g2_read_32 (CHNREGADDR (ch, 36)) & 0xffffff00) | | 269 (g2_read_32(CHNREGADDR(ch, 36)) & 0xffffff00) | |
270 (AICA_PAN (pan))); | 270 (AICA_PAN(pan))); |
271 g2_fifo_wait (); | 271 g2_fifo_wait(); |
272 } | 272 } |
273 | 273 |
274 /* Set channel frequency */ | 274 /* Set channel frequency */ |
275 void | 275 void |
276 aica_freq (int ch, int freq) | 276 aica_freq(int ch, int freq) |
277 { | 277 { |
278 g2_write_32 (CHNREGADDR (ch, 24), AICA_FREQ (freq)); | 278 g2_write_32(CHNREGADDR(ch, 24), AICA_FREQ(freq)); |
279 g2_fifo_wait (); | 279 g2_fifo_wait(); |
280 } | 280 } |
281 | 281 |
282 /* Get channel position */ | 282 /* Get channel position */ |
283 int | 283 int |
284 aica_get_pos (int ch) | 284 aica_get_pos(int ch) |
285 { | 285 { |
286 #if 1 | 286 #if 1 |
287 /* Observe channel ch */ | 287 /* Observe channel ch */ |
288 g2_write_32 (SNDREGADDR (0x280c), | 288 g2_write_32(SNDREGADDR(0x280c), |
289 (g2_read_32 (SNDREGADDR (0x280c)) & 0xffff00ff) | (ch << 8)); | 289 (g2_read_32(SNDREGADDR(0x280c)) & 0xffff00ff) | (ch << 8)); |
290 g2_fifo_wait (); | 290 g2_fifo_wait(); |
291 /* Update position counters */ | 291 /* Update position counters */ |
292 return g2_read_32 (SNDREGADDR (0x2814)) & 0xffff; | 292 return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; |
293 #else | 293 #else |
294 /* Observe channel ch */ | 294 /* Observe channel ch */ |
295 g2_write_8 (SNDREGADDR (0x280d), ch); | 295 g2_write_8(SNDREGADDR(0x280d), ch); |
296 /* Update position counters */ | 296 /* Update position counters */ |
297 return g2_read_32 (SNDREGADDR (0x2814)) & 0xffff; | 297 return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; |
298 #endif | 298 #endif |
299 } | 299 } |
300 | 300 |
301 /* vi: set ts=4 sw=4 expandtab: */ | 301 /* vi: set ts=4 sw=4 expandtab: */ |