Mercurial > hg > dmlib
comparison jssmix.c @ 287:1e89cd081956
Use fixed point everywhere in the mixing internals, to avoid going over
sample boundaries.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 11 Oct 2012 11:09:26 +0300 |
parents | b7e23d91a8c2 |
children | 701c3d22e0f9 |
comparison
equal
deleted
inserted
replaced
286:a17e54015bd9 | 287:1e89cd081956 |
---|---|
26 { | 26 { |
27 int mixerID; | 27 int mixerID; |
28 int outFormat; | 28 int outFormat; |
29 int outChannels; | 29 int outChannels; |
30 | 30 |
31 int (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32); | 31 int (*jvmMixChannel_FW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint); |
32 int (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const Sint32); | 32 int (*jvmMixChannel_BW)(JSSMixer *, JSSChannel *, JMIXER_ADDBUF_TYPE *, const int, const DMFixedPoint); |
33 void (*jvmPostProcess)(JMIXER_ADDBUF_TYPE *, void *, const int); | 33 void (*jvmPostProcess)(JMIXER_ADDBUF_TYPE *, void *, const int); |
34 } JSSMixingRoutine; | 34 } JSSMixingRoutine; |
35 | 35 |
36 | 36 |
37 /* This table should be sorted from fastest to slowest, e.g. MMX/x86 | 37 /* This table should be sorted from fastest to slowest, e.g. MMX/x86 |
248 { | 248 { |
249 // Sample is looped | 249 // Sample is looped |
250 if (chn->chFlags & jsfBiDi) | 250 if (chn->chFlags & jsfBiDi) |
251 { | 251 { |
252 // Bi-directional loop | 252 // Bi-directional loop |
253 if (FP_GETH(chn->chPos) >= chn->chLoopE) | 253 if (chn->chPos.dw >= chn->chLoopE.dw) |
254 { | 254 { |
255 DMFixedPoint end; | 255 DMFixedPoint end; |
256 FP_SETHL(end, chn->chLoopE + chn->chLoopE, 0); | 256 FP_ADD_R(end, chn->chLoopE, chn->chLoopE); |
257 FP_SUB_R(chn->chPos, end, chn->chPos); | 257 FP_SUB_R(chn->chPos, end, chn->chPos); |
258 chn->chDirection = FALSE; | 258 chn->chDirection = FALSE; |
259 } | 259 } |
260 } | 260 } |
261 else | 261 else |
262 { | 262 { |
263 // Normal forward loop | 263 // Normal forward loop |
264 if (FP_GETH(chn->chPos) >= chn->chLoopE) | 264 if (chn->chPos.dw >= chn->chLoopE.dw) |
265 { | 265 { |
266 DMFixedPoint diff, end; | 266 DMFixedPoint diff; |
267 FP_SETHL(end, chn->chLoopE, 0); | 267 FP_SUB_R(diff, chn->chPos, chn->chLoopE); |
268 FP_SUB_R(diff, chn->chPos, end); | 268 FP_ADD_R(chn->chPos, chn->chLoopS, diff); |
269 FP_SETHL(chn->chPos, chn->chLoopS, 0); | |
270 FP_ADD(chn->chPos, diff); | |
271 } | 269 } |
272 } | 270 } |
273 } | 271 } |
274 else | 272 else |
275 { | 273 { |
276 // Normal (non-looped) sample | 274 // Normal (non-looped) sample |
277 if (FP_GETH(chn->chPos) >= chn->chSize) | 275 if (chn->chPos.dw >= chn->chSize.dw) |
278 { | 276 { |
279 chn->chPlaying = FALSE; | 277 chn->chPlaying = FALSE; |
280 return; | 278 return; |
281 } | 279 } |
282 } | 280 } |
288 { | 286 { |
289 // Sample is looped | 287 // Sample is looped |
290 if (chn->chFlags & jsfBiDi) | 288 if (chn->chFlags & jsfBiDi) |
291 { | 289 { |
292 // Bi-directional loop | 290 // Bi-directional loop |
293 if (FP_GETH(chn->chPos) <= chn->chLoopS) | 291 if (chn->chPos.dw <= chn->chLoopS.dw) |
294 { | 292 { |
295 DMFixedPoint start; | 293 DMFixedPoint start; |
296 FP_SETHL(start, chn->chLoopS + chn->chLoopS, 0); | 294 FP_ADD_R(start, chn->chLoopS, chn->chLoopS); |
297 FP_SUB_R(chn->chPos, start, chn->chPos); | 295 FP_SUB_R(chn->chPos, start, chn->chPos); |
298 chn->chDirection = TRUE; | 296 chn->chDirection = TRUE; |
299 } | 297 } |
300 } | 298 } |
301 else | 299 else |
302 { | 300 { |
303 // Normal forward loop | 301 // Normal forward loop |
304 if (FP_GETH(chn->chPos) <= chn->chLoopS) | 302 if (chn->chPos.dw <= chn->chLoopS.dw) |
305 { | 303 { |
306 DMFixedPoint diff; | 304 DMFixedPoint diff; |
307 FP_SETHL(diff, chn->chLoopE - chn->chLoopS, 0); | 305 FP_SUB_R(diff, chn->chLoopE, chn->chLoopS); |
308 FP_ADD(chn->chPos, diff); | 306 FP_ADD(chn->chPos, diff); |
309 } | 307 } |
310 } | 308 } |
311 } | 309 } |
312 else | 310 else |
313 { | 311 { |
314 // Normal (non-looped) sample | 312 // Normal (non-looped) sample |
315 if (FP_GETH(chn->chPos) <= 0) | 313 if (chn->chPos.dw <= 0) |
316 { | 314 { |
317 chn->chPlaying = FALSE; | 315 chn->chPlaying = FALSE; |
318 return; | 316 return; |
319 } | 317 } |
320 } | 318 } |
324 if (chn->chDirection) | 322 if (chn->chDirection) |
325 { | 323 { |
326 DBG("MIX_FW[%p : %d : ", ab, mixDone); | 324 DBG("MIX_FW[%p : %d : ", ab, mixDone); |
327 if (chn->chFlags & jsfLooped) | 325 if (chn->chFlags & jsfLooped) |
328 { | 326 { |
329 DBG("%d (%x)] {loop}\n", chn->chLoopE, chn->chLoopE); | 327 DBG("%d (%x)] {loop}\n", FP_GETH(chn->chLoopE), FP_GETH(chn->chLoopE)); |
330 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn, | 328 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn, |
331 ab, mixDone, chn->chLoopE); | 329 ab, mixDone, chn->chLoopE); |
332 } | 330 } |
333 else | 331 else |
334 { | 332 { |
335 DBG("%d (%x)]\n", chn->chSize, chn->chSize); | 333 DBG("%d (%x)]\n", FP_GETH(chn->chSize), FP_GETH(chn->chSize)); |
336 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn, | 334 mixResult = mixer->jvmMixChannel_FW((void *) mixer, chn, |
337 ab, mixDone, chn->chSize); | 335 ab, mixDone, chn->chSize); |
338 } | 336 } |
339 } | 337 } |
340 else | 338 else |
346 mixResult = mixer->jvmMixChannel_BW(mixer, chn, | 344 mixResult = mixer->jvmMixChannel_BW(mixer, chn, |
347 ab, mixDone, chn->chLoopS); | 345 ab, mixDone, chn->chLoopS); |
348 } | 346 } |
349 else | 347 else |
350 { | 348 { |
349 static const DMFixedPoint zero = { 0 }; | |
351 DBG("%d (%x)]\n", 0, 0); | 350 DBG("%d (%x)]\n", 0, 0); |
352 mixResult = mixer->jvmMixChannel_BW(mixer, chn, | 351 mixResult = mixer->jvmMixChannel_BW(mixer, chn, |
353 ab, mixDone, 0); | 352 ab, mixDone, zero); |
354 } | 353 } |
355 } | 354 } |
356 | 355 |
357 mixDone -= mixResult; | 356 mixDone -= mixResult; |
358 ab += mixResult * mixer->outChannels; | 357 ab += mixResult * mixer->outChannels; |
516 JSSChannel *c; | 515 JSSChannel *c; |
517 | 516 |
518 JSS_LOCK(mixer); | 517 JSS_LOCK(mixer); |
519 c = &mixer->channels[channel]; | 518 c = &mixer->channels[channel]; |
520 | 519 |
520 FP_SETHL(c->chSize, size, 0); | |
521 FP_SETHL(c->chLoopS, loopS, 0); | |
522 FP_SETHL(c->chLoopE, loopE, 0); | |
521 c->chData = data; | 523 c->chData = data; |
522 c->chSize = size; | |
523 c->chLoopS = loopS; | |
524 c->chLoopE = loopE; | |
525 c->chFlags = flags; | 524 c->chFlags = flags; |
526 c->chDirection = TRUE; | 525 c->chDirection = TRUE; |
527 c->chPos.dw = c->chDeltaO.dw = 0; | 526 c->chPos.dw = c->chDeltaO.dw = 0; |
528 | 527 |
529 JSS_UNLOCK(mixer); | 528 JSS_UNLOCK(mixer); |