pac-dev / protoplug

Create audio plugins on-the-fly with LuaJIT.
Other
278 stars 36 forks source link

host-synchronized midicontrolled gate + midi MTC commands #7

Closed coderofsalvation closed 9 years ago

coderofsalvation commented 9 years ago

I want to make the following linux plugin, and I would like to get some guidelines / feedback whether this is possible:

(and if not this'll be the featurerequest):

and, at the same :

so practically I need to send these raw midi-bytes:

 start MMC bytes: 0xF0 0x7F 0x7F 0x06 0x02
 stop  MMC bytes: 0xF0 0x7F 0x7F 0x06 0x01
SpotlightKid commented 9 years ago

Towards your first question, the general strategy would be:

coderofsalvation commented 9 years ago

I think I already got the midimsg delay working (I looked at the midiChordify example):

require "include/protoplug"

local mididelay
local delayBuf = {}
local playing = false

function plugin.processBlock(samples, smax, midiBuf)
  blockEvents = {}
  -- analyse midi buffer and push them to midiDelaybuffer
  for ev in midiBuf:eachEvent() do
    ev.time = ev.time + mididelay
    table.insert( delayBuf, ev )    
  end
  -- fill midi buffer with delayed notes (if any)
  midiBuf:clear()
  sendDelayBuf(midiBuf)
  sendMMC()
end

function sendDelayBuf(midiBuf)
  if #delayBuf>0 then
    for _,e in ipairs(delayBuf) do
      if e.time < smax then       
        midiBuf:addEvent(e)
        table.remove( delayBuf, _ )
        print "midi msg!"
      else
        e.time = e.time - smax
      end
    end
  end
end

function sendMMC()
  if not playing and plugin.PositionInfo.isPlaying
    -- send start to midi out ( 0xF0 0x7F 0x7F 0x06 0x02 )
  end
  if playing and not plugin.PositionInfo.isPlaying
    -- send stop to midi out ( 0xF0 0x7F 0x7F 0x06 0x01 )
  end   
end 

params = plugin.manageParams {
  {
    name = "Mididelay";
    type = "int";
    max = 50000;
    changed = function(val) mididelay = val end;
  }
}

Now I only need to send out the midi bytes by creating some custom midi events. WDYT?

ps. actually its not important to deal with real milliseconds since the only purpose of the slider is to do a manual correction by ear. (compensate hardware/software midi delay)

pac-dev commented 9 years ago

For receiving start and stop events from the host, you can use plugin.getCurrentPosition().isPlaying. Here's an example:

require "include/protoplug"

local oldPlaying = false

function plugin.processBlock(samples, smax, midiBuf)
    local info = plugin.getCurrentPosition()
    if info and info.isPlaying ~= oldPlaying then
        print (info.isPlaying and "Host started playing!" or "Host stopped!")
        oldPlaying = info.isPlaying
    end
end

For sending custom MIDI messages, the API docs are pretty explicit, there's even an example!:

http://www.osar.fr/protoplug/api/modules/midi.html#midi.Event:Event

coderofsalvation commented 9 years ago

indeed nothing wrong with those docs! thnx