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

API Functions Request: Get/Set SWS Notes and Subtitles #755

Closed
X-Raym opened this Issue Aug 3, 2015 · 20 comments

Comments

Projects
None yet
2 participants
@X-Raym
Copy link
Contributor

X-Raym commented Aug 3, 2015

Hi !

SWS come with Regions and Markers notes (subtitles) possibility.
But, we cant reach them at script level.
It would be nice to have a function like GetMarlerNotes(id) so that we can return these notes into ReaScript.

Thanks for listening !

@X-Raym X-Raym changed the title API Function Request: GetMarkerNotes API Function Request: Get Marker/Regions Notes/Subtitles Aug 3, 2015

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented Apr 8, 2017

A Set function would be handy too. 👍
Or we can consider GetSet functions instead.

Also, extra notes from SWS are not accessible either from API, like :

  • Track notes
  • Extra project notes

For flexibility, it would be nice to have them too.

@X-Raym X-Raym changed the title API Function Request: Get Marker/Regions Notes/Subtitles API Function Request: Get/Set SWS Notes and Subtitles Apr 8, 2017

@X-Raym X-Raym changed the title API Function Request: Get/Set SWS Notes and Subtitles API Functions Request: Get/Set SWS Notes and Subtitles Apr 8, 2017

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented Apr 17, 2018

@nofishonfriday Hi ! Any progress on your investigation about this ? :)

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 13, 2018

@X-Raym
Here's a test version for getting / setting region subtitles (for markers may come later if getting to working ok with regions):
https://www.dropbox.com/s/ysl24dy2ftuzq5k/reaper_sws64_GetSetRegionSubs01.dll?dl=1

Example code:

reaper.ClearConsole()

function msg(m)
  return reaper.ShowConsoleMsg(tostring(m) .. "\n")
end

local regionIdx = 1 -- one-based (as how region numbers are displayed in the project / Region/Marker manager)

-- SET REGION SUB --
local fastStringIn = reaper.SNM_CreateFastString("Subtitle text for region " .. regionIdx)

-- set region sub, note: region must in exist in project already that region sub can be set!
-- returns true if region sub is set successfully (ie region exists in project)
regionSubIsSet = reaper.NF_SetRegionSub(fastStringIn, regionIdx) 

reaper.SNM_DeleteFastString(fastStringIn)


-- GET REGION SUB --
local fastStringOut = reaper.SNM_CreateFastString("")

-- get region sub, returns empty string if region not existant or region sub not set
regionSub = reaper.NF_GetRegionSub(fastStringOut, regionIdx) 

msg("Region sub for region " .. regionIdx .. ": " .. regionSub)
reaper.SNM_DeleteFastString(fastStringOut)

Let me know how it goes. :)

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 16, 2018

@nofish Nice you work on that :P

Could it be based on RegionIDX (like parameter of EnumProjectMarker) or on idx (like the retval of EnumProjectMarker) ?

Currently, if there is markers, it is not very handy to plug this function.

Here is demo code with a usual region/marker loop:

https://www.dropbox.com/s/fi8wnguret60a2j/region%20notes.rpp?dl=0

count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  local fastStringOut = reaper.SNM_CreateFastString("")
  regionSub = reaper.NF_GetRegionSub(fastStringOut, retval)
  msg("Region sub " .. retval .. " = " .. regionSub)
  reaper.SNM_DeleteFastString(fastStringOut)
  i = i + 1
end

We already have to deal with idx and regionIDX, so a third type of index (the one displayed on the timeline, wich is different that the other two) is a bit confusing. (or maybe I miss something. Which prove it can be confusing haha :P)

Note that it is already generic (it can return both marker and region notes, so the name might be change). IMHO, it it can deal with EnumProjectMarkers( i ) i parameter it would then be more coherent (as this function is also able to return both markers and regions).

What do you think ?

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 16, 2018

