Mercurial > hg > dmlib
changeset 134:1ba202b448e0
Implement volume and panning ramps (interpolation between callbacks aka "frames")
in the mixer.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 05 Oct 2012 02:47:36 +0300 |
parents | 92cc5e1fa180 |
children | ff0fe1d1ab3d |
files | jmix_c_in.c jmixtmpl_c.h jssmix.c jssmix.h |
diffstat | 4 files changed, 60 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/jmix_c_in.c Fri Oct 05 00:36:40 2012 +0300 +++ b/jmix_c_in.c Fri Oct 05 02:47:36 2012 +0300 @@ -12,8 +12,9 @@ /* Mono / Linear Interpolation */ #define JMIXER_SAMPLE_TYPE Sint16 -#define JMIXER_INIT const Sint32 vol = (chn->chVolume * mixer->globalVol) / 256; +#define JMIXER_INIT #define JMIXER_FUNC \ + const Sint32 vol = (FP_GETH(tmpVolume) * mixer->globalVol) / 256; \ memmove(&tl[0], &tl[1], 4 * sizeof(tl[0])); \ tl[4] = (((Sint32) sp[FP_GETH(tmpPos)]) * vol * 3 + tl[3] * 2 + tl[2] + tl[1] + tl[0]) / (256 * 8); *(ap++) += tl[4]; \ @@ -36,10 +37,11 @@ /* Stereo / Linear Interpolation */ #define JMIXER_SAMPLE_TYPE Sint16 -#define JMIXER_INIT const Sint32 vol_l = (chn->chVolume * mixer->globalVol) / 256, \ - vol_r = (chn->chVolume * mixer->globalVol) / 256; +#define JMIXER_INIT #define JMIXER_FUNC \ + const Sint32 vol_l = (FP_GETH(tmpVolume) * mixer->globalVol) / 256, \ + vol_r = (FP_GETH(tmpVolume) * mixer->globalVol) / 256; \ memmove(&tl[0], &tl[1], 4 * sizeof(tl[0])); \ memmove(&tr[0], &tr[1], 4 * sizeof(tr[0])); \ tl[4] = (((Sint32) sp[FP_GETH(tmpPos)]) * vol_l * 3 + tl[3] * 2 + tl[2] + tl[1] + tl[0]) / (256 * 8); *(ap++) += tl[4]; \
--- a/jmixtmpl_c.h Fri Oct 05 00:36:40 2012 +0300 +++ b/jmixtmpl_c.h Fri Oct 05 02:47:36 2012 +0300 @@ -9,8 +9,8 @@ #else int JMIXER_NAME (JSSMixer *mixer, JSSChannel *chn, JMIXER_ADDBUF_TYPE *addBuffer, const int mixLength, const Sint32 endPos) { - const DMFixedPoint tmpDelta = chn->chDeltaO; - DMFixedPoint tmpPos = chn->chPos; + const DMFixedPoint tmpDelta = chn->chDeltaO, tmpDeltaV = chn->chDeltaV; + DMFixedPoint tmpPos = chn->chPos, tmpVolume = chn->chVolume; JMIXER_ADDBUF_TYPE *ap = addBuffer, *tr = chn->chPrevR, @@ -26,10 +26,12 @@ JMIXER_FUNC JMIXER_DEBUG JMIXER_NEXT + FP_ADD(tmpVolume, tmpDeltaV); strideLength++; } - chn->chPos.dw = tmpPos.dw; + chn->chPos = tmpPos; + chn->chVolume = tmpVolume; return strideLength; } #endif
--- a/jssmix.c Fri Oct 05 00:36:40 2012 +0300 +++ b/jssmix.c Fri Oct 05 02:47:36 2012 +0300 @@ -385,6 +385,12 @@ { if (mixer->cbCounter <= 0) { + for (i = 0; i < jsetNChannels; i++) + { + JSSChannel *chn = &(mixer->channels[i]); + if (chn->chPlaying && !chn->chMute) + chn->chDeltaV.dw = chn->chDeltaP.dw = 0; + } mixer->cbFunction(mixer, mixer->cbData); mixer->cbCounter = mixer->cbFreq; } @@ -459,13 +465,13 @@ { assert(mixer); - if ((cbFreq < 1) || (cbFreq >= mixer->outFreq)) + if (cbFreq < 1 || cbFreq >= mixer->outFreq) JSSERROR(DMERR_INVALID_ARGS, DMERR_INVALID_ARGS, "Invalid callback frequency given (%i / %i)\n", cbFreq, mixer->outFreq); JSS_LOCK(mixer); - mixer->cbFreq = (mixer->outFreq / cbFreq); + mixer->cbFreq = mixer->outFreq / cbFreq; mixer->cbCounter = 0; //fprintf(stderr, "set(outFreq = %d, cbFreq = %d) = %d\n", mixer->outFreq, cbFreq, mixer->cbFreq); @@ -553,7 +559,22 @@ void jvmSetVolume(JSSMixer * mixer, const int channel, const int volume) { JSS_LOCK(mixer); - mixer->channels[channel].chVolume = volume; + FP_SETHL(mixer->channels[channel].chVolume, volume, 0); + mixer->channels[channel].chDeltaV.dw = 0; + JSS_UNLOCK(mixer); +} + + +void jvmSetVolumeRamp(JSSMixer * mixer, const int channel, const int start, const int end) +{ + DMFixedPoint a, b; + JSS_LOCK(mixer); + FP_SETHL(mixer->channels[channel].chVolume, start, 0); + + FP_SETHL(a, (end - start), 0); + FP_CONV(b, mixer->cbFreq); + FP_DIV_R(mixer->channels[channel].chDeltaV, a, b); + JSS_UNLOCK(mixer); } @@ -563,7 +584,7 @@ int tmp; JSS_LOCK(mixer); - tmp = mixer->channels[channel].chVolume; + tmp = FP_GETH(mixer->channels[channel].chVolume); JSS_UNLOCK(mixer); return tmp; @@ -573,8 +594,7 @@ void jvmSetPos(JSSMixer * mixer, const int channel, const Sint32 pos) { JSS_LOCK(mixer); - FP_SETH(mixer->channels[channel].chPos, pos); - FP_SETL(mixer->channels[channel].chPos, 0); + FP_SETHL(mixer->channels[channel].chPos, pos, 0); JSS_UNLOCK(mixer); } @@ -594,7 +614,20 @@ void jvmSetPan(JSSMixer * mixer, const int channel, const int panning) { JSS_LOCK(mixer); - mixer->channels[channel].chPanning = panning; + FP_SETHL(mixer->channels[channel].chPanning, panning, 0); + mixer->channels[channel].chDeltaP.dw = 0; + JSS_UNLOCK(mixer); +} + + +void jvmSetPanRamp(JSSMixer * mixer, const int channel, const int start, const int end) +{ + DMFixedPoint a, b; + JSS_LOCK(mixer); + FP_SETHL(mixer->channels[channel].chPanning, start, 0); + FP_SETHL(a, (end - start), 0); + FP_CONV(b, mixer->cbFreq); + FP_DIV_R(mixer->channels[channel].chDeltaP, a, b); JSS_UNLOCK(mixer); } @@ -604,7 +637,7 @@ int tmp; JSS_LOCK(mixer); - tmp = mixer->channels[channel].chPanning; + tmp = FP_GETH(mixer->channels[channel].chPanning); JSS_UNLOCK(mixer); return tmp;
--- a/jssmix.h Fri Oct 05 00:36:40 2012 +0300 +++ b/jssmix.h Fri Oct 05 02:47:36 2012 +0300 @@ -25,7 +25,11 @@ { DMFixedPoint chPos, // Current position in sample, 32:32 fixpoint - chDeltaO; // Delta in 32:32 UNSIGNED! (chDirection) + chDeltaO, // Delta in 32:32 UNSIGNED! (chDirection) + chVolume, // Volume + chDeltaV, + chPanning, // Panning + chDeltaP; int chFreq; // Frequency of sampel in Hz Sint32 @@ -40,8 +44,6 @@ chDirection; // TRUE = playing forwards, FALSE = backwards int chFlags; // Flags - int chVolume, // Volume - chPanning; // Panning JMIXER_ADDBUF_TYPE chPrevR[5], chPrevL[5]; } JSSChannel; @@ -131,12 +133,16 @@ void jvmSetFreq(JSSMixer *mixer, const int channel, const int freq); int jvmGetFreq(JSSMixer *mixer, const int channel); + void jvmSetVolume(JSSMixer *mixer, const int channel, const int volume); +void jvmSetVolumeRamp(JSSMixer * mixer, const int channel, const int start, const int end); int jvmGetVolume(JSSMixer *mixer, const int channel); + void jvmSetPos(JSSMixer *mixer, const int channel, const Sint32 pos); Sint32 jvmGetPos(JSSMixer *mixer, const int channel); void jvmSetPan(JSSMixer *mixer, const int channel, const int panning); +void jvmSetPanRamp(JSSMixer * mixer, const int channel, const int start, const int end); int jvmGetPan(JSSMixer *mixer, const int channel); void jvmMute(JSSMixer *mixer, const int channel, const BOOL mute);