Old 03-09-2017, 06:47 PM   #1
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default Sexan, Lokasenna, I need your help!

Hello!

I ask for help specifically from Sexan and Lokasenna because of this. But, whoever else could help or has similar code, please help!

I need a function that just stores in the project file (or in another file - maybe safer!) just the chunk that has to do with the items of a specified track. And then another function that reads them from file and restores them.
So, function StoreItems(trackGUID) and function RestoreItems(trackGUID).

Since, you have done it with your TrackList Versions script, could you share with me the code that would do specifically these two things? I don't need any other part of the code. Just the ability to save whatever has to do with the items of a specific track and then to recall it.

Thanks!
amagalma is offline   Reply With Quote
Old 03-09-2017, 08:08 PM   #2
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,430
Default

Storing data in a project

reaper.SetProjExtState( proj, extname, key, value )

proj = 0 will refer to the active project
extname = "Amagalma"
key = "GUID"
value = your GUID

Loading data from a project

retval = reaper.GetProjExtState( proj, extname, key )

(The API shows two return values, I don't know what the second one is for)

Returns the value you saved as a string, or just "" if that key doesn't exist.

----

There are two equivalent functions for storing values globally in one of Reaper's .ini files, i.e. for user settings in a script, etc:

reaper.SetExtState( section, key, value, persist )

section = Same as 'extname' above.
persist = Whether Reaper should store the value permanently or just hold on to it for this session.

Personally I find it easier to work with an external .txt file myself, especially for anything more than one or two lines of data.

Saving data to an external file

Code:
-- Get the script's path, so we can save the data in the same place
local info = debug.getinfo(1,'S');
local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]]

local file_path = script_path .. "amagalma script data.txt"

-- Open the file for writing, and avoid crashing if there's a problem
-- "w+" means "erase whatever's there".
local file, err = io.open(file_name, "w+") or nil
if not file then 
  reaper.ShowMessageBox("Couldn't open the file.\nError: "..tostring(err), "Whoops", 0)
  return 0 
end

-- If your table's indices are contiguous numbers starting from 1, i.e. 123456789, not 123  6 apple 9...
for i = 1, #my_table_of_data do
  file:write(my_table[i] .. "\n")
end

-- Otherwise
for k, v in pairs(my_table_of_data) do
  file:write( tostring(k) .. "=" .. tostring(v) .. "\n" )
end

-- Close the file
io.close(file)
Loading data from an external file

Obviously this will depend on which of the two methods you used to save it.

Code:
-- Get the script's path, so we can save the data in the same place
local info = debug.getinfo(1,'S');
local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]]

local file_path = script_path .. "amagalma script data.txt"

-- Open the file in "read" mode
local file, err = io.open(file_name) or nil
if not file then 
  reaper.ShowMessageBox("Couldn't open the file.\nError: "..tostring(err), "Whoops", 0)
  return 0 
end

-- If your data was indexed with contiguous numbers
for line in file:lines() do
  table.insert(my_table_of_data, line)
end

-- A little more work if you're using string keys or noncontiguous indices
for line in file:lines() do

  -- Break the line back up into a key and value.
  -- The matching pattern here will only work for data stored as:  key=value
  -- I haven't tried it though, not sure if it does work or not.
  local key, val = string.match(line, "(^[^=]*)=([^=]*)$")

  -- Error checking
  if not (key and val) then
    reaper.ShowMessageBox("Error parsing this line:\n" .. line)
    my_error_checking_value = true
    break
  end

  -- Currently the key and value are strings. If either of them were 
  -- originally numbers, let's get them back that way
  key = not tonumber(key) and key or tonumber(key)
  val = not tonumber(val) and val or tonumber(val)

  my_table_of_data[key] = val

end

io.close(file)

Last edited by Lokasenna; 03-09-2017 at 08:29 PM.
Lokasenna is offline   Reply With Quote
Old 03-10-2017, 06:07 AM   #3
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