Could you do a quick explaination about RegionIDX and idx, what do they specify (what's the difference) ?
I'm currently getting confused by this. :D

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 16, 2018

@nofishonfriday well, the most confusing part is that all of that are called indexes ^^

Ok so I tested with a more complete code snippet. Let's restart from there:

count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  markerIdx, regionIdx = reaper.GetLastMarkerAndCurRegion( 0, posOut )
  local fastStringOut = reaper.SNM_CreateFastString("")
  regionSub = reaper.NF_GetRegionSub(fastStringOut, markrgnindexnumberOut)
  msg("i = " .. i)
  msg("retval = " .. retval)
  msg("is_region = " .. tostring(isrgnOut))
  msg("markrgnindexnumberOut = " .. markrgnindexnumberOut)
  msg("NOTES = " .. regionSub)
  msg("")
  reaper.SNM_DeleteFastString(fastStringOut)
  i = i + 1
end
  • We have EnumProjectMarkers( i ) index. This can return both Region or Markers. i is zero based.
  • The retval of EnumProjectMarkers( i ) is in fact just i + 1.
  • the markrgnindexnumber returned value of EnumProjectMarkers( i ) is the number in the arrange view

So it sounds like the markrgnindexnumber should work, according to your comment, but it does not. Something is wrong in the get notes function. I think it is confused by the order of the marker/region.

Here what I got with my RPP:

i = 0
retval = 1
is_region = true
markrgnindexnumberOut = 1
NOTES = Region 1

i = 1
retval = 2
is_region = false
markrgnindexnumberOut = 1
NOTES = Region 1

i = 2
retval = 3
is_region = true
markrgnindexnumberOut = 3
NOTES = Region 3

i = 3
retval = 4
is_region = false
markrgnindexnumberOut = 2
NOTES = Marker 1

i = 4
retval = 5
is_region = true
markrgnindexnumberOut = 2
NOTES = Marker 1

Instead of

i = 0
retval = 1
is_region = true
markrgnindexnumberOut = 1
NOTES = Region 1

i = 1
retval = 2
is_region = false
markrgnindexnumberOut = 1
NOTES = Marker 1

i = 2
retval = 3
is_region = true
markrgnindexnumberOut = 3
NOTES = Region 3

i = 3
retval = 4
is_region = false
markrgnindexnumberOut = 2
NOTES = Marker 2

i = 4
retval = 5
is_region = true
markrgnindexnumberOut = 2
NOTES = Region 2

What I would find useful is the NF_GetRegionSub to be a NF_GetMarkerRegionSub and would work just like the EnumProjectMarkers( i ) with the i parameter. This way, easy to plug in the loop !

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 16, 2018

Your provided material helps a lot again Sir! °°
Thanks.

Next version:
https://www.dropbox.com/s/m37shzq1cbhncgk/reaper_sws64_GetSetRegionSubs02.dll?dl=1

updated script:

reaper.ClearConsole()

function msg(m)
  return reaper.ShowConsoleMsg(tostring(m) .. "\n")
end

count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  markerIdx, regionIdx = reaper.GetLastMarkerAndCurRegion( 0, posOut )
  local fastStringOut = reaper.SNM_CreateFastString("")
  regionSub = reaper.NF_GetMarkerRegionSub(fastStringOut, i) -- renamed function and works now on i index!
  msg("i = " .. i)
  msg("retval = " .. retval)
  msg("is_region = " .. tostring(isrgnOut))
  msg("markrgnindexnumberOut = " .. markrgnindexnumberOut)
  msg("NOTES = " .. regionSub)
  msg("")
  reaper.SNM_DeleteFastString(fastStringOut)
  i = i + 1
end

Console output I now get with your project:

i = 0
retval = 1
is_region = true
markrgnindexnumberOut = 1
NOTES = Region 1

i = 1
retval = 2
is_region = false
markrgnindexnumberOut = 1
NOTES = Marker 1

i = 2
retval = 3
is_region = true
markrgnindexnumberOut = 3
NOTES = Region 3

i = 3
retval = 4
is_region = false
markrgnindexnumberOut = 2
NOTES = Marker 2

i = 4
retval = 5
is_region = true
markrgnindexnumberOut = 2
NOTES = Region 2

Looks ok ?
(The Set... function is not working correctly yet...)

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 16, 2018

@nofishonfriday This does looks like to be the expected results ! Well done 💃

I assume the setting function is harder, but at least we have a clear idea of how it should behave.

Having these accessible via API will really bring interoperability to Region and Markers.

Good luck !

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 17, 2018

Next version for testing the Set function:
https://www.dropbox.com/s/8mrmlkkh4nxclud/reaper_sws64_GetSetRegionSubs03.dll?dl=1

For test code I used this:

reaper.ClearConsole()

function msg(m)
  return reaper.ShowConsoleMsg(tostring(m) .. "\n")
end

-- set subs
count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  
  if isrgnOut == true then 
    fastStringIn = reaper.SNM_CreateFastString("new Subtitle text for region " .. markrgnindexnumberOut)
  else
    fastStringIn = reaper.SNM_CreateFastString("new Subtitle text for marker " .. markrgnindexnumberOut)
  end
  
  regionSubIsSet = reaper.NF_SetMarkerRegionSub(fastStringIn, i)
  reaper.SNM_DeleteFastString(fastStringIn)
  i = i + 1
end

-- get subs
count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  markerIdx, regionIdx = reaper.GetLastMarkerAndCurRegion( 0, posOut )
  local fastStringOut = reaper.SNM_CreateFastString("")
  regionSub = reaper.NF_GetMarkerRegionSub(fastStringOut, i)
  msg("i = " .. i)
  msg("retval = " .. retval)
  msg("is_region = " .. tostring(isrgnOut))
  msg("markrgnindexnumberOut = " .. markrgnindexnumberOut)
  msg("NOTES = " .. regionSub)
  msg("")
  reaper.SNM_DeleteFastString(fastStringOut)
  i = i + 1
end

What do you think ?

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 17, 2018

@nofishonfriday This seems to works flawlessly, even with non consecutive marker index ! Ready to be merge :P

Note: You can color highlight your code snippet :P https://help.github.com/articles/creating-and-highlighting-code-blocks/

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 17, 2018

Cool, thanks for testing.

Some final touches before PR / merge:
https://www.dropbox.com/s/0j6w9yhve6hrj1c/reaper_sws64_GetSetRegionSubs04.dll?dl=1

  • Functions have been renamed to NF_Get/SetSWSMarkerRegionSub (to be consistent with already existing NF_Get/SetSWSTrackNotes)

  • SetMarkerRegionSub got a new param, see updated ReaScript API doc. (ReaScript: Open reaScript documentation (html)... )

Also it would be nice if you could say what you think about the doc for these functions, if I should change/add anything.
Thanks.

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 17, 2018

@nofishonfriday All good and working fine !

(how much faster it is with the force update set to off ?)

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 17, 2018

When set to on the function must: iterate over all existing subs and check if the passed in one is currently displayed so it can update it imediately.
Don't know how much that makes in real life (you could measure and tell me if you're curious :P).

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 17, 2018

