VST LUA beta -- midi scripting VST

VST, AU, AAX, CLAP, etc. Plugin Virtual Instruments Discussion
Post Reply New Topic
RELATED
PRODUCTS

Post

Ok about te first script. It works now. But what about the second one. I get nothing. The same with arpeg.lua.

Post

Still running into some troubles. :(

In SX3, I can load it up but I cannot send it any MIDI input. MIDI output seems to work ok. It just doesn't appear in the list of plugins to send MIDI to...

In XT2, sending midi from midieventcb does not seem to work. Easy to test with arpeg (if you release a note while it's playing it won't be turned off) or transpose (no output at all) stock scripts. Dunno if this is vstlua or xt2, as I can't test it in cubase... ;)

Post

A belated congratulations to tzec for creating this. It looks really interesting, and I'm very interested to see how it develops and what people create with it :)

Post

Thanks Ben! Contrast, I'll get on to fixing that -- thanks for the detailed report, should make tracking it down easier.

I'll also try and fix the SDL dll issue so people don't have to restart just to get a plugin working!

Post

Is there any Vstlua coding procedure to avoid "hanging notes", or missed noteoffs? I guess that inputNotesDown and stopAllPlaying can do something about that but I have no idea how to use them?
thanks

Post

Assuming you've not run into some kind of bug or problem, you shouldn't have to do anything unusual, but you need to make sure you are sending note offs when you need to... It's a design issue rather than something specific to VSTlua. Could you describe in more detail what you are trying to do or even post your script? And include which host you are using.

Post

I use energy1.4
this script should split keyboard in two zones on noteon 48. Notes C,C#,D...A#,H played in the left zone are converted to numbers:
0,1,2,3,4,5,6,-5,-4,-3,-2,-1.
Those notes have velocity 0 and should not produce sound. Those notes use abovementioned numbers to transpose notes > 48 for realtime transpose.
I have problems with two bugs:

1)to be able to start I must press noteon 36(or 24 or 12 or 0) first because if I start playing with notes > 48 I get error because addition can not be done with a nil value.

2)If I change transpositions AND keep noteon in zone >48 than i get hanging notes until I press that note again. I can not understand how noteoffs get lost. I monitor all values with vprint and all the noteons and noteoffs are there.

function midiEventCb(midiEvent)
if midiEvent.type==midi.noteOn or midiEvent.type==midi.noteOff then
if midiEvent.byte2 < 48 then
midiEvent.byte3 = 0
remainder = math.fmod (midiEvent.byte2 , 12)
if remainder > 6 then
remainder = remainder - 12
end

vprint(remainder)
vprint(midiEventToString(midiEvent))
else
vprint(midiEventToString(midiEvent))
midiEvent.byte2 = midiEvent.byte2 + remainder

end
sendMidi(midiEvent)

end
end

Post

I would prefer to explain how to fix these things in words, but I think it is too hard to follow if I just type it all out in text like this. So I just did it and put lots of comments in to help explain things.

However, this might have bugs or other problems as I'm currently not able to test it...! The general method should be ok, though...

Code: Select all

-- set remainder to 0 when the script is loaded so that it has a
-- default value, solves problem 1
remainder = 0

-- this table's keys will be the input notes, and the values will
-- be the output notes. if we receive midi note 60 then maybe
-- note_map[60] == 67 if it was transposed up a fifth. this
-- information allows us to send the correct note off even if the
-- transposition amount changes
-- we also check whether a note is being played by looking to see
-- if note_map[60] (or whatever number) is nil or not. because of
-- that, we must be careful to set the appropriate key back to
-- nil when we turn the note off.
note_map = { }

