19#include "processing/vector_rendering_function.h"
20#include "util/fixedpoint.h"
21#include "util/waves.h"
25[[gnu::always_inline]]
static inline void
26renderOscSync(
auto storageFunction,
auto extraInstructionsForCrossoverSampleRedo,
28 uint32_t& phase, uint32_t phaseIncrement, uint32_t& resetterPhase, uint32_t resetterPhaseIncrement,
29 int32_t resetterDivideByPhaseIncrement, uint32_t retriggerPhase, int32_t& numSamplesThisOscSyncSession,
30 int32_t*& bufferStartThisSync) {
32 bool renderedASyncFromItsStartYet =
false;
33 int32_t crossoverSampleBeforeSync;
34 int32_t fadeBetweenSyncs;
39 uint32_t samplesIncludingNextCrossoverSample = 1;
41 uint32_t distanceTilNextCrossoverSample = -resetterPhase - (resetterPhaseIncrement >> 1);
42 samplesIncludingNextCrossoverSample += (uint32_t)(distanceTilNextCrossoverSample - 1) / resetterPhaseIncrement;
43 bool shouldBeginNextSyncAfter = (numSamplesThisOscSyncSession >= samplesIncludingNextCrossoverSample);
44 size_t numSamplesThisSyncRender = shouldBeginNextSyncAfter
45 ? samplesIncludingNextCrossoverSample
46 : numSamplesThisOscSyncSession;
48 storageFunction(std::span{bufferStartThisSync, numSamplesThisSyncRender}, phase);
51 if (renderedASyncFromItsStartYet) {
52 int32_t average = (*bufferStartThisSync >> 1) + (crossoverSampleBeforeSync >> 1);
53 int32_t halfDifference = (*bufferStartThisSync >> 1) - (crossoverSampleBeforeSync >> 1);
54 int32_t sineValue = getSine(fadeBetweenSyncs >> 1);
55 *bufferStartThisSync = average + (multiply_32x32_rshift32(halfDifference, sineValue) << 1);
58 if (shouldBeginNextSyncAfter) {
61 bufferStartThisSync += samplesIncludingNextCrossoverSample - 1;
62 crossoverSampleBeforeSync = *bufferStartThisSync;
63 numSamplesThisOscSyncSession -= samplesIncludingNextCrossoverSample - 1;
64 extraInstructionsForCrossoverSampleRedo(samplesIncludingNextCrossoverSample);
67 resetterPhase += resetterPhaseIncrement * (samplesIncludingNextCrossoverSample - renderedASyncFromItsStartYet);
71 fadeBetweenSyncs = multiply_32x32_rshift32((int32_t)resetterPhase, resetterDivideByPhaseIncrement)
73 phase = multiply_32x32_rshift32(fadeBetweenSyncs, phaseIncrement) + retriggerPhase;
75 phase -= phaseIncrement;
76 renderedASyncFromItsStartYet =
true;
77 samplesIncludingNextCrossoverSample = 2;
79 goto startRenderingASync;
84 phase += phaseIncrement * numSamplesThisSyncRender;
87auto renderWavetableLoop(
auto bufferStartThisSync,
auto firstCycleNumber,
auto bandHere,
auto phaseIncrement,
88 auto crossCycleStrength2,
auto crossCycleStrength2Increment,
auto kernel) {
89 return [&](int32_t
const*
const bufferEndThisSyncRender, uint32_t phaseTemp, int32_t* __restrict__ writePos) {
90 doRenderingLoop(bufferStartThisSync, bufferEndThisSyncRender, firstCycleNumber, bandHere, phaseTemp,
91 phaseIncrement, crossCycleStrength2, crossCycleStrength2Increment, kernel);
96inline Argon<int32_t> createAmplitudeVector(int32_t amplitude, int32_t amplitude_increment) {
98 auto amplitudeVector = Argon<int32_t>{amplitude}.MultiplyAdd(amplitude_increment, int32x4_t{1, 2, 3, 4});
101 return amplitudeVector >> 1;