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: */