21#define setupAmplitudeVector(i) { \
22 amplitude += amplitudeIncrement; \
23 amplitudeVector = vsetq_lane_s32(amplitude >> 1, amplitudeVector, i); \
27#define RENDER_OSC_SYNC(storageFunctionName, valueFunctionName, extraInstructionsForCrossoverSampleRedo, startRenderingASyncLabel) \
29 bool renderedASyncFromItsStartYet = false; \
30 int32_t crossoverSampleBeforeSync; \
31 int32_t fadeBetweenSyncs; \
35 uint32_t samplesIncludingNextCrossoverSample = 1; \
36startRenderingASyncLabel: \
37 uint32_t distanceTilNextCrossoverSample = -resetterPhase - (resetterPhaseIncrement >> 1); \
38 samplesIncludingNextCrossoverSample += (uint32_t)(distanceTilNextCrossoverSample - 1) / resetterPhaseIncrement; \
39 bool shouldBeginNextSyncAfter = (numSamplesThisOscSyncSession >= samplesIncludingNextCrossoverSample); \
40 int numSamplesThisSyncRender = shouldBeginNextSyncAfter ? samplesIncludingNextCrossoverSample : numSamplesThisOscSyncSession; \
42 int32_t const* const bufferEndThisSyncRender = bufferStartThisSync + numSamplesThisSyncRender; \
43 uint32_t phaseTemp = phase; \
44 int32_t* __restrict__ writePos = bufferStartThisSync; \
46 storageFunctionName(valueFunctionName); \
49 if (renderedASyncFromItsStartYet) { \
50 int32_t average = (*bufferStartThisSync >> 1) + (crossoverSampleBeforeSync >> 1); \
51 int32_t halfDifference = (*bufferStartThisSync >> 1) - (crossoverSampleBeforeSync >> 1); \
52 int32_t sineValue = getSine(fadeBetweenSyncs >> 1); \
53 *bufferStartThisSync = average + (multiply_32x32_rshift32(halfDifference, sineValue) << 1); \
56 if (shouldBeginNextSyncAfter) { \
58 bufferStartThisSync += samplesIncludingNextCrossoverSample - 1; \
59 crossoverSampleBeforeSync = *bufferStartThisSync; \
60 numSamplesThisOscSyncSession -= samplesIncludingNextCrossoverSample - 1; \
61 extraInstructionsForCrossoverSampleRedo; \
63 resetterPhase += resetterPhaseIncrement * (samplesIncludingNextCrossoverSample - renderedASyncFromItsStartYet); \
66 fadeBetweenSyncs = multiply_32x32_rshift32((int32_t)resetterPhase, resetterDivideByPhaseIncrement) \
68 phase = multiply_32x32_rshift32(fadeBetweenSyncs, phaseIncrement) + retriggerPhase; \
70 phase -= phaseIncrement; \
71 renderedASyncFromItsStartYet = true; \
72 samplesIncludingNextCrossoverSample = 2; \
73 goto startRenderingASyncLabel; \
77 phase += phaseIncrement * numSamplesThisSyncRender;
81#define RENDER_WAVETABLE_LOOP(dontCare) { \
82 doRenderingLoop (bufferStartThisSync, bufferEndThisSyncRender, firstCycleNumber, bandHere, phaseTemp, phaseIncrement, crossCycleStrength2, crossCycleStrength2Increment, kernel); \
85#define RENDER_SINGLE_CYCLE_WAVEFORM_LOOP(dontCare) { \
86 doRenderingLoopSingleCycle (bufferStartThisSync, bufferEndThisSyncRender, bandHere, phaseTemp, phaseIncrement, kernel); \
89#define WAVETABLE_EXTRA_INSTRUCTIONS_FOR_CROSSOVER_SAMPLE_REDO { \
90 crossCycleStrength2 += crossCycleStrength2Increment * (samplesIncludingNextCrossoverSample - 1); \
94#define STORE_VECTOR_WAVE_FOR_ONE_SYNC(vectorValueFunctionName) { \
96 int32x4_t valueVector; \
97 vectorValueFunctionName(); \
98 vst1q_s32(writePos, valueVector); \
100 } while (writePos < bufferEndThisSyncRender); \
103#define SETUP_FOR_APPLYING_AMPLITUDE_WITH_VECTORS() \
104 int32x4_t amplitudeVector; \
105 setupAmplitudeVector(0) \
106 setupAmplitudeVector(1) \
107 setupAmplitudeVector(2) \
108 setupAmplitudeVector(3) \
109 int32x4_t amplitudeIncrementVector = vdupq_n_s32(amplitudeIncrement << 1);
116#define CREATE_WAVE_RENDER_FUNCTION_INSTANCE(thisFunctionInstanceName, vectorValueFunctionName) \
118__attribute__((optimize("unroll-loops"))) \
119void thisFunctionInstanceName(const int16_t* __restrict__ table, int tableSizeMagnitude, int32_t amplitude, int32_t* __restrict__ outputBuffer, int32_t* bufferEnd, \
120 uint32_t phaseIncrement, uint32_t phase, bool applyAmplitude, uint32_t phaseToAdd, int32_t amplitudeIncrement) { \
122 int16x4_t const32767 = vdup_n_s16(32767); \
123 int32_t* __restrict__ outputBufferPos = outputBuffer; \
124 SETUP_FOR_APPLYING_AMPLITUDE_WITH_VECTORS(); \
125 uint32_t phaseTemp = phase; \
128 int32x4_t valueVector; \
130 vectorValueFunctionName(); \
132 if (applyAmplitude) { \
133 int32x4_t existingDataInBuffer = vld1q_s32(outputBufferPos); \
134 valueVector = vqdmulhq_s32(amplitudeVector, valueVector); \
135 amplitudeVector = vaddq_s32(amplitudeVector, amplitudeIncrementVector); \
136 valueVector = vaddq_s32(valueVector, existingDataInBuffer); \
139 vst1q_s32(outputBufferPos, valueVector); \
141 outputBufferPos += 4; \
143 while (outputBufferPos < bufferEnd); \