Hmmm chatGPT was not giving anything working untill I input the working python code and gave the formula.
Once at least the note came out I asked to include offset in cents.
Haven’t tested it properly but this is what I got and it seem to work. !!!
Its surprising how confident chatGPT give the wrong answers
But still in the end i got what i wanted.
Pretty cool!
local A4 = 440
local C0 = A4 * 2^(-4.75)
local name = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}
function pitch(freq)
if freq < 27.5 or freq > 4186.01 then
error("Frequency out of range: " .. freq)
end
local h = math.floor(12 * math.log(freq / C0, 2) + 0.5)
local octave = math.floor(h / 12)
local n = h % 12 + 1
local cents_offset = math.floor(1200 * math.log(freq / (C0 * 2^(h/12)), 2) + 0.5)
return name[n] .. octave, cents_offset
end
--usage
local freq = 261.63
local note, offset = pitch(freq)
print(note, offset)
freq = 440
note, offset = pitch(freq)
print(note, offset)
freq = 444
note, offset = pitch(freq)
print(note, offset)
For the Mirage to get sample frequency into the note range we do
--Ensoniq Mirage Sample frequency range
if freq < 5000 or freq > 50000 then
error("Input frequency out of range: " .. freq)
end
-- Divide the input frequency by 256 to get it into the note range
freq = freq / 256
Pretty cool I got all the tools to generate a note with offset so the Mirage can sample ‘perfect’ loops.
This is not tested yet.
function get_pitch_bend_value(cents_offset, bend_range)
-- Calculate the pitch bend units per cent
local pitch_bend_units_per_cent = 8192 / bend_range / 100
-- Calculate the pitch bend value based on the cents offset
local pitch_bend_value = math.floor(cents_offset * pitch_bend_units_per_cent)
-- Convert the pitch bend value to a signed 14-bit integer
pitch_bend_value = pitch_bend_value + 8192
-- Clamp the pitch bend value to the range of 0 to 16383
pitch_bend_value = math.min(16383, math.max(0, pitch_bend_value))
return pitch_bend_value
end
-- Generate pitch bend value for a 100 cent up bend with a pitch bend range of 2 semitones
local pitch_bend_value = get_pitch_bend_value(-100, 200)
print("The pitchbend value " .. pitch_bend_value)
pitchbendUnits = pitch_bend_value - 8192
print(pitchbendAmound)
But all the data can be then used to send a midi note and a bend message to trigger the exact frequency that fits into the Mirage.