Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
sine_osc.h
1#pragma once
2
3#include "deluge/util/misc.h"
4#include <argon.hpp>
5#include <array>
6#include <cstdint>
7
8namespace deluge::dsp {
9class [[gnu::hot]] SineOsc {
10 static constexpr size_t kSineTableSizeMagnitude = 8;
11 static std::array<int16_t, 512> sineWaveDiff;
12
13public:
14 static inline int32_t doFMNew(uint32_t carrierPhase, uint32_t phaseShift) {
15 // return getSineNew((((*carrierPhase += carrierPhaseIncrement) >> 8) + phaseShift) & 16777215, 24);
16
17 uint32_t phaseSmall = (carrierPhase >> 8) + phaseShift;
18 int32_t strength2 = phaseSmall & 65535;
19
20 uint32_t readOffset = (phaseSmall >> (24 - 8 - 1)) & 0b0111111110;
21
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;
26 }
27
28 // Test and verified to be identical to original function 11/22/24
29 static inline Argon<int32_t> getSineVector(uint32_t* thisPhase, uint32_t phaseIncrement) {
30 // create a vector containing a ramp of incrementing phases:
31 // {phase + (phaseIncrement * 1), phase + (phaseIncrement * 2), phase + (phaseIncrement * 3), phase +
32 // (phaseIncrement * 4)}
33 auto phaseVector = Argon<uint32_t>::LoadCopy(thisPhase).MultiplyAdd(uint32x4_t{1, 2, 3, 4}, phaseIncrement);
34 *thisPhase = *thisPhase + phaseIncrement * 4;
35
36 return render(phaseVector);
37 }
38
39 // Test and verified to be identical to original function 11/22/24
40 static inline Argon<int32_t> doFMVector(Argon<uint32_t> phaseVector, Argon<uint32_t> phaseShift) {
41 return render(phaseVector + (phaseShift << 8));
42 }
43
44private:
45 static inline Argon<int32_t> render(Argon<uint32_t> phase) {
46 // interpolation fractional component
47 ArgonHalf<int16_t> strength2 = phase.ShiftRightNarrow<32 - 16 - kSineTableSizeMagnitude + 1>()
48 .BitwiseAnd(std::numeric_limits<int16_t>::max())
49 .As<int16_t>();
50
51 // multiply by 2 due to interleave. i.e. sin(x) is actually table[x * 2]
52 Argon<uint32_t> indices = (phase >> (32 - kSineTableSizeMagnitude)) << 1;
53
54 // load our two relevent table components
55 auto [sine, diff] = ArgonHalf<int16_t>::LoadGatherInterleaved<2>(sineWaveDiff.data(), indices);
56
57 // Essentially a MultiplyAddFixedPoint, but without the reduction back down to q31
58 return sine.ShiftLeftLong<16>().MultiplyDoubleAddSaturateLong(diff, strength2);
59 }
60
61}; // namespace deluge::dsp
62} // namespace deluge::dsp
Definition sine_osc.h:9