Thank you SO much Lokasenna!!!

A few questions:
1) if I wanted to save it in the project path, then I would replace:
Code:
local info = debug.getinfo(1,'S');
local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]]
with: script_path = reaper.GetProjectPath(0)
Right?
2)I had a look at the patterns section of the Lua manual, but still cannot understand: [[^@?(.*[\/])[^\/]-$]]. Could you explain?
3) In your opinion is it safer to store the data in the Project itself or in an external file? In the first occasion, I am worried if by mistake I corrupt the project file and in the second occasion I am worried if I delete accidentally the external file and loose what I had stored..


Hopefully, Sexan comes with his get/restore items from track chunk code and I combine it all to the script I need
amagalma is offline   Reply With Quote
Old 03-10-2017, 08:21 AM   #4
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,430
Default

1. I think so, yes.

3. As far as I know it's not possible for an ExtState to corrupt a project file. As for accidentally deleting the external file... maybe don't delete it then? I prefer external files just because it's easier to store a lot of settings/data in whatever format you want. For instance, Radial Menu stores its settings as a Lua table in text form, so loading settings is just a matter of loadstring("settings.txt")()

2. Yeah, patterns are fun. I have to use bookmarked sites for them half the time. It helps to break them down into individual symbols/sections:

Code:
[[                  ]]
Tells Lua that this is a literal string, so you don't have to use \\s anywhere


Code:
  ^                $
These specify the beginning and end of the string, respectively.


Code:
   @?
The string can start with a single @, but it doesn't have to.


Code:
     (      )
()s tell string.match what part of the string we want to extract.


Code:
      .*
Matches any characters, of any length.


Code:
        [  ]
These define a 'set', so any of the characters in it will be a match.


Code:
         \/
In this case, the set will match either a \ or a /.


The total 'capture', then, translates as:
"Grab the longest string you can that ends with a \ or /"


Code:
             [^\/]-
Another set. Within a set, ^ means 'not', so it will match anything that ISN'T a \ or /. Additionally the - afterward tells it that the match should be as short as possible.

So the entire pattern translates as:

From the beginning of the string, ignoring the @ symbol if it starts with one, grab the longest string you can find that ends with a \ or /.

For example, info.source returns this on my system:
Code:
@C:\Users\Adam\AppData\Roaming\REAPER\Scripts\Lokasenna\misc + testing\display info.source .lua
After matching, that becomes:
Code:
C:\Users\Adam\AppData\Roaming\REAPER\Scripts\Lokasenna\misc + testing\
Lokasenna is offline   Reply With Quote
Old 03-10-2017, 09:12 AM   #5
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

Thank you very much for the explication and your time!

Regarding external files or ExtState.. I understood that when saving/recalling to/from external files, there are two ways to save/recall depending on the format of my table's indices. Right?

One does not have the same choice when using ExtState? Does it require a special format? What makes it more difficult than external files?
amagalma is offline   Reply With Quote
Old 03-10-2017, 10:14 AM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,430
Default

With an external file, you're free to store the data in whatever way you want. ExtStates are just a series of string keys and string values, so you still have to grab each of them and convert them back to numbers, etc if necessary.

ProjExtStates can use retval, keyOutOptional, valOutOptional reaper.EnumProjExtState( proj, extname, idx ) to loop through all of the keys for a given ExtName, which would be essentially the same as the second load method above - each loop would output a new key and value pair.

If it's project-related data, by all means use ProjExtStates.
Lokasenna is offline   Reply With Quote
Old 03-10-2017, 03:12 PM   #7
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

Yes, it's project-related data.. I would like to make items on selected track to appear and disappear.. So, when the time comes, and if I cannot manage it myself, I'll ask you again on how to do it with ExtStates.. At the moment, this discussion is irrelevant as long as I cannot get item-only-related track chunks...
amagalma is offline   Reply With Quote
Old 03-12-2017, 05:52 AM   #8
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I managed to hack the code I wanted from benmiller's scripts here. But it is in eel..
amagalma is offline   Reply With Quote
Old 03-12-2017, 06:31 AM   #9
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

