-
-
Save aisot/c16e612aad2a15e165eff54cd7e35315 to your computer and use it in GitHub Desktop.
[OSC]MIDI受信ピアノ VCIで使用しているLuaスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- [Piano receiving OSC] | |
-- main.lua MIT License by aisot | |
-- Version 2023.02.20 | |
-- MIDI OSC を受信して vci.message を送信 | |
local Mome = require("metry-osc-midi-emit") | |
local isReceiveEnabled = vci.osc.IsReceiveEnabled() | |
vci.assets.SetText("Text1", | |
"OSC ReceiveEnabled : " .. tostring(isReceiveEnabled)) | |
vci.assets.SetText("Text2", "") | |
-- 複数のMIDI OSC受信アイテムがある場合、Useしたアイテムがvci.messageへの送信を担当する | |
onUse = Mome:addEventStartEmit(onUse) | |
-- 受信したvci.message からMIDIを受信してピアノを動かす | |
local prefix = "pianola_" | |
local KeyItemsObj = {} | |
local KeyItemsRot = {} | |
for key_num = 1, 88 do | |
local item_name = prefix .. key_num | |
local itemObj = vci.assets.GetTransform(item_name) | |
KeyItemsObj[key_num] = itemObj | |
KeyItemsRot[key_num] = itemObj.GetLocalRotation() | |
end | |
-- 鍵盤の色と回転をリセットする onUse時などに呼ばれる | |
function Mome:onOscToVciMsgStart() | |
for key_num = 1, 88 do | |
KeyItemsObj[key_num].SetLocalRotation(KeyItemsRot[key_num]) | |
vci.assets.material.Reset(prefix .. key_num); | |
end | |
end | |
function onMsgMidiNoteOn(sender, name, data) | |
local channel, note_num, velocity = unpack(data) | |
text = "NoteOn:" .. channel .. "," .. note_num .. "," .. velocity | |
vci.assets.SetText("Moniter", text) | |
if note_num < 21 or note_num > 108 then return end | |
if not (channel == 0) then return end | |
local key_num = note_num - 21 + 1 | |
local mat_name = prefix .. key_num | |
local itemObj = KeyItemsObj[key_num] | |
local item_rot = KeyItemsRot[key_num] | |
local rot = Quaternion.AngleAxis(-2, Vector3.left); | |
itemObj.SetLocalRotation(item_rot * rot) | |
local color = Color.__new(1.5, 0.01, 0.01); | |
vci.assets.material.SetColor(mat_name, color) | |
end | |
vci.message.On("/midi/noteon", onMsgMidiNoteOn) | |
function onMsgMidiNoteOff(sender, name, data) | |
local channel, note_num, velocity = unpack(data) | |
text = "NoteOff:" .. channel .. "," .. note_num .. "," .. velocity | |
vci.assets.SetText("Moniter", text) | |
if note_num < 21 or note_num > 108 then return end | |
if not (channel == 0) then return end | |
local key_num = note_num - 21 + 1 | |
local mat_name = prefix .. key_num | |
KeyItemsObj[key_num].SetLocalRotation(KeyItemsRot[key_num]) | |
vci.assets.material.Reset(mat_name); | |
end | |
vci.message.On("/midi/noteoff", onMsgMidiNoteOff) | |
function onMsgMidiControlChange(sender, name, data) | |
local channel, number, value = unpack(data) | |
text = "ControlChange:" .. channel .. "," .. number .. "," .. value | |
vci.assets.SetText("Moniter", text) | |
end | |
vci.message.On("/midi/controlchange", onMsgMidiControlChange) | |
function onMsgMidiPitchbend(sender, name, data) | |
local channel, msb, lsb = unpack(data) | |
local text = "Pitchbend:" .. channel .. "," .. msb .. "," .. lsb | |
vci.assets.SetText("Moniter", text) | |
end | |
vci.message.On("/midi/pitchbend", onMsgMidiPitchbend) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- metry-osc-midi-emit.lua MIT License by aisot | |
-- Version 2023.02.20 | |
-- MIDI OSC を受信して vci.message を送信 | |
local moMidiEmit = {} | |
local MIDI = require("metry-osc-midi") | |
local instanceId = vci.assets.GetInstanceId() | |
local isReceiveEnabled = vci.osc.IsReceiveEnabled() | |
local isMidiMsgEmit = false | |
-- MIDI OSC受信アイテムが複数ある場合、二重送信を防止する(最後に出したアイテムが送信する) | |
function moMidiEmit:onInit(isMidiMsgEmit) end | |
vci.message.On("/oscToMsgStart", function(sender, name, receiveInstantID) | |
isMidiMsgEmit = (instanceId == receiveInstantID) | |
print("MidiMsgEmit : " .. tostring(isMidiMsgEmit)) | |
--vci.assets.SetText("Text2", "MidiMsgEmit : " .. tostring(isMidiMsgEmit)) | |
end) | |
vci.message.Emit("/oscToMsgStart", instanceId) | |
-- イベント関数にoscToVciMsgStartEmitを追加する | |
-- onUse = moMidiEmit:addEventStartEmit(onUse) | |
function moMidiEmit:addEventStartEmit(eventFunction) | |
return function(...) | |
if eventFunction then eventFunction(...) end | |
vci.message.Emit("/oscToMsgStart", instanceId) | |
end | |
end | |
-- OSCから受信したMIDIを自身を含む他のVCIに向けにvci.messageを送信 | |
function MIDI:onNoteOn(...) | |
if vci.assets.IsMine and isMidiMsgEmit then | |
vci.message.Emit("/midi/noteon", {...}) | |
end | |
end | |
function MIDI:onNoteOff(...) | |
if vci.assets.IsMine and isMidiMsgEmit then | |
vci.message.Emit("/midi/noteoff", {...}) | |
end | |
end | |
function MIDI:onControlChange(...) | |
if vci.assets.IsMine and isMidiMsgEmit then | |
vci.message.Emit("/midi/controlchange", {...}) | |
end | |
end | |
function MIDI:onPitchbend(...) | |
if vci.assets.IsMine and isMidiMsgEmit then | |
vci.message.Emit("/midi/pitchbend", {...}) | |
end | |
end | |
function MIDI:onRawMidi(...) | |
if vci.assets.IsMine and isMidiMsgEmit then | |
vci.message.Emit("/midi/rawmidi", {...}) | |
end | |
end | |
return moMidiEmit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- metry-osc-midi.lua MIT License by aisot | |
-- Version 2023.02.19 | |
-- MIDI OSC 受信する | |
local moMidi = {} | |
local isEnabled = vci.osc.IsReceiveEnabled() | |
if (isEnabled == false) then return moMidi end | |
local String = vci.osc.types.String | |
local Int = vci.osc.types.Int32 | |
local Floart = vci.osc.types.Float32 | |
local Blob = vci.osc.types.BlobAsUtf8 | |
local III = {Int, Int, Int} | |
local I = {Int} | |
local nilError = function(s) | |
print(s .. " - Data in OSC is nil.") | |
return -1 | |
end | |
--------------------------------------------------------- | |
-- NoteOn | |
-- /midi/noteon/ INT32 INT32 INT32 | |
--------------------------------------------------------- | |
function moMidi:onNoteOn(channel, pitch, velocity) | |
print("onNoteOn:" .. channel .. "," .. pitch .. "," .. velocity) | |
end | |
local function noteOn(...) | |
if ... == nil then return nilError("noteOn") end | |
moMidi:onNoteOn(...) | |
end | |
vci.osc.RegisterMethod("/midi/noteon/", noteOn, III) | |
vci.osc.RegisterMethod("/midi/noteon", noteOn, III) | |
--------------------------------------------------------- | |
-- NoteOff | |
-- /midi/noteoff/ INT32 INT32 INT32 | |
--------------------------------------------------------- | |
function moMidi:onNoteOff(channel, pitch, velocity) | |
print("onNoteOff:" .. channel .. "," .. pitch .. "," .. velocity) | |
end | |
local function noteOff(...) | |
if ... == nil then return nilError("noteOff") end | |
moMidi:onNoteOff(...) | |
end | |
vci.osc.RegisterMethod("/midi/noteoff/", noteOff, III) | |
vci.osc.RegisterMethod("/midi/noteoff", noteOff, III) | |
--------------------------------------------------------- | |
-- ControlChange | |
-- /midi/controlchange INT32 INT32 INT32 | |
--------------------------------------------------------- | |
function moMidi:onControlChange(channel, number, value) | |
print("moMidi:onControllerChange:" .. channel .. "," .. number .. "," .. | |
value) | |
end | |
local function ControlChange(...) | |
if ... == nil then return nilError("controllerChange") end | |
moMidi:onControlChange(...) | |
end | |
vci.osc.RegisterMethod("/midi/controlchange", ControlChange, III) | |
--------------------------------------------------------- | |
-- Pitchbend - ch msb lsb | |
-- /midi/pitchbend INT32 INT32 INT32 | |
-------------------------------------------------------- | |
function moMidi:onPitchbend(channel, msb, lsb) | |
print("moMidi:onPitchbend:" .. channel .. "," .. msb .. "," .. lsb) | |
end | |
local function pitchbend(...) | |
if ... == nil then return nilError("pitchbend") end | |
moMidi:onPitchbend(...) | |
end | |
vci.osc.RegisterMethod("/midi/pitchbend", pitchbend, III) | |
--------------------------------------------------------- | |
-- Raw midi | |
-- /rawmidi INT32 INT32 INT32 | |
--------------------------------------------------------- | |
function moMidi:onRawMidi(event, data1, data2) | |
print("moMidi:onRawMidi:" .. event .. "," .. data1 .. "," .. data2) | |
end | |
local function rawMidi(event, data1, data2) | |
if event == nil then return nilError("rawMidi") end | |
-- print("rawMidi:" .. event .. "," .. data1 .. "," .. data2) | |
-- noteOff | |
if event >= 0x80 and event <= 0x8F then | |
local channel, pitch, velocity = event - 0x80, data1, data2 | |
moMidi:onNoteOff(channel, pitch, velocity) | |
-- noteOn | |
elseif event >= 0x90 and event <= 0x9F then | |
local channel, pitch, velocity = event - 0x90, data1, data2 | |
moMidi:onNoteOn(channel, pitch, velocity) | |
-- Control Change | |
elseif event >= 0xB0 and event <= 0xBF then | |
local channel, msb, lsb = event - 0xB0, data1, data2 | |
moMidi:onControlChange(channel, msb, lsb); | |
-- Pitch Wheel | |
elseif event >= 0xE0 and event <= 0xEF then | |
local channel, msb, lsb = event - 0xE0, data1, data2 | |
moMidi:onPitchbend(channel, msb, lsb) | |
else | |
moMidi:onRawMidi(event, data1, data2) | |
end | |
end | |
vci.osc.RegisterMethod("/rawmidi", rawMidi, III) | |
--------------------------------------------------------- | |
-- OSC/PAR(https://oscpilot.com/pages/osc-par) | |
-- /TrackName/note_[1-127] INT32 | |
-- /midi/[1-16]/note_[1-127] INT32 | |
--------------------------------------------------------- | |
for pitch = 0, 127 do | |
for channel = 0, 15 do | |
local func = function(velocity) | |
if velocity == 0 then | |
moMidi:onNoteOff(channel, pitch, velocity) | |
else | |
moMidi:onNoteOn(channel, pitch, velocity) | |
end | |
end | |
if channel == 0 then | |
-- default TrackName OSC address | |
vci.osc.RegisterMethod("/TrackName/note_" .. pitch, func, I) | |
end | |
local chName = channel + 1 | |
vci.osc.RegisterMethod("/midi/" .. chName .. "/note_" .. pitch, func, I) | |
end | |
end | |
return moMidi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment