|
|
|
05-25-2017, 08:33 AM
|
#1
|
Human being with feelings
Join Date: Dec 2014
Posts: 597
|
Set item events to a specific chan
Hi everyone,
I'm trying to find a solution to the strange behaviour I get and explained here : http://forum.cockos.com/showthread.php?t=187524 and here : http://forum.cockos.com/showthread.php?t=188474
And I wonder if there is a way to assign specific channel for midi events in an item WITHOUT using MIDI Editor.
I mean, I select a midi item in the arrange view and call a custom action/script that automatically sets all events in this item to chan 16.
thanks for your suggestions
|
|
|
05-25-2017, 12:21 PM
|
#2
|
Human being with feelings
Join Date: Nov 2007
Location: Lucas, TX, USA (via Luleå, Sweden)
Posts: 2,008
|
I'm not sure I understand the context of your question.
I don't think there is a native command to do this, but it is certainly something that could be done with reascript.
I have several eel and lua programs where I select a MIDI item in the arrange view, and the program does things to the events in the item (such as changing the channel) without the user having to open a MIDI editor.
So yes, definitely possible. I couldn't tell from the threads you referenced whether you have tried writing one, and couldn't get it to work, or whether you are asking if it's possible so that you know whether to try writing one.
__________________
Best Regards, Ernie "lunker" Lundqvist
BDSM (Bad Dog Studio Musicians)
Windows 10 running on Z390 + i7-8700
Last edited by lunker; 05-25-2017 at 12:29 PM.
|
|
|
05-25-2017, 01:01 PM
|
#3
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Sorry, for crossing by, but...
Quote:
Originally Posted by lunker
I have several eel and lua programs where I select a MIDI item in the arrange view, and the program does things to the events in the item (such as changing the channel) without the user having to open a MIDI editor.
|
that's exctly what I'm also looking for currently (setting all events of selected MIDI items to a specific channel. Not having to use the MIDI editor for it would even be better).
http://forum.cockos.com/showthread.php?t=192250
http://forum.cockos.com/showthread.php?t=192213
Would you mind sharing this script ?
|
|
|
05-25-2017, 01:13 PM
|
#4
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
first try with lua
native API looks buggy
Code:
channel = 16
function SetEventsChannelForSelectedItem()
local item = reaper.GetSelectedMediaItem(0,0)
if not item then return end
local take = reaper.GetActiveTake(item)
if not take or not reaper.TakeIsMIDI(take) then return end
local _, notecntOut, ccevtcntOut = reaper.MIDI_CountEvts( take )
for i = 1, math.max(notecntOut, ccevtcntOut) do
if reaper.MIDI_GetCC( take, i-1 ) then reaper.MIDI_SetCC( take, i-1, nil, nil, nil, nil, channel-1, nil, nil, true ) end
if reaper.MIDI_GetNote( take, i-1 ) then reaper.MIDI_SetNote( take, i-1, nil, nil, nil, nil, channel-1, nil, nil, true ) end
end
reaper.MIDI_Sort( take )
end
SetEventsChannelForSelectedItem()
EDIT: SWS/FNG (note only) also buggy
Code:
channel = 16
function SetEventsChannelForSelectedItem_FNG_mod()
local item = reaper.GetSelectedMediaItem(0,0)
if not item then return end
local take = reaper.GetActiveTake(item)
if not take or not reaper.TakeIsMIDI(take) then return end
local fng_tk = reaper.FNG_AllocMidiTake( take )
for i = 1, reaper.FNG_CountMidiNotes( fng_tk ) -1 do
local fng_note = reaper.FNG_GetMidiNote( fng_tk, i-1 )
if fng_note then reaper.FNG_SetMidiNoteIntProperty( fng_note, 'CHANNEL', channel ) end
end
reaper.FNG_FreeMidiTake( fng_tk )
end
SetEventsChannelForSelectedItem_FNG_mod()
Last edited by mpl; 05-25-2017 at 01:31 PM.
|
|
|
05-25-2017, 01:25 PM
|
#5
|
Human being with feelings
Join Date: Nov 2007
Location: Lucas, TX, USA (via Luleå, Sweden)
Posts: 2,008
|
EDIT: ACK!! I was too slow!
I certainly don't mind. I posted one here a while ago: http://forum.cockos.com/showpost.php...01&postcount=5
If you try to run it, make sure you grab the library file that I included a few posts later. If you just want to look at the code, don't bother with the library file. It's just a function that gaussian randomizer function.
That program does a lot of other stuff, which obscures the task you are trying to perform. After sifting through this program, I think the basic structure you want would be something like this:
Code:
// eel code (lua would be similar)
// get the current take of the selected item
Item = GetSelectedMediaItem (0, 0);
Take = GetMediaItemInfo_Value (Item, "I_CURTAKE");
// get the number of events
MIDI_CountEvts (Take, Count.Note, Count.Cc, Count.TextSysex);
// loop through all the CC events, and reset the channel
Cc.Index = 0;
while (Cc.Index < Count.Cc) (
MIDI_GetCC (
Take
, Cc.Index
, Cc.IsSelected
, Cc.IsMuted
, Cc.Pos
, Cc.Msg1
, Cc.Channel
, Cc.Msg2
, Cc.Msg3
);
MIDI_SetCC (
Take
, Cc.Index
, Cc.IsSelected
, Cc.IsMuted
, Cc.Pos
, Cc.Msg1
, 15 // 0 = channel 1, 15 = channel 16
, Cc.Msg2
, Cc.Msg3
);
Cc.Index += 1;
);
I can't guarantee that the code above is correct, because I cut it from different parts of the program, and had to modify some terms when I pasted it in here. But that should be the basic structure you want. Now that I've learned lua, I can certainly say that I prefer it over eel. But it seems that I don't actually have a lua program that does this type of thing yet. But the lua structure would be identical. The only difference would be the syntax of some commands (and of course the fact that I liked to use periods in my eel variable names, which doesn't work in lua).
__________________
Best Regards, Ernie "lunker" Lundqvist
BDSM (Bad Dog Studio Musicians)
Windows 10 running on Z390 + i7-8700
Last edited by lunker; 05-25-2017 at 01:33 PM.
|
|
|
05-25-2017, 02:49 PM
|
#6
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Thank you both, this helps a lot.
The surrounding stuff for my needs (work on all selected items, add user prompt for channel) I'm fine adding myself.
mpl, of course I'll also test myself soon but what do you mean with 'buggy' ?
Did you find the used API functions not working correctly already ?
Last edited by nofish; 05-25-2017 at 02:56 PM.
|
|
|
05-25-2017, 02:54 PM
|
#7
|
Human being with feelings
Join Date: Dec 2014
Posts: 597
|
Thanks mpl, your lua script seems to work for me ! :-D
[OutOfTopic] And I love your music, just listened your soundcloud [/OutOfTopic]
|
|
|
05-25-2017, 08:52 PM
|
#8
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
Yes, nofish, they aren't applying properly (changed length, need to run twice or more to get all notes looped).
|
|
|
05-26-2017, 04:09 AM
|
#9
|
Human being with feelings
Join Date: Jul 2009
Posts: 3,714
|
If the scripts above are not applying properly, you can also try the following:
(It should change the channels of all CCs as well as notes and notation events.)
Code:
-- Change the channel of all notes and CCs in all selected items to specified channel
newChannel = 15 -- Channel to which events should be changed (0-15, NOT 1-16).
---------------
notationReplacementText = string.format("NOTE %i ", newChannel) -- Will be used to replace channel info in REAPER's notation events
-- First, loop through all selected items
for i = 0, reaper.CountSelectedMediaItems(0)-1 do
item = reaper.GetSelectedMediaItem(0, i)
-- Loop through all takes within each selected item
for t = 0, reaper.CountTakes(item)-1 do
take = reaper.GetTake(item, t)
if reaper.TakeIsMIDI(take) then
-- Use the new Get/SetAllEvts functions to directly (and quickly) edit the MIDI data
local gotAllOK, MIDIstring = reaper.MIDI_GetAllEvts(take, "")
if gotAllOK then
local tableEvents = {} -- MIDI events will temporarily be stored in this table until they are concatenated into a string again
local t = 1 -- Index inside tableEvents
local MIDIlen = MIDIstring:len()
local positionInString = 1 -- Position inside MIDIstring while parsing
local offset, flags, msg
-- Now parse through all events in the MIDI string, one-by-one
-- (Excluding the final 12 bytes, which provides REAPER's All-notes-off end-of-take message)
while positionInString < MIDIlen-12 do
offset, flags, msg, positionInString = string.unpack("i4Bs4", MIDIstring, positionInString)
local msg1 = msg:byte(1) -- The first byte contains the event type and channel
if msg1 then -- If empty event that simply changes PPQ position, msg1 will be nil
if msg1>>4 ~= 0xF then -- First nybble gives event type; exclude text/sysex messages, which do not carry channel info
msg = string.char(((msg1 & 0xF0) | newChannel)) .. msg:sub(2) -- 2nd nybble gives channel
elseif msg1 == 0xFF then -- REAPER's notation events also refer to the note channel
msg = msg:gsub("NOTE %d+ ", notationReplacementText, 1)
end
end
tableEvents[t] = string.pack("i4Bs4", offset, flags, msg)
t = t + 1
end
-- This script does not change the order of events, so no need to call MIDI_Sort after updating take's MIDI
reaper.MIDI_SetAllEvts(take, table.concat(tableEvents) .. MIDIstring:sub(-12))
end -- if gotAllOK
end -- if reaper.TakeIsMIDI(take)
end
end
reaper.Undo_OnStateChange("Set channel of all MIDI in selected items")
Last edited by juliansader; 05-26-2017 at 03:41 PM.
|
|
|
05-26-2017, 05:37 AM
|
#10
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Thanks Julian.
Actually I played around with using the new Get/SetAllEvts API for this (as I've read it's considerably faster) but couldn't quite wrap my head around it, so this is very welcome.
|
|
|
05-26-2017, 08:43 AM
|
#11
|
Human being with feelings
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
|
whoa I didn`t saw that API, looks interesting, Julian
|
|
|
05-27-2017, 11:24 AM
|
#12
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
I've added a user input prompt to Julian's version and some other small additions (like checking for required Reaper version).
edit:
Available now in my ReaPack repo.
(Julian, if you're not ok with this, just tell me and I'll take it down.)
Last edited by nofish; 05-29-2017 at 11:32 AM.
|
|
|
05-27-2017, 01:55 PM
|
#13
|
Human being with feelings
Join Date: Nov 2015
Location: Germany
Posts: 1,015
|
This is s.th. I really wanted to have since I use REAPER. (Well that's not THAT long, but...)
THANKS!
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 04:35 AM.
|