Double Range Selection length

Is there a way of quickly double the length of your range selection?
image

I understand I can just do the math and enter 2.728 in the above Info Line, but I’m hoping there might be a quicker way.

Hi,

I’m not aware of any. Sorry.

Just for the fun of it and since I know you’re into MIDI remote scripting, I’ve prepared a snippet that seems to works here (when our primary time frame is set to Bars+Beats).

The idea is to take advantage of the setTime method, get our left and right locators, calculate the range duration, set our cursor to the new right point (our right locator + duration) and then call the Edit→Right Selection Side to Cursor command. In the end, we restore our cursor to its initial position.

var midiremote_api=require('midiremote_api_v1')
var deviceDriver = midiremote_api.makeDeviceDriver('Test Devices', 'Extend Range To Double', 'Someone')

var midiInput = deviceDriver.mPorts.makeMidiInput()
var midiOutput = deviceDriver.mPorts.makeMidiOutput()

deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
    .expectInputNameContains('a port')
    .expectOutputNameContains('an output port')

var surface=deviceDriver.mSurface
var button=surface.makeButton(0,0,1,1) //used to trigger the duplicate
button.mSurfaceValue.mMidiBinding
    .setInputPort(midiInput)
    .bindToControlChange(0,0x20)

var customSetRangeEndToRightLocator=surface.makeCustomValueVariable("customSetRangeEndToRightLocator")

var customRestoreCursorVar=surface.makeCustomValueVariable("restoreCursor")

var customTimer=surface.makeCustomValueVariable("customTimer")


var page=deviceDriver.mMapping.makePage("page")

page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mTransportLocator.mOnChange=function(activeDevice,activeMapping,locator,type){
    
    activeDevice.setState("loc",locator)
    activeDevice.setState("locTimeFormat",type)

    var cursorState=activeDevice.getState("cursorState")
    
    if(cursorState=="1"){

        customTimer.setProcessValue(activeDevice,10)

    }

}

page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mCycleLocatorLeft.mOnChange=function(activeDevice,activeMapping,locator,type){

    activeDevice.setState("locLeft",locator)
    activeDevice.setState("locLeftTimeFormat",type)

}

page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mCycleLocatorRight.mOnChange=function(activeDevice,activeMapping,locator,type){

    activeDevice.setState("locRight",locator)
    activeDevice.setState("locRightTimeFormat",type)

}


customTimer.mOnProcessValueChange=function(activeDevice,value,diff){
    
    value-- 
    
    if(value>0){

        customTimer.setProcessValue(activeDevice,value)

    } else {

        var cursorState=activeDevice.getState("cursorState")

        if(cursorState=="1"){

            customSetRangeEndToRightLocator.setProcessValue(activeDevice,1)

        } else if (cursorState=="2"){

            customRestoreCursorVar.setProcessValue(activeDevice,1)

        }

    }

}

var dummyDoubleTheRangeVar=page.mCustom.makeHostValueVariable("doubleTheRangeVar")

var dummyRestoreCursorVar=page.mCustom.makeHostValueVariable("restoreCursorVar")

page.makeValueBinding(button.mSurfaceValue,dummyDoubleTheRangeVar).mOnValueChange=function(activeDevice,activeMapping,value){

    var locLeft=parseToFrames(activeDevice,"Left")
    var locRight=parseToFrames(activeDevice,"Right")

    if(locLeft==locRight){

        return 

    }
    
    var length=locRight-locLeft
    var finalLocRightInFrames=locRight+length 
    var finalLocRight=convertFramesToBarsAndBeats(finalLocRightInFrames)

    activeDevice.setState("cursorState","1")
    activeDevice.setState("restoreCursorTo",activeDevice.getState("loc"))

    page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mTransportLocator.setTime(activeMapping,finalLocRight)

}

page.makeValueBinding(customRestoreCursorVar,dummyRestoreCursorVar).mOnValueChange=function(activeDevice,activeMapping,value,diff){
    
    if(value==1){
        
        var cursorState=activeDevice.getState("cursorState")
        
        if(cursorState=="2"){
        
            activeDevice.setState("cursorState","")
            customSetRangeEndToRightLocator.setProcessValue(activeDevice,0)
            
            var initCursor=activeDevice.getState("restoreCursorTo")
            
            page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mTransportLocator.setTime(activeMapping,initCursor)

        }
    
        customRestoreCursorVar.setProcessValue(activeDevice,0)
    }
    
}

page.makeCommandBinding(customSetRangeEndToRightLocator,'Edit', 'Right Selection Side to Cursor').mOnValueChange=function(activeDevice,activeMapping,value,diff){

    var cursorState=activeDevice.getState("cursorState")

    if(cursorState=="1"){

        activeDevice.setState("cursorState","2")
        customTimer.setProcessValue(activeDevice,10)
    
    }
    
}

function parseToFrames(activeDevice,locator){

    var locatorValue=activeDevice.getState("loc"+locator)
    var timeFormat=activeDevice.getState("loc"+locator+"TimeFormat")
    
    switch(timeFormat){

        case "Bars+Beats":

            var newLocator=convertBarsAndBeatsToFrames(locatorValue)
            break 
    
            //we have to add here the other cases
    
    }

    return newLocator

}

function convertBarsAndBeatsToFrames(barsAndBeats){
    
    var stripped=barsAndBeats.replace(new RegExp(" ", 'g'), "")
    var arr=stripped.split(".")
    var bars=1*arr[0]
    var quarters=1*arr[1]
    var sixteenths=1*arr[2]
    var frames0=1*arr[3]
    var frames=(16*bars-16+4*quarters-4+1*sixteenths-1)*120+frames0
    
    return frames 
    
}

function convertFramesToBarsAndBeats(frames){
    
    var newFrames=frames%120
    var barsAndBeats=Math.floor(frames/120)
    
    var bars0=Math.floor(barsAndBeats/16)
    var quarters0=Math.floor((barsAndBeats-16*bars0)/4)
    var beats0=barsAndBeats-16*bars0-4*quarters0
    
    return ""+(bars0+1)+"."+(quarters0+1)+"."+(beats0+1)+"."+newFrames

}
2 Likes

Wow! That is one helluva workaround!
Thank you kindly for taking the time to come up with this.
I will have to put this in my back pocket since I’m still on Cubase 12 and I believe “setTime” is only present in the latest version of the API. I don’t believe that is available to C12 users, although I haven’t actually investigated that.

1 Like

It’s available in CB12 as well, no problem.

1 Like

I love it. how can i check this out? i didn’t;t think you could directly interact with cubase in this way? unless using the developers SDK and the like which you probably are.

Hi, you may want to try the snippet I posted, by inserting it to your script.
The left/right locators and the cursor position are exposed to the MIDI Remote API, and at the same time, there is the method setTime included. So, yeah, some things can be done using a combination of these.

wen you say inserting into my script… What script is that? again, i wows under the impression we couldn’t run scripts or batch files in cubase unless you are pretty full on into developing and SDK’s etc.

All my automation is done through the logistical editor (midi, project, input and transform) and keyboard maestro pretty much. I also make dummy controllers that do specific things until im sick off it which is usually half way through programming it :slight_smile:

Hi Jake, I’m talking about the MIDI Remote API scripting.