Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

host-synchronized midicontrolled gate + midi MTC commands #7

Closed
coderofsalvation opened this issue May 20, 2015 · 4 comments
Closed

Comments

@coderofsalvation
Copy link

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):

  • receive midi-in messages
  • delay these midi-in messages a variable amount of ms
  • send them to midi-out

and, at the same :

  • receive start- and stop- events from pluginhost (JACK transport?)
  • and send as MMC midi start- and stop- bytes to midi-out

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
Copy link
Contributor

Towards your first question, the general strategy would be:

  • get the sample rate
  • calculate your delay length in terms of samples and numbers of buffer periods
  • read the midi events and store them together with a timestamp (e.g. samples since startup)
  • in each period, check if the delay number of buffer periods and samples has passed, comparing the stored timestamps to the current number of periods/samples since startup, and, if yes
  • add the stored midi events to the output buffer

@coderofsalvation
Copy link
Author

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
Copy link
Owner

pac-dev commented May 20, 2015

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
Copy link
Author

indeed nothing wrong with those docs!
thnx

@pac-dev pac-dev closed this as completed Jun 5, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants