ref: ccfd02dd2dcfa72085c4dc4f29dea58313964b57
dir: /src/mixer/ft2_silence_mix.c/
#include <stdint.h> #include "../ft2_audio.h" // used for the audio channel mixer when voice volume is zero void silenceMixRoutine(voice_t *v, int32_t numSamples) { const uint64_t samplesToMix = (uint64_t)v->delta * (uint32_t)numSamples; // fixed-point const uint32_t samples = (uint32_t)(samplesToMix >> MIXER_FRAC_BITS); const uint64_t samplesFrac = (samplesToMix & MIXER_FRAC_MASK) + v->positionFrac; uint32_t position = v->position + samples + (uint32_t)(samplesFrac >> MIXER_FRAC_BITS); uint64_t positionFrac = samplesFrac & MIXER_FRAC_MASK; if (position < (uint32_t)v->sampleEnd) // we haven't reached the sample's end yet { v->positionFrac = positionFrac; v->position = position; return; } // end of sample (or loop) reached if (v->loopType == LOOP_DISABLED) { v->active = false; // shut down voice return; } if (v->loopType == LOOP_FORWARD) { if (v->loopLength >= 2) position = v->loopStart + ((position - v->sampleEnd) % v->loopLength); else position = v->loopStart; } else // pingpong loop { if (v->loopLength >= 2) { const uint32_t overflow = position - v->sampleEnd; const uint32_t cycles = overflow / v->loopLength; const uint32_t phase = overflow % v->loopLength; position = v->loopStart + phase; v->samplingBackwards ^= !(cycles & 1); } else { position = v->loopStart; } } v->hasLooped = true; v->positionFrac = positionFrac; v->position = position; }