Commit 539556cf authored by Hanspeter Portner's avatar Hanspeter Portner

extend cps2midi and midi2cps.

* base: MIDI note
* noct: number of notes per octave
* fref: reference frequence
parent a41aa403
......@@ -208,8 +208,11 @@ static int
_lmidi2cps(lua_State *L)
{
const lua_Number note = luaL_checknumber(L, 1);
const lua_Number base = luaL_optnumber(L, 2, 69.0);
const lua_Number noct = luaL_optnumber(L, 3, 12.0);
const lua_Number fref = luaL_optnumber(L, 4, 440.0);
const lua_Number cps = exp2( (note - 69.0) / 12.0) * 440.0;
const lua_Number cps = exp2( (note - base) / noct) * fref;
lua_pushnumber(L, cps);
return 1;
......@@ -219,8 +222,11 @@ static int
_lcps2midi(lua_State *L)
{
const lua_Number cps = luaL_checknumber(L, 1);
const lua_Number base = luaL_optnumber(L, 2, 69.0);
const lua_Number noct = luaL_optnumber(L, 3, 12.0);
const lua_Number fref = luaL_optnumber(L, 4, 440.0);
const lua_Number note = log2(cps / 440.0) * 12.0 + 69.0;
const lua_Number note = log2(cps / fref) * noct + base;
lua_pushnumber(L, note);
return 1;
......
......@@ -1589,9 +1589,19 @@ do
end
assert(69.0 == cps2midi(440.0))
assert(440.0 == midi2cps(69.0))
local base = 60.0
local noct = 32.0
local fref = 400.0
for note = 0.0, 127.0, 0.1 do
local cps = midi2cps(note, base, noct, fref)
assert(note - cps2midi(cps, base, noct, fref) < 1e-4)
end
assert(60.0 == cps2midi(400.0, base, noct, fref))
assert(400.0 == midi2cps(60.0, base, noct, fref))
end
-- midi2cps/cps2midi
-- HashMap
print('[test] HashMap')
do
local prefix = 'http://open-music-kontrollers.ch/lv2/synthpod#'
......
......@@ -2868,6 +2868,22 @@ end</code></pre>
<dd>time position property value</dd>
</dl>
<dl>
<dt class="func">timeR:stash(forge)</dt>
<dt>forge (forge)</dt>
<dd>forge object to stash responder state to</dd>
<dt class="ret">(forge)</dt>
<dd>self forge object</dd>
</dl>
<dl>
<dt class="func">timeR:apply(atom)</dt>
<dt>atom (atom)</dt>
<dd>atom object to apply responder state from</dd>
<dt class="ret">(boolean)</dt>
<dd>flag whether state has been applied successfully</dd>
</dl>
<a class="api-snippet" href="#snippet-responder-time" data-snippet="snippet-responder-time">&rArr; show snippet</a>
<pre class="api-hidden"><code id="snippet-responder-time">-- TimeResponder
......@@ -2885,10 +2901,12 @@ local timeR = TimeResponder({
end,
-- listen for barBeat change
[Time.barBeat] = function(self, frames, forge, barBeat)
assert(barBeat == 0.0)
if forge then -- forge==nil in timeR:apply()
assert(barBeat == 0.0)
-- send NoteOn message at each beat
forge:time(frames):midi(MIDI.NoteOn, 69, 0x7f)
-- send NoteOn message at each beat
forge:time(frames):midi(MIDI.NoteOn, 69, 0x7f)
end
end,
-- listen for beatUnit change
[Time.beatUnit] = function(self, frames, forge, beatUnit)
......@@ -2923,6 +2941,17 @@ assert(timeR[Time.beatsPerMinute] == 120.0)
assert(timeR[Time.frame] == 0)
assert(timeR[Time.framesPerSecond] == 48000.0)
-- push current responder state to temporary stash
function stash(forge)
timeR:stash(forge)
end
-- pop and apply current responder state from temporary stash
function apply(atom)
local handled = timeR:apply(atom)
assert(handled == true)
end
-- forge test messages
local function produce_seq(forge)
local obj = forge:time(0):object(nil, Time.Position)
......@@ -2963,7 +2992,7 @@ end</code></pre>
<!-- Utilities -->
<div class="api-section"><div class="api-content">
<h1 id="util">Utilities</h1>
<p>...</p>
<p>Various hopefully useful utility functions.</p>
</div></div>
<!-- midi2cps -->
......@@ -2972,9 +3001,15 @@ end</code></pre>
<p>Conversion from MIDI note to Hertz.</p>
<dl>
<dt class="func">midi2cps(note)</dt>
<dt class="func">midi2cps(note, base=69.0, noct=12.0, fref=440.0)</dt>
<dt>note (number)</dt>
<dd>MIDI note, fractions are allowed</dd>
<dt>base (number)</dt>
<dd>MIDI base note corresponding to reference frequency, defaults to 69.0 (A-5)</dd>
<dt>noct (number)</dt>
<dd>number of notes per octave, default to 12.0</dd>
<dt>fref (number)</dt>
<dd>reference frequency corresponding to MIDI base note, defaults to 440.0 Hz (A-5)</dd>
<dt class="ret">(number)</dt>
<dd>corresponding frequency in Hz</dd>
</dl>
......@@ -2982,7 +3017,8 @@ end</code></pre>
<a class="api-snippet" href="#snippet-util-midi2cps" data-snippet="snippet-util-midi2cps">&rArr; show snippet</a>
<pre class="api-hidden"><code id="snippet-util-midi2cps">-- midi2cps
assert(midi2cps(69.0) == 440.0)</code></pre>
assert(midi2cps(69.0) == 440.0) -- relative to 'A-5'==440 Hz
assert(midi2cps(60.0, 60, 12, 400) == 400.0) -- relative to 'C-5'==400 Hz</code></pre>
</div></div>
<!-- cps2midi -->
......@@ -2994,6 +3030,12 @@ assert(midi2cps(69.0) == 440.0)</code></pre>
<dt class="func">cps2midi(cps)</dt>
<dt>cps (number)</dt>
<dd>frequency in Hz</dd>
<dt>base (number)</dt>
<dd>MIDI base note corresponding to reference frequency, defaults to 69.0 (A-5)</dd>
<dt>noct (number)</dt>
<dd>number of notes per octave, default to 12.0</dd>
<dt>fref (number)</dt>
<dd>reference frequency corresponding to MIDI base note, defaults to 440.0 Hz (A-5)</dd>
<dt class="ret">(number)</dt>
<dd>corresponding MIDI note</dd>
</dl>
......@@ -3001,7 +3043,8 @@ assert(midi2cps(69.0) == 440.0)</code></pre>
<a class="api-snippet" href="#snippet-util-cps2midi" data-snippet="snippet-util-cps2midi">&rArr; show snippet</a>
<pre class="api-hidden"><code id="snippet-util-cps2midi">-- cps2midi
assert(cps2midi(440.0) == 69.0)</code></pre>
assert(cps2midi(440.0) == 69.0) -- relative to 'A-5'==400 Hz
assert(cps2midi(400.0, 60, 12, 400) == 60.0) -- relative to 'C-5'==400 Hz</code></pre>
</div></div>
<!-- encrypt -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment