How Can I Move Markers With Tracks in Studio One?
| | #1 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | If you are looking to get Studio One 4 chord tracks into Reaper, here's a script or standalone exe to do the job. Studio-One-4-Chords-to-Markers-x64-x86-ahk.zip As Studio One has no API like Reaper I had to use AutoHotKey set: Cursor follows Edit position <|> at the top Code: Send, ^+!n ; Studio One shortcut for 'insert named' (Marker) Ctrl+Shift+Alt+N ^+!n is sending Ctrl+Shift+Alt+N open Chord Selector Without downloading the above you can copy and save this to Studio One 4 Chords to Markers.ahk in notepad, the Macro number needs to be unique for each Action you have. Code: ;Studio One Chords to Markers F11:: ; Hot Key , set to custom ^=Ctrl !+Alt +=Shift #=Win eg. ^+y = Ctrl+Shift+Y Macro20: IfWinExist, Chord Selector WinActivate ; use the window found above ControlGetFocus, cr, A ; get the focused(active) control(child window) of the active window ControlGetPos, x, y, width, Height, %cr%, A ; get the position and dimensions of Chord Selector MouseMove, % x + Width / 2, % y + Height / 2.2 ; move mouse to center of window and up a bit , 0 Sleep, 50 MouseClick, left ; click center chord in Chord Selector clipboard:="" ; clears the clipboard While clipboard Sleep 10 ; this sleep will repeat until the clipboard is cleared. TimeOut = 0 While !clipboard AND TimeOut < 100 { Send ^c Sleep 50 ; gives time for the clipboard to be populated, especially if it is large Timeout ++ } Send, {Enter} Sleep, 50 Send, ^+!n ; Studio One shortcut for 'insert named' (Marker) Ctrl+Shift+Alt+N Sleep, 50 Send, ^V Sleep, 50 Send, {Enter} Sleep, 50 Send, {Right} Return Full Screen |
| | |
| | #2 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | Here's a JS script package that creates song markers for all selected chords. Rename the file extension to *.package and put it in the application \scripts folder and restart S1, it will appear on the Event menu, Chords to Markers. |
| | |
| | #3 |
| Human being with feelings Join Date: Aug 2007 Location: Near Cambridge UK and Near Questembert, France Posts: 22,137 | You guys always make me (non coder/scripter) feel utterly useless and inept. WELL DONE! __________________ |
| | |
| | #4 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | Yeah... that's a relatively simple script. Code: var chords = []; // collect selected chords into an array var iterator = context.iterator; while (!iterator.done()) { var event = iterator.next(); chords.push(event) } // move to the first chord event Host.GUI.Commands.interpretCommand("Navigation", "First Event") // iterate the array, only used for the range for (i = 0; i < chords.length; i++) { // get the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').string; // locate to the current chord position Host.GUI.Commands.interpretCommand('Transport', 'Locate Selection') // create a new marker named after the current chord Host.GUI.Commands.interpretCommand('Marker', 'Insert Named', false, Host.Attributes(["Name", chord])) // move to the next chord event Host.GUI.Commands.interpretCommand("Navigation", "Right") } Last edited by Lawrence; 06-28-2019 at 06:28 AM. |
| | |
| | #5 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | Yea I made the AHK script ages ago then heard someone made a java one. I will look more into it as I need to import chords from text file to S1 Last edited by MusoBob; 06-28-2019 at 01:54 PM. |
| | |
| | #6 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | Getting this error Code: // get the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').string; |
| | |
| | #7 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | I can only trigger that when there's no chord events selected, as that's not trapped. You can add this trap in the code if you want.. Code: // collect selected chords into an array var iterator = context.iterator; while (!iterator.done()) { var event = iterator.next(); // error trap --------------------------------- if (event.mediaType != undefined) { Host.GUI.alert("Please only select chord events for this function.") return; } // -------------------------------------------- chords.push(event) } Last edited by Lawrence; 06-29-2019 at 03:47 AM. |
| | |
| | #8 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | Oh of course "selected chords" ! I changed the message to "Select first chord on timeline" Code: // select all chord events Host.GUI.Commands.interpretCommand("Edit", "Select All") Yea I tried some way to select the chord track then select all but couldn't find one. I was looking for some way to "Move to bar x beat x" "Insert chord" also, so I could parse the text file with the chord list. I can do it in Reaper ok, it reads the Band In A Box plugin's chords from it's Song.txt file then inserts the regions: ReaTrak import chords from biab plugin.lua https://www.youtube.com/watch?v=5pup364svAo |
| | |
| | #9 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | So I can see the get chord name Code: // get the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').string; is there a way to set chord name ? also with "Transport" "Goto Time" if I can set that as well then it will be a start to get the chord list in. this is the text file it reads, it only needs the Chord=bar,beat,chord Code: Mode=Song ProgramName=Band-in-a-Box ProgramVersionNumber=Version 2019.1 (615) FileDate=1322889738 RealTracksOK=1 ChorusBegin=1 ChorusEnd=32 TotalChoruses=1 Tempo=90 MIDIStyle=_BREATH.STY MIDILongStyleName=Breath Celtic Pop Ballad Key=Am PartMarker=1,1 PartMarker=9,2 PartMarker=17,1 PartMarker=25,2 PartMarker=33,1 Chord=1,1,Am Chord=2,1,Dm Chord=3,1,Em Chord=4,1,Am Chord=4,3,G Chord=5,1,F Chord=6,1,Em Chord=7,1,Dm Chord=8,1,E7 Chord=9,1,Am Chord=9,3,G Chord=10,1,F Chord=10,3,G Chord=11,1,Am Chord=11,3,G Chord=12,1,F Chord=12,3,E Chord=13,1,Am Chord=13,3,G Chord=14,1,F Chord=14,3,E Chord=15,1,D Chord=16,1,Dm Chord=17,1,Am Chord=18,1,Dm Chord=19,1,Em Chord=20,1,Am Chord=20,3,G Chord=21,1,F Chord=22,1,Em Chord=23,1,Dm Chord=24,1,E7 Chord=25,1,Am Chord=25,3,G Chord=26,1,F Chord=26,3,G Chord=27,1,Am Chord=27,3,G Chord=28,1,F Chord=28,3,E Chord=29,1,Am Chord=29,3,G Chord=30,1,F Chord=30,3,E Chord=31,1,D Chord=32,1,Dm Chord=33,1,Am PPQ=120 StyleTimeSig=4 SongHasBeenToDesktopAtSomeTime=1 SongTitle=_BREATH Demo - Breath Celtic Pop Ballad TimeSig=1,4 V7=3085,1 V7=3086,51 V7=3087,1 ....... ....... |
| | |
| | #10 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | Quote: Originally Posted by MusoBob is there a way to set chord name ? Try ~.findParameter('chord').setValue(var, true); That may work, haven't tried it though. |
| | |
| | #11 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | This works to edit the existing chord to E Code: // set the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').setValue('E', true); not sure how to set the time position then insert new chord ? Code: Host.GUI.Commands.interpretCommand('Navigation', 'Goto Time', false, Host.Attributes(['Time', '04.01.01.00']) EDIT: If there's no way to insert a chord, I can get the user to insert one chord manually, then the script will copy, paste and rename the chord. Last edited by MusoBob; 06-30-2019 at 10:38 PM. |
| | |
| | #12 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | Host.Attributes only works for actions that have arguments and that one doesn't so that's a non-starter as it has no attributes. For positioning, this will get the play cursor... Code: var cursor = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('primaryTime') … and the time divisions of that are somewhat odd. This appears to work with your data once you extract the bar and beat integers, where data[0] is bars and data[1] is beats. Looping doing that correctly placed the cursor for each event from your BIAB text... Code: var position = ((data[0] * 2) - 2) var beat = data[1] if (beat > 1) {position = (position + (beat * .5))} cursor.setValue(position, true) Another option is to Return to Zero and use Forward Bar and Nudge (1/4 note) commands or something to move the play cursor before pasting. What you're trying to do re: creating new chord events, may not be possible except for pasting, not sure yet. Pasting chord events also doesn't force focus to or update the object required to rename it. It's easy enough to extract the data, start with one chord event and cut it as the first step, then use paste to paste the 47 new chord events from that text into their correct bar and beat positions. The idea then was to put those into an array and circle back and select (for focus) and name them in series as in the previous loop the event focus is not allowing it. That's not working currently. It looks like the code is executing too fast. I'll look at it again when I get time. The main issue there is that the chord events don't have appear to have exposed "name" or "title" properties, they can only be named from the chord selector object so that has to be updated or refreshed for it to work. P.S. Is that text something that BIAB auto-generates or is that something you manually extracted? Anyway, your experiment with BIAB is interesting. Last edited by Lawrence; 07-01-2019 at 05:50 AM. |
| | |
| | #13 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | "P.S. Is that text something that BIAB auto-generates or is that something you manually extracted?" Haven't tried S1 enough to see if you need to connect the chords, or you can have one bar chord C on bar 1 and a one bar chord G on bar 4 where it changes. I could just paste a C every bar until change occurs on a bar or mid bar. Code: // change the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') //.findParameter('chord').string; .findParameter('chord').setValue('E', true); //Host.GUI.alert(chord) // copy chord event Host.GUI.Commands.interpretCommand("Edit", "Copy") // change the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').setValue('E', true); var time = "6.02.01.00" Host.GUI.Commands.interpretCommand('Transport', 'Goto Time', false, Host.Attributes(["Time", time])) Host.GUI.Commands.interpretCommand("Edit", "Paste") // move to the next chord event Host.GUI.Commands.interpretCommand("Navigation", "Next Event") // change the current chord name var chord = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/EventInspector/EventInfo/ChordSelector') .findParameter('chord').setValue('A', true); Thanks for the help ! Last edited by MusoBob; 07-01-2019 at 10:27 AM. |
| | |
| | #14 |
| Human being with feelings Join Date: Mar 2007 Posts: 21,554 | You're welcome. I got it sorted out. See the animated gif below. It only requires clicking in one chord event and running it. https://prnt.sc/o9l2u7 Last edited by Lawrence; 07-02-2019 at 09:01 AM. |
| | |
| | #15 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | Awesome thanks ! but I think it's missing the start of the function and end when you pasted. Code: function BiabPluginChords() { ...... ...... function createInstance() { return new BiabPluginChords; } and the classfactory.xml do I make a unique ID ?? Code: <ClassFactory> <ScriptClass classID="{427F12C7-F026-44E2-8180-B77B998C3085}" category="EditTask" subCategory="EventEdit" name="Biab Plugin Chords" sourceFile="code.js" functionName="createInstance" metaClassID="{D40394D1-852A-4B7E-8B4D-24FFB57232BA}"> <Attribute id="menuPriority" value="1"/> </ScriptClass> </ClassFactory> |
| | |
| | #16 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | Another thing, can you have a 2 bar offset as the tracks have a 2 bar count-in, so if it could start on bar 3, but don't worry if it's an issue they can insert 2 bars after the chords are populated. Like select the first 2 bars the Insert Silence (Ctrl+Alt+I) EDIT: I don't know if the cursor position is in time or bars ? Quote: // move the play cursor and paste a new event And beat needs to -1 as it's putting the A on beat 4 and not 3 beat -1 Last edited by MusoBob; 07-02-2019 at 07:55 PM. |
| | |
| | #17 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | I think that's working right now at different tempos, it just needs to get the EDIT: It needs to start another bar ahead from where it does at the moment also. Code: var bar1 = data[0]; var beat = data[1]; var bar = Number(bar1) + 1 EDIT: got the Cursor follows edit position Code: Host.GUI.Commands.interpretCommand('Transport', 'Cursor follows Edit Position', false, Host.Attributes(["State", "1"])) Code: function BiabPluginChords() { this.interfaces = [ Host.Interfaces.IEditTask ]; // --------------------------------------------------------------------- this.prepareEdit = function (context) { return Host.Results.kResultOk; } // --------------------------------------------------------------------- this.performEdit = function (context) { // play cursor var cursor = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('primaryTime'); // host command shortcut var cmd = Host.GUI.Commands; /////////////////////////////////////////////////////////////////////////////// ////////////////////// OPEN / READ BIAB TEXT FILE //////////////////////////// /////////////////////////////////////////////////////////////////////////////// var fileSelector = Host.Classes.createInstance("CCL:FileSelector"); var textType = {filename: ("Song.txt"),description: ("Song.txt"), extension: "txt", mimetype: "text"}; fileSelector.addFilter(textType); fileSelector.runOpen(); var path = fileSelector.getPath() // array to hold the chord names var chordNames = []; context.editor.selection.showHideSuspended = true; // cut the manually created event to the clipboard cmd.interpretCommand("Edit", "Cut") // read the file and paste events, and build the name array var file = Host.IO.openTextFile(path); if (file) { while (!file.endOfStream) { var text = file.readLine() // only read the lines with Chord= if (text.indexOf("Chord=") > -1) { // strip unnecessary text text = text.replace("Chord=", "") // split the delimited text and get the data data = text.split(',') var bar = data[0]; var beat = data[1]; // push name to a reference array for the chord names chordNames.push (data[2]) // move the play cursor and paste a new event //var position = ((bar * 2) + 2) var bpm = 140 var beat_per_measure = 4 var position = (bar * (((((beat_per_measure) / bpm) * 60)))) var beat = data[1] //if (beat > 1) {position = (position + (beat * .5))} if (beat > 1) {position = (position + (((((beat - 1) / bpm) * 60))))} cursor.setValue(position, true) // paste the new event cmd.interpretCommand("Edit", "Paste") } } file.close(); } // select and name all of the new chord events var chordSelector = Host.Objects.getObjectByUrl ('object://hostapp/DocumentManager/ActiveDocument/TrackList/CurrentChord/EventInfo/ChordSelector') .findParameter('chord') // select the first event cmd.interpretCommand('Navigation', 'First Event') // iterate the names array and name each event for (i = 0; i < chordNames.length; i++) { chordSelector.setValue(chordNames[i], true) cmd.interpretCommand('Navigation', 'Next Event') } context.editor.selection.showHideSuspended = false; return Host.Results.kResultOk; } } function createInstance() { return new BiabPluginChords; } Last edited by MusoBob; 07-03-2019 at 06:08 PM. |
| | |
| | #18 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | I got the tempo with Code: var bpm = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('tempo').string; Now I just got to get the numerator of the time signature. EDIT: here's the latest one, it just needs to get beat_per_measure from StyleTimeSig= in the Biab Song.txt Code: function BiabPluginChords() { this.interfaces = [ Host.Interfaces.IEditTask ]; // --------------------------------------------------------------------- this.prepareEdit = function (context) { return Host.Results.kResultOk; } // --------------------------------------------------------------------- this.performEdit = function (context) { // set Cursor follows Edit Position Host.GUI.Commands.interpretCommand('Transport', 'Cursor follows Edit Position', false, Host.Attributes(["State", "1"])) // get the current tempo var bpm = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('tempo').string; // play cursor var cursor = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('primaryTime'); // host command shortcut var cmd = Host.GUI.Commands; /////////////////////////////////////////////////////////////////////////////// ////////////////////// OPEN / READ BIAB TEXT FILE //////////////////////////// /////////////////////////////////////////////////////////////////////////////// var fileSelector = Host.Classes.createInstance("CCL:FileSelector"); var textType = {filename: ("Song.txt"),description: ("Song.txt"), extension: "txt", mimetype: "text"}; fileSelector.addFilter(textType); fileSelector.runOpen(); var path = fileSelector.getPath() // array to hold the chord names var chordNames = []; context.editor.selection.showHideSuspended = true; // cut the manually created event to the clipboard cmd.interpretCommand("Edit", "Cut") // read the file and paste events, and build the name array var file = Host.IO.openTextFile(path); if (file) { while (!file.endOfStream) { var text = file.readLine() // only read the lines with Chord= if (text.indexOf("Chord=") > -1) { // strip unnecessary text text = text.replace("Chord=", "") // split the delimited text and get the data data = text.split(',') var bar1 = data[0]; var beat = data[1]; var bar = Number(bar1) + 1 // push name to a reference array for the chord names chordNames.push (data[2]) // move the play cursor and paste a new event //var position = ((bar * 2) + 2) //var bpm = 140 var beat_per_measure = 4 var position = (bar * (((((beat_per_measure) / bpm) * 60)))) var beat = data[1] //if (beat > 1) {position = (position + (beat * .5))} if (beat > 1) {position = (position + (((((beat - 1) / bpm) * 60))))} cursor.setValue(position, true) // paste the new event cmd.interpretCommand("Edit", "Paste") } } file.close(); } // select and name all of the new chord events var chordSelector = Host.Objects.getObjectByUrl ('object://hostapp/DocumentManager/ActiveDocument/TrackList/CurrentChord/EventInfo/ChordSelector') .findParameter('chord') // select the first event cmd.interpretCommand('Navigation', 'First Event') // iterate the names array and name each event for (i = 0; i < chordNames.length; i++) { chordSelector.setValue(chordNames[i], true) cmd.interpretCommand('Navigation', 'Next Event') } context.editor.selection.showHideSuspended = false; cmd.interpretCommand("Transport", "Return to Zero") return Host.Results.kResultOk; } } function createInstance() { return new BiabPluginChords; } Last edited by MusoBob; 07-04-2019 at 01:33 AM. |
| | |
| | #19 |
| Human being with feelings Join Date: Sep 2014 Posts: 2,248 | @Lawrence thanks again for the help !!! This is all working now (will try and get it to work with a tempo map and time signature changes later) Code: function BiabPluginChords() { this.interfaces = [ Host.Interfaces.IEditTask ]; // --------------------------------------------------------------------- this.prepareEdit = function (context) { return Host.Results.kResultOk; } // --------------------------------------------------------------------- this.performEdit = function (context) { // set Cursor follows Edit Position Host.GUI.Commands.interpretCommand('Transport', 'Cursor follows Edit Position', false, Host.Attributes(["State", "1"])) // get the current tempo var bpm = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('tempo').string; // play cursor var cursor = Host.Objects.getObjectByUrl ('://hostapp/DocumentManager/ActiveDocument/Environment/TransportPanel') .findParameter('primaryTime'); // host command shortcut var cmd = Host.GUI.Commands; /////////////////////////////////////////////////////////////////////////////// ////////////////////// OPEN / READ BIAB TEXT FILE //////////////////////////// /////////////////////////////////////////////////////////////////////////////// var fileSelector = Host.Classes.createInstance("CCL:FileSelector"); var textType = {filename: ("Song.txt"),description: ("Song.txt"), extension: "txt", mimetype: "text"}; fileSelector.addFilter(textType); fileSelector.runOpen(); var path = fileSelector.getPath() // array to hold the chord names var chordNames = []; context.editor.selection.showHideSuspended = true; // cut the manually created event to the clipboard cmd.interpretCommand("Edit", "Cut") var file = Host.IO.openTextFile(path); if (file) { while (!file.endOfStream) { var text = file.readLine() if (text.indexOf("StyleTimeSig=") > -1 ) { if (text == 'StyleTimeSig=4') { var beat_per_measure1 = '4' } if (text == 'StyleTimeSig=3') { var beat_per_measure1 = '3' } } } } // read the file and paste events, and build the name array var file = Host.IO.openTextFile(path); if (file) { while (!file.endOfStream) { var text = file.readLine() // only read the lines with Chord= if (text.indexOf("Chord=") > -1) { // strip unnecessary text text = text.replace("Chord=", "") // split the delimited text and get the data data = text.split(',') var bar1 = data[0]; var beat = data[1]; var bar = Number(bar1) + 1 var beat_per_measure = Number(beat_per_measure1) // push name to a reference array for the chord names chordNames.push (data[2]) // move the play cursor and paste a new event //var beat_per_measure = 4 var position = (bar * (((((beat_per_measure) / bpm) * 60)))) var beat = data[1] //if (beat > 1) {position = (position + (beat * .5))} if (beat > 1) {position = (position + (((((beat - 1) / bpm) * 60))))} cursor.setValue(position, true) // paste the new event cmd.interpretCommand("Edit", "Paste") } } file.close(); } // select and name all of the new chord events var chordSelector = Host.Objects.getObjectByUrl ('object://hostapp/DocumentManager/ActiveDocument/TrackList/CurrentChord/EventInfo/ChordSelector') .findParameter('chord') // select the first event cmd.interpretCommand('Navigation', 'First Event') // iterate the names array and name each event for (i = 0; i < chordNames.length; i++) { chordSelector.setValue(chordNames[i], true) cmd.interpretCommand('Navigation', 'Next Event') } context.editor.selection.showHideSuspended = false; cmd.interpretCommand("Transport", "Return to Zero") //Host.GUI.alert(beat_per_measure) return Host.Results.kResultOk; } } function createInstance() { return new BiabPluginChords; } |
| | |
|
|
All times are GMT -7. The time now is 01:13 PM.
How Can I Move Markers With Tracks in Studio One?
Source: https://forum.cockos.com/showthread.php?t=222438
Posting Rules
0 Response to "How Can I Move Markers With Tracks in Studio One?"
Post a Comment