One shot perpetual loop - how?

I’d like to have a sample trigger and then loop essentially forever without having a trigger lasting forever. Basically a one shot perpetual loop. I can’t figure eiut a way to do it on Halion 7. Is it possible?

I don’t think it’s possible unless you find a way to filter-out the Note-Off midi message (as far as I know you cannot do that in Halion, only in your DAW). It might be possible to accomplish the Note-off filtering by using some script in Halion, although I’m not sure.
However, if the loop is playing “forever”, how are you going to stop it eventually?

You can filter out note off messages by using a script and an empty onRelease callback.

function onRelease(e)
	-- Do nothing
end

But you will get hanging notes so it’s probably a good idea to stop the notes somehow.

There are several things you could try. Maybe something like a latch mode. One note starts the playback, next one stops the playback.
(The actual pitch doesn’t matter in the following example)

function onNote(e)
	if ids then
		releaseVoice(ids)
		ids = nil
	else
		ids = postEvent(e)
	end
end

function onRelease(e)
	-- Do nothing
end

Or you can make it specific to pitch. Play a note to start playback then play the same note again to stop playback. This lets you have more notes play at the same time.

local ids = {}

function onNote(e)
	if ids[e.note] then
		releaseVoice(ids[e.note])
		ids[e.note] = nil
	else
		ids[e.note] = playNote(e.note, e.velocity, 0)
	end
end

function onRelease(e)
	-- Do nothing
end

You could also try other things like using a midi cc to stop the the playback instead of pressing a note. But in all cases you filter out the note off with onRelease. Using postEvent or playNote with duration of 0 should work the same way in this case.

1 Like

This is interesting! I just remember a situation where your script would be very useful, but I’d need a modified version of it. Would it be possible to specify a particular note (let’s say C#1) to stop another particular note (let’s say G3) but without C#1 actually playing a note? In other words, the only purpose for de C#1 is to stop the G3.

You could do that either by creating and posting a note off event or keeping track of note ids.

keyProperties = getKeyProperties()

keyProperties[37] = {color = 10,	tooltip = "Stop G3"}

function onNote(e)
	if e.note == 37 then
		local noteOff = Event(EventType.noteOff)
		noteOff.note = 67
		noteOff.velocity = 100
		postEvent(noteOff)
	else
		postEvent(e)
	end
end
keyProperties = getKeyProperties()

keyProperties[37] = {color = 10,	tooltip = "Stop G3"}

ids = {}

function onNote(e)
	if e.note == 37 then
		while ids[1] do
			local id = table.remove(ids)
			releaseVoice(id)
		end
	elseif e.note == 67 then
		local id = playNote(e.note, e.velocity)
		table.insert(ids, id)
	else
		postEvent(e)
	end
end
1 Like

Great! Thank you very much, @misohoza ! :hugs:

With the transport. I just don’t want it to have a fixed length based on the note triggering.

Wow, that’s amazing, thank you. I’ve never tried scripting but I’m definitely going to give it a try now.