Can I ask what are you trying to build? My script has more or less every feature you need. If you want I can post stripped down script with only basic functionallity so you can add your stuff.

It has storing ,deleting ,hiding ,appearing, chunks etc. So when you click save it stores all the necessary data you need from the item
Sexan is offline   Reply With Quote
Old 03-12-2017, 06:52 AM   #10
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I am trying to build a playlist system that it is a hybrid of your approach (with track chunks) and heda's approach in his Track Inspector (with hidden tracks).

I have a good deal of it ready... My only problem is that some of my scripts are in eel and other in lua.. which is a small inconsistency..

The basic idea is:
-your Main take lives in a folder track, where all the fx AND items are
- alternative takes are childs of the folder
- when soloing-choosing a take (a child track), the rest of the the tales (child tracks) are muted and the items on the Main take (folder track) are deleted and saved in ExtState
- when soloing-choosing the Main Take, then all of its childs are muted and and the items that were on the Main Take are recalled from ExtState
- there are functions to copy from the child takes to the main take, to duplicate a take, or to downgrade a Main Take as regular take

The problem with your approach-script is that one cannot see all different playlists simultaneously and sometimes I have lost some items when changing between playlists. The problem with heda´s approach is that every playlist has all the FX loaded again, which is a waste of CPU.

I think the hybird approach is the best of both worlds. What do you think?

Last edited by amagalma; 03-12-2017 at 07:07 AM.
amagalma is offline   Reply With Quote
Old 03-12-2017, 07:13 AM   #11
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

The part that I am not sure what to do about is track envelopes..
amagalma is offline   Reply With Quote
Old 03-12-2017, 07:43 AM   #12
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

Sounds cool, AFAIK envelopes can also can be read-stored from-to chunk
Sexan is offline   Reply With Quote
Old 03-12-2017, 08:45 AM   #13
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I need your help Sexan, please

I need a function to Store to Project ExtState and a function to Recall all the items and all the track envelopes (VOLENV, PANENV, VOLENV2, PANENV2, WIDTHENV, WIDTHENV2, VOLENV3, MUTEENV) of a track.

Do you have such a code to share?
amagalma is offline   Reply With Quote
Old 03-12-2017, 09:00 AM   #14
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

I currently do not have envelopes implemented, but I will look into it. My script only (at the moment) stores item chunks. But since we are talking about them keep in mind if you wanna store the WHOLE track chunk with FX it can crash reaper with certain VST-VSTi (they get pretty large). Wait a minute I will post you the code that stores and recalls items. BTW you will need to implement (copy-paste) picke code
Sexan is offline   Reply With Quote
Old 03-12-2017, 09:08 AM   #15
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