@nofishonfriday so don't you think that there shouldn't be an extra update parameter, but simply a force display update function, as we have with other system( reaper.UpdateArrange etc...) ?

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 17, 2018

Good idea, makes it more consistent with Reaper API. :)

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 17, 2018

Done.
https://www.dropbox.com/s/zur7lc6xdzfyu4v/reaper_sws64_GetSetRegionSubs05.dll?dl=1

Reverted forceDisplayUpdate param, added NF_UpdateSWSMarkerRegionSubWindow()
(API doc also updated)

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 18, 2018

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented May 18, 2018

Thanks for the snippet template, I've linked it in the ReaScript doc.
I think a little optimisation (better coding practice) would be to create the fastString before the loop and delete afterwards instead of creating / destroying in every iteration (didn't think about this when doing the script originally).

-- For SWS v2.9.9.0
reaper.ClearConsole()

function msg(m)
  return reaper.ShowConsoleMsg(tostring(m) .. "\n")
end

-- set subs
fastStringIn = reaper.SNM_CreateFastString("")
count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  
  if isrgnOut == true then 
    reaper.SNM_SetFastString(fastStringIn, "new Subtitle text for region " .. markrgnindexnumberOut)
  else
    reaper.SNM_SetFastString(fastStringIn, "new Subtitle text for marker " .. markrgnindexnumberOut)
  end
  
  regionSubIsSet = reaper.NF_SetSWSMarkerRegionSub(fastStringIn, i)
  i = i + 1
end
reaper.SNM_DeleteFastString(fastStringIn)
reaper.NF_UpdateSWSMarkerRegionSubWindow() -- optional

-- get subs
fastStringOut = reaper.SNM_CreateFastString("")
count_markers_and_regions, count_regions = reaper.CountProjectMarkers(0)
for i = 0, count_markers_and_regions - 1 do
  local retval, isrgnOut, posOut, rgnendOut, nameOut, markrgnindexnumberOut =  reaper.EnumProjectMarkers( i )
  markerIdx, regionIdx = reaper.GetLastMarkerAndCurRegion( 0, posOut )
  regionSub = reaper.NF_GetSWSMarkerRegionSub(fastStringOut, i)
  msg("i = " .. i)
  msg("retval = " .. retval)
  msg("is_region = " .. tostring(isrgnOut))
  msg("markrgnindexnumberOut = " .. markrgnindexnumberOut)
  msg("NOTES = " .. regionSub)
  msg("")
  i = i + 1
end
reaper.SNM_DeleteFastString(fastStringOut)

Should I create a PR to ReaTeam? :P

@X-Raym

This comment has been minimized.

Copy link
Contributor Author

X-Raym commented May 19, 2018

@nofishonfriday yes you can :P

nofishonfriday pushed a commit to nofishonfriday/sws that referenced this issue May 19, 2018

nofishonfriday pushed a commit to nofishonfriday/sws that referenced this issue Oct 28, 2018

nofishonfriday pushed a commit to nofishonfriday/sws that referenced this issue Nov 6, 2018

@nofishonfriday

This comment has been minimized.

Copy link
Collaborator

nofishonfriday commented Feb 7, 2019

added in v2.10.0

NF_GetSWSMarkerRegionSub()
NF_SetSWSMarkerRegionSub()
NF_UpdateSWSMarkerRegionSubWindow()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment