From accc98c35771af83fb851341040bd8e159ab8b65 Mon Sep 17 00:00:00 2001 From: Annika Date: Mon, 27 Jul 2026 00:19:06 -0700 Subject: [PATCH] created note LUT for MIDI notes --- oscillator.cpp | 57 ++++++++++++++---------------------------- scripts/midilut-gen.py | 13 ++++++++++ 2 files changed, 32 insertions(+), 38 deletions(-) create mode 100644 scripts/midilut-gen.py diff --git a/oscillator.cpp b/oscillator.cpp index aee436d..2a94581 100644 --- a/oscillator.cpp +++ b/oscillator.cpp @@ -4,25 +4,23 @@ namespace Fem { class Oscillator { private: - // 11.21 fixed point amount to increment per 48kHz clock cycle - // 11.8 used, least significant 13 bits only used for accumulator precision - const uint32_t NOTELUT[16] = { - 749114669, // C9 - 793659848, // C#9 - 840853486, // D9 - 890853486, // D#9 - 943826222, // E9 - 999948917, // F9 - 1059409160, // F#9 - 1122404698, // G9 - 1189146700, // G#9D - 1259857073, // A9 - 1334772041, // A#9 - 1414141247, // B9 - 0, // invalid - 0, // invalid - 0, // invalid - 0 // invalid + const uint32_t NOTELUT[128] = { + 0x000b29a6, 0x000bd392, 0x000c879a, 0x000d4656, 0x000e1069, 0x000ee680, 0x000fc953, 0x0010b9a2, + 0x0011b83c, 0x0012c5f9, 0x0013e3c0, 0x00151285, 0x0016534c, 0x0017a725, 0x00190f34, 0x001a8cac, + 0x001c20d2, 0x001dcd01, 0x001f92a6, 0x00217345, 0x00237078, 0x00258bf2, 0x0027c780, 0x002a250b, + 0x002ca698, 0x002f4e4b, 0x00321e68, 0x00351958, 0x003841a5, 0x003b9a03, 0x003f254d, 0x0042e68a, + 0x0046e0f0, 0x004b17e4, 0x004f8f01, 0x00544a17, 0x00594d30, 0x005e9c96, 0x00643cd1, 0x006a32b0, + 0x0070834b, 0x00773407, 0x007e4a9b, 0x0085cd15, 0x008dc1e0, 0x00962fc9, 0x009f1e02, 0x00a8942e, + 0x00b29a61, 0x00bd392c, 0x00c879a3, 0x00d46561, 0x00e10697, 0x00ee680e, 0x00fc9536, 0x010b9a2a, + 0x011b83c1, 0x012c5f92, 0x013e3c05, 0x0151285c, 0x016534c3, 0x017a7259, 0x0190f346, 0x01a8cac3, + 0x01c20d2e, 0x01dcd01d, 0x01f92a6c, 0x02173455, 0x02370783, 0x0258bf25, 0x027c780b, 0x02a250b9, + 0x02ca6986, 0x02f4e4b3, 0x0321e68d, 0x03519586, 0x03841a5d, 0x03b9a03a, 0x03f254d9, 0x042e68ab, + 0x046e0f06, 0x04b17e4b, 0x04f8f016, 0x0544a173, 0x0594d30d, 0x05e9c967, 0x0643cd1a, 0x06a32b0c, + 0x070834ba, 0x07734074, 0x07e4a9b2, 0x085cd157, 0x08dc1e0d, 0x0962fc96, 0x09f1e02d, 0x0a8942e6, + 0x0b29a61a, 0x0bd392cf, 0x0c879a35, 0x0d465619, 0x0e106974, 0x0ee680e9, 0x0fc95364, 0x10b9a2ae, + 0x11b83c1a, 0x12c5f92c, 0x13e3c05a, 0x151285cd, 0x16534c34, 0x17a7259f, 0x190f346a, 0x1a8cac33, + 0x1c20d2e8, 0x1dcd01d2, 0x1f92a6c8, 0x2173455d, 0x23707834, 0x258bf258, 0x27c780b4, 0x2a250b9b, + 0x2ca69869, 0x2f4e4b3f, 0x321e68d4, 0x35195867, 0x3841a5d0, 0x3b9a03a5, 0x3f254d90, 0x42e68abb }; // lanczos2 kernel LUT @@ -73,24 +71,6 @@ namespace Fem { return (int16_t)filteredSample; } - uint32_t noteFrequency(uint8_t note) { - // 2048 samples / cycle ~ 48kHz / 20Hz - // uint32_t pitch accumulator coefficient - // top 11-bits = sample # - // bottom 21-bits = subsample resolution - // use a discontinuous "fast" note notation - // oooonnnn - // o = octave (0:15 = -6:9) - // n = note (0:11 = C:B) - - - uint32_t notePitch = NOTELUT[note & 0x0f]; - uint8_t octaveShift = note >> 4; - octaveShift = (0xf - octaveShift) & 0x0f; - notePitch = notePitch >> octaveShift; - return notePitch; - } - // linear interpolation of two samples int16_t lerp(int16_t a, int16_t b, uint16_t t) { int32_t lerpSum = (int32_t)(0x2000 - t) * (int32_t)a; @@ -109,7 +89,8 @@ namespace Fem { } int16_t gen(uint8_t note, uint16_t wavePos, int16_t** waveTable) { - pitchAcc += noteFrequency(note); + // pitchAcc += noteFrequency(note); + pitchAcc += NOTELUT[note]; // interpolate between two waves in the wavetable uint8_t waveIndex = wavePos >> 13; diff --git a/scripts/midilut-gen.py b/scripts/midilut-gen.py new file mode 100644 index 0000000..7459c97 --- /dev/null +++ b/scripts/midilut-gen.py @@ -0,0 +1,13 @@ +# generate a lookup table of all 128 MIDI notes + +import numpy as np + +for j in range(0, 128, 8): + lineString = "" + for k in range(8): + n = j + k + f = 440. * (2. ** ((n - 69.) / 12.)) + y = f * (2. ** 32.) / 48000. + lineString += hex(int(y)) + lineString += ", " + print(lineString) \ No newline at end of file