Saving :
Code:
function store()
  local save = {}
    for i = 1 , #table do
      save[#save+1] = {item = item}      
    end
  reaper.SetProjExtState(0, "Save", "States", pickle(save))
end
Restoring:
Code:
function restore()
  local ok, states = reaper.GetProjExtState(0, "Save","States")
    if states~="" then
      states = unpickle(states)
        for i = 1, #states do
          item = states[i].item
        end
    end
end
for this code to work you will need picke at the top of your script

This may be a little unclear to you just as raw functions. If you have some code to share I will help you implement it. If your code involves tables you will need it,also you will need pickle (its little long to post it here) :

http://lua-users.org/wiki/PickleTable
You literally just need to copy paste it in your script

If your code does not involve tables, then this functions will need to be adjusted to that.

Basically all you need to do (if you currently HAVE all the needed chunks) is store them to table call this functions and thats it. Restore function will need to be modified in order to restore your chunks/data to apropriate place

Lets go step by step here, implement one feature at the time. And also I am not very good at explaining things but I will try my best

Last edited by Sexan; 03-12-2017 at 09:16 AM.
Sexan is offline   Reply With Quote
Old 03-12-2017, 09:08 AM   #16
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

No, I do not need the whole track chunk. Just the <ITEMS> and the 8 track envelopes that I mentioned before. Thanks!

P.S. What is your pickle and unpickle code? Could you post that too? Is it this?
amagalma is offline   Reply With Quote
Old 03-12-2017, 09:17 AM   #17
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

wait there are few more functions, and this is only for ITEM only. Yeah thats the pickle

Code:
function getTrackItems(track)
  local items={}
  local num_items = reaper.CountTrackMediaItems(track)
    for i=1, num_items, 1 do
      local item = reaper.GetTrackMediaItem(track, i-1)
      local _, it_chunk = reaper.GetItemStateChunk(item, '')
      items[#items+1]=it_chunk
    end
    if #items == 0 then items[1]=EMPTY_TABLE end -- pickle doesn't like empty tables
  return setmetatable(items, tcmt)
end
When you call this function it will get you all the all ITEM chunks on track
Code:
items = getTrackItems(track)
Code:
function restoreTrackItems(guid, track_items_table)
  local track = reaper.BR_GetMediaTrackByGUID(0,guid)
  local num_items = reaper.CountTrackMediaItems(track)
      for i = 1, num_items, 1 do
        reaper.DeleteTrackMediaItem(track, reaper.GetTrackMediaItem(track,0))
      end
    for i = 1, #track_items_table, 1 do
      local item = reaper.AddMediaItemToTrack(track)            
      reaper.SetItemStateChunk(item, track_items_table[i], false)
    end
  reaper.UpdateArrange()
end
This one sets items on your track,you need to specify guid of the track and table where you stored the items

Last edited by Sexan; 03-12-2017 at 09:25 AM.
Sexan is offline   Reply With Quote
Old 03-12-2017, 09:20 AM   #18
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I have this code in eel:
Code:
function FilterStringToPhrase(pstr,str)
local(pi,i,found,ii,garbage,temp)
(
  pi=0;
  pl=strlen(pstr);
  loop(pl,
    stack_push(str_getchar(pstr, pi));
    pi!=pl ? pi+=1;
  );
  i=found=0;
  while( i<strlen(str) && !found) (
    str_getchar(str, i)==stack_peek(pi-1) && str_getchar(str, i+1)==stack_peek(pi-2) ? (
    ii=0;
    //testpeek=1;
    loop(pi,
      str_getchar(str, i+ii)==stack_peek(pi-1-ii) ? ii+=1;
    );
    ii==pi ? found=1; //testf=1;
    ); 
    i+=1; 
  );
  loop(pi, garbage=stack_pop(); ); //clean up stack     
  found ?  (
    strncpy(temp=#,str,i-1); 
    strcpy(str,temp);  
  );      
);

function FilterStringFromPhrase(pstr,str)
local(pi,i,found,ii,garbage,temp)
(
  pi=0;
  pl=strlen(pstr);
  loop(pl,
    stack_push(str_getchar(pstr, pi));
    pi!=pl ? pi+=1;
  );
  i=found=0;
  while( i<strlen(str) && !found) (
    str_getchar(str, i)==stack_peek(pi-1) && str_getchar(str, i+1)==stack_peek(pi-2) ? (
      ii=0;
      //testpeek=1;
      loop(pi,
        str_getchar(str, i+ii)==stack_peek(pi-1-ii) ? ii+=1;
      );
      ii==pi ? found=1; //testf=1;
    ); 
    i+=1; 
  );
  loop(pi, garbage=stack_pop(); ); //clean up stack     
  found ?  (
    strcpy_from(temp=#,str,i-1); 
    strcpy(str,temp);  
  );      
);

function GetItemsOnly(oldchunk,newchunk)
(match("*\n<ITEM*",#TrackChunk);)?(
  strcpy(#From,oldchunk);
  strcpy(#To,newchunk);
  FilterStringToPhrase("<ITEM",#To);
  FilterStringFromPhrase("<ITEM",#From);
  strcpy(newchunk,#To);
  strcat(newchunk,#From);
  ):(sprintf(newchunk,"<<NOITEMS>>");
);

function GetNonItemsOnly(oldchunk,newchunk)
(
(match("*\n<ITEM*",#TrackChunk);)?(
  strcpy(#To,oldchunk);
  strcpy(#From,newchunk);
  FilterStringToPhrase("<ITEM",#To);
  FilterStringFromPhrase("<ITEM",#From);
  strcpy(newchunk,#To);
  strcat(newchunk,#From);
  //sprintf(newchunk,"%s>",newchunk);
  ):(
  strcpy(#To,oldchunk);
  strcpy(#From,newchunk);
  FilterStringToPhrase("<ITEM",#To);
  FilterStringFromPhrase("<ITEM",#From);
  strcpy(newchunk,#To);
  strcat(newchunk,#From);
  len=strlen(newchunk)-2;
  str_delsub(newchunk,len,2);
  //If no items, remove the last ">" from the chunk!!!
  );
); 
////////////////////////////////////////////////////////////////////////////////////
function SaveTrackItemsToExtState()
(track = GetSelectedTrack( 0, 0 );
  GetTrackStateChunk(track, #TrackChunk, 0);
  GetTrackGUID(#TrackGUID, track);
  sprintf(#section,"SavedFolderTrack");
  sprintf(#trackid,"trackGUID %s",#TrackGUID);
  GetItemsOnly(#TrackChunk,#NewChunk);
  SetProjExtState(0,#section,#trackid,#NewChunk);
);

function RecallTrackItemsFromExtState()
(track = GetSelectedTrack( 0, 0 );
  GetTrackGUID(#TrackGUID, track);
  sprintf(#section,"SavedFolderTrack");
  sprintf(#trackid,"trackGUID %s",#TrackGUID);
  GetTrackStateChunk(track, #TrackChunk, 0);
  (GetProjExtState(0,#section,#trackid,#EndChunk);   
  ) 
  ?(  GetNonItemsOnly(#TrackChunk,#StartChunk);
  
      (match("<<NOITEMS>>",#EndChunk))
      ?(sprintf(#NewChunk,"%s>",#StartChunk);)
       
      :(sprintf(#NewChunk,"%s%s",#StartChunk,#EndChunk);
      
      );
      SetTrackStateChunk(track, #NewChunk, 1);   
   ) : (//playlistdoesn't exist!
    MB("A saved ExtState for the selected track has not been found!", "Error!", 0 );
   ); 
);

//RecallTrackItemsFromExtState()
//SaveTrackItemsToExtState()
It's a modification of benmiller's code for playlists and it is in eel. It saves and restores the selected track's items. I need to modify it and and the track envelopes too. Or perhaps start a new script in lua with your guidance that does what I need.
amagalma is offline   Reply With Quote
Old 03-12-2017, 09:23 AM   #19
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I could simply make new functions and substitute <VOLENV for <ITEMS etc but I think this would not be the most economic and efficient way to do it...
amagalma is offline   Reply With Quote
Old 03-12-2017, 09:24 AM   #20
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

Sorry I dont know EEL, not even to port 1 line from it to LUA. BTW this functions are not looking at TRACK chunks, but ITEMS chunks, different API
Sexan is offline   Reply With Quote
Old 03-12-2017, 09:35 AM   #21
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

You mean your functions look at ITEM CHUNKS?
amagalma is offline   Reply With Quote
Old 03-12-2017, 09:38 AM   #22
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 2,452
Default

yes because it was easier since I only needed items to be stored,it can be modified to look at track chunk and then extract the items from it and other stuff if you need that.Regarding chunks it would be better to ask someone more knowledgeable in that area (mpl,eugen,x-raym) if you need TRACK CHUNKS
Sexan is offline   Reply With Quote
Old 03-12-2017, 10:12 AM   #23
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

Yes, probably I need Track Chunks since I want to get the envelopes too besides the items.
amagalma is offline   Reply With Quote
Old 03-12-2017, 03:21 PM   #24
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

I'll try to do it from the beginning in lua..

Ok, let's say I have the track chunk I want. For example:
Code:
<TRACK
NAME test
PEAKCOL 16576
BEAT -1
AUTOMODE 0
VOLPAN 1 0 -1 -1 1
MUTESOLO 0 0 0
IPHASE 0
ISBUS 0 0
BUSCOMP 0 0
SHOWINMIX 1 0.6667 0.5 1 0.5 0 0 0
FREEMODE 0
REC 0 1 1 0 0 0 0
VU 2
TRACKHEIGHT 0 0
INQ 0 0 0 0.5 100 0 0 100
NCHAN 2
FX 1
TRACKID {16F72221-7DB1-4940-91E0-B32238687864}
PERF 0
MIDIOUT -1
MAINSEND 1 0
<VOLENV
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 5 1 1
>
<PANENV
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 0 1
PT 6 0 1
>
<VOLENV2
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 6 1 1
>
<PANENV2
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 0 1
PT 6 0 1
>
<WIDTHENV
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 6 1 1
>
<WIDTHENV2
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 6 1 1
>
<VOLENV3
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 5 1 1
>
<MUTEENV
ACT 1
VIS 1 1 1
LANEHEIGHT 0 0
ARM 0
DEFSHAPE 1 -1 -1
PT 0 1 1
PT 5 1 1
>
<FXCHAIN
SHOW 0
LASTSEL 0
DOCKED 0
>
<ITEM
POSITION 0
SNAPOFFS 0
LENGTH 10
LOOP 0
ALLTAKES 0
FADEIN 1 0 0 1 0 0
FADEOUT 1 0 0 1 0 0
MUTE 0
SEL 1
IGUID {4068E6F0-4AA1-4F3E-A102-FCCCA11854EC}
IID 1
NAME test
VOLPAN 1 0 1 -1
SOFFS 0 0
PLAYRATE 1 1 0 -1 0 0.0025
CHANMODE 0
GUID {620F91D0-1C1B-4378-8C64-6FE5DF345940}
<SOURCE MIDI
HASDATA 1 960 QN
POOLEDEVTS {60D0E25E-D926-46C8-97D0-ABBAE6C77C84}
E 0 90 25 60
E 1920 80 25 00
E 960 90 30 60
E 2880 80 30 00
E 960 90 35 60
E 1920 80 35 00
E 960 90 2d 60
E 5280 80 2d 00
E 0 90 23 60
E 2400 80 23 00
e 0 90 27 60
e 480 80 27 00
E 1440 b0 7b 00
GUID {1BB8F3BE-77B5-49CB-B923-54B32F082ACB}
IGNTEMPO 0 120 4 4
SRCCOLOR 0
VELLANE 32 180 0
CFGEDITVIEW 0 68.4 61 12 0 -1 0 0 0 0.5
KEYSNAP 0
TRACKSEL 0
EVTFILTER 0 -1 -1 -1 -1 0 0 0 0 -1 -1 -1 -1 0 -1 0 -1 -1
CFGEDIT 1 1 0 1 0 0 1 1 1 1 1 0.5 24 24 1688 1018 0 0 2 0 0 0 0 0 0 0.5 0 0 1 64
>
>
>
I want to get only ITEMS and the 8 track envelopes. I need some string.match formation and then a way to put them in a table so that it can be saved to Project ExtState.. That's in theory.. In practice, how?
amagalma is offline   Reply With Quote
Old 03-14-2017, 04:34 PM   #25
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,512
Default

Small bump...
amagalma is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 07:13 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.