function midiEventCb(midiEvent)
	if midiEvent.type==midi.noteOn then
		if midiEvent.byte2 < 48 then
			remainder = math.fmod(midiEvent.byte2, 12)
			if remainder > 6 then
				remainder = remainder - 12
			end

			-- don't want to send the midi event, see
			-- the end of the script
			midiEvent = nil
		else
			-- first prevent hanging notes if the
			-- pre-transpose note is already
			-- played, we just turn the currently
			-- played note off
			if note_map[midiEvent.byte2] then
				event = noteOff(note_map[midiEvent.byte2])
				event.channel = midiEvent.channel
				event.delta = midiEvent.delta
				sendMidi(event)
				note_map[midiEvent.byte2] = nil
			end

			-- store the new note value so we still know
			-- what it is even if the transpose changes
			new_note = midiEvent.byte2 + remainder
			note_map[midiEvent.byte2] = new_note
			midiEvent.byte2 = new_note
		end
	end

	if midiEvent.type==midi.noteOff then
		if midiEvent.byte2 < 48 then
			-- don't want to send the midi event, see the
			-- end of the script
			midiEvent = nil
		else
			-- retrieve the note value that we stored when
			-- we created the note and use that to detemine
			-- what noteoff to send
			stored_note = note_map[midiEvent.byte2]
			if stored_note then 
				midiEvent.byte2 = stored_note
				note_map[midiEvent.byte2] = nil
			end
		end
	end

	-- i also moved sendMidi(midiEvent) to this spot, so that CCs,
	-- pitchbend, and so on will still be passed on. only if
	-- you set midiEvent to nil will it not be sent
	if midiEvent then
		sendMidi(midiEvent)
	end
end

Post

thanks contrast!
If I start playing notes > 48 it' ok but if I want to transpose by playing < 48 I get this:
== VstLua 0.06 / tzec 2007 ==--
FATAL ERROR: Error in MIDI callback: ...:\Program Files\vst\vstlua-0.06\scripts\contrast.lua:48: attempt to index local 'midiEvent' (a nil value)

Line 48 is

if midiEvent.type==midi.noteOff then

Post

Erm, right. Sorry about that. Easy to fix though.

Change these lines:

Code: Select all

   end

   if midiEvent.type==midi.noteOff then 
to this:

Code: Select all

   elseif midiEvent.type==midi.noteOff then
Just remove the "end" and change the if to elseif like that and that should take care of it.

Post

thanks!
I experimented today too. This code does the trick too. It is based on your code but without elseif, stored_note and without event.channel and event.delta.
why do you use event.channel and event.delta anyway?

remainder = 0
note_map = { }

function midiEventCb(midiEvent)
if midiEvent.type==midi.noteOn or midi.noteOff then
if midiEvent.byte2 < 48 then
remainder = math.fmod(midiEvent.byte2, 12)
if remainder > 6 then
remainder = remainder - 12
end
midiEvent.byte3 = 0
else

if note_map[midiEvent.byte2] then
event = noteOff(note_map[midiEvent.byte2])
sendMidi(event)
note_map[midiEvent.byte2] = nil
end

new_note = midiEvent.byte2 + remainder
note_map[midiEvent.byte2] = new_note
midiEvent.byte2 = new_note
end
end

if midiEvent then
sendMidi(midiEvent)
end
end

Post

maki wrote:thanks!
I experimented today too. This code does the trick too. It is based on your code but without elseif, stored_note and without event.channel and event.delta.
why do you use event.channel and event.delta anyway?
No problem. The event.delta bit just sets the noteoff event that is created to occur at the same place in the buffer where the noteon was received. If you omit it probably the noteoff event will occur some number of samples early, how much depends on the host and usually the audio buffer size, as well as where the event happens to fall in the buffer.

The channel stuff just sets the new noteoff event to the same midi channel on which the incoming event was received, which is generally what you want, but it's not really important in this case because the rest of the script doesn't account for channels. It makes no difference if you only use one channel and if you want to use multiple channels you need further modifications anyway.

Post

Code: Select all

--Now I want to make a table
table1 = {}

--where noteons in my lowest octave 
function midiEventCb(midiEvent)     
   if midiEvent.type==midi.noteOn then 
     if midiEvent.byte2 < 48 then

--can be inserted while I play them.Every noteon value should be ----located on position 1-12.That depends on distance from C. 
table.insert(table1,(1 + math.fmod(midiEvent.byte2, 12)), midiEvent.byte2)
     end

--than I would like to monitor those values by printing table ------content every time a new noteon inserts
for i,v in ipairs(table1) do vprint(i,v) end
	   vprint("\n")

--while I release notes, noteoff values should destroy previously --located   noteon values from their locations. 
    elseif midiEvent.type==midi.noteOff then  
    table.remove(table1,(1 + math.fmod(midiEvent.byte2, 12)),nil)

--than I would like to monitor those values by printing table ------content every 
--time a new noteon deletes from the table1
      for i,v in ipairs(table1) do vprint(i,v) end
	   vprint("\n")
           end
--other midi events should be sent to midiout unchanged
if midiEvent then 
      sendMidi(midiEvent) 
   end  
end

--but problem is that this code does not work at all. Help!

Post

The page is down... :(

Post

Back up again :)

Post Reply

Return to “Instruments”