10 static constexpr size_t kSineTableSizeMagnitude = 8;
11 static std::array<int16_t, 512> sineWaveDiff;
14 static inline int32_t doFMNew(uint32_t carrierPhase, uint32_t phaseShift) {
17 uint32_t phaseSmall = (carrierPhase >> 8) + phaseShift;
18 int32_t strength2 = phaseSmall & 65535;
20 uint32_t readOffset = (phaseSmall >> (24 - 8 - 1)) & 0b0111111110;
22 uint32_t readValue = *(uint32_t*)&sineWaveDiff[readOffset];
23 int32_t value = readValue << 16;
24 int32_t diff = (int32_t)readValue >> 16;
25 return value + diff * strength2;
29 static inline Argon<int32_t> getSineVector(uint32_t* thisPhase, uint32_t phaseIncrement) {
33 auto phaseVector = Argon<uint32_t>::LoadCopy(thisPhase).MultiplyAdd(uint32x4_t{1, 2, 3, 4}, phaseIncrement);
34 *thisPhase = *thisPhase + phaseIncrement * 4;
36 return render(phaseVector);
40 static inline Argon<int32_t> doFMVector(Argon<uint32_t> phaseVector, Argon<uint32_t> phaseShift) {
41 return render(phaseVector + (phaseShift << 8));
45 static inline Argon<int32_t> render(Argon<uint32_t> phase) {
47 ArgonHalf<int16_t> strength2 = phase.ShiftRightNarrow<32 - 16 - kSineTableSizeMagnitude + 1>()
48 .BitwiseAnd(std::numeric_limits<int16_t>::max())
52 Argon<uint32_t> indices = (phase >> (32 - kSineTableSizeMagnitude)) << 1;
55 auto [sine, diff] = ArgonHalf<int16_t>::LoadGatherInterleaved<2>(sineWaveDiff.data(), indices);
58 return sine.ShiftLeftLong<16>().MultiplyDoubleAddSaturateLong(diff, strength2);