469 lines
16 KiB
CoffeeScript
469 lines
16 KiB
CoffeeScript
context = window
|
|
ConfigureTracksStore = @ConfigureTracksStore
|
|
@ConfigureLiveTracksDialog = React.createClass({
|
|
|
|
mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged"), Reflux.listenTo(@AppStore, "onAppInit")]
|
|
|
|
onConfigureTracksChanged:(configureTracks) ->
|
|
@setState({configureTracks: configureTracks})
|
|
|
|
onAppInit: (@app) ->
|
|
|
|
getInitialState: () ->
|
|
{configureTracks: null, midiInterface: null}
|
|
|
|
renderAudio: () ->
|
|
inputOneOptions = []
|
|
inputTwoOptions = []
|
|
|
|
defaultSelectionOne = `<option key="" value="">None</option>`
|
|
defaultSelectionTwo = `<option key="" value="">None</option>`
|
|
|
|
inputOneOptions.push(defaultSelectionOne)
|
|
inputTwoOptions.push(defaultSelectionTwo)
|
|
inputOneValue = ''
|
|
inputTwoValue = ''
|
|
selectedInstrument = ''
|
|
selectedVst = 'NONE'
|
|
|
|
|
|
instruments = []
|
|
instruments.push(`<option key="" value="">Select the instrument for this track</option>`)
|
|
for instrument in context.JK.server_to_client_instrument_alpha
|
|
instruments.push(`<option key={instrument.server_id} value={instrument.server_id}>{instrument.display}</option>`)
|
|
|
|
vsts = []
|
|
|
|
instrumentDisabled = true
|
|
vstDisabled = true
|
|
|
|
|
|
if @state.configureTracks?
|
|
|
|
if @state.configureTracks.scanningVsts
|
|
scan =
|
|
`<div className="vstScan">
|
|
<div className="spinner-small"></div><span>Scanning your system<br/>for VST & AU plug-ins...</span>
|
|
</div>`
|
|
|
|
selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id?
|
|
|
|
if @state.configureTracks.editingTrack.length == 1
|
|
input = @state.configureTracks.editingTrack[0]
|
|
if input.number == 0
|
|
inputOneValue = input.id
|
|
else
|
|
inputTwoValue = input.id
|
|
|
|
if @state.configureTracks.editingTrack.length > 1
|
|
inputOneValue = @state.configureTracks.editingTrack[0].id
|
|
inputTwoValue = @state.configureTracks.editingTrack[1].id
|
|
|
|
instrumentDisabled = @state.configureTracks.editingTrack.length == 0
|
|
vstDisabled = @state.configureTracks.editingTrack.length == 0 || @state.configureTracks.unscanned
|
|
|
|
if @state.configureTracks.unscanned
|
|
initialScan = `<p className="initial-scan">“If you want to use an audio plugin, click the <b>manage audio plugins</b> link above, and then click the <b>scan for new or updated plugins</b> link in the menu.</p>`
|
|
|
|
for input in @state.configureTracks.musicPorts.inputs
|
|
|
|
include = false
|
|
# we need to see that this input is unassigned, or one of the two selected
|
|
for unassignedInputs in @state.configureTracks.trackAssignments.inputs.unassigned
|
|
if unassignedInputs.id == input.id
|
|
include = true
|
|
break
|
|
|
|
if !include
|
|
# not see if it's the currently edited track
|
|
for currentInput in @state.configureTracks.editingTrack
|
|
if currentInput.id == input.id
|
|
include = true
|
|
|
|
if include
|
|
item = `<option key={input.id} value={input.id}>{input.name}</option>`
|
|
inputOneOptions.push(item)
|
|
inputTwoOptions.push(item)
|
|
|
|
|
|
for plugin in @state.configureTracks.vstPluginList.vsts
|
|
if plugin.category == 'NONE'
|
|
vsts.push(`<option key={plugin.file} value={plugin.file}>No VST/AU plugin selected</option>`)
|
|
else if plugin.isInstrument == false
|
|
vsts.push(`<option key={plugin.file} value={plugin.file}>{plugin.name} by {plugin.manuf}</option>`)
|
|
|
|
if @state.configureTracks.editingTrack.vst?
|
|
vstAssignedThisTrack = true
|
|
selectedVst = @state.configureTracks.editingTrack.vst.file
|
|
|
|
vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack})
|
|
`<div className="audio">
|
|
<div className="audio-input-ports">
|
|
<h3>Audio Input Ports</h3>
|
|
<p>Select one or two inputs ports to assign to this track. Note that if you assign a single input port, the app will automatically duplicate this port into a stereo track.</p>
|
|
<select className="input-one input-selectors" name="input-one" onChange={this.inputChanged} value={inputOneValue}>
|
|
{inputOneOptions}
|
|
</select>
|
|
<select className="input-two input-selectors" name="input-two" onChange={this.inputChanged} value={inputTwoValue}>
|
|
{inputTwoOptions}
|
|
</select>
|
|
</div>
|
|
<div className="instrument-selection">
|
|
<h3>Instrument</h3>
|
|
<select className="instrument-pick" name="instrument" onChange={() => {this.instrumentSelected()}} value={selectedInstrument} disabled={instrumentDisabled}>
|
|
{instruments}
|
|
</select>
|
|
</div>
|
|
<div className="audio-effects">
|
|
<h3>Audio Effects (optional)</h3>
|
|
<select className="vsts" name="vsts" onChange={this.vstsChanged} value={selectedVst} disabled={vstDisabled}>
|
|
{vsts}
|
|
</select>
|
|
<a className="manage-audio-plugins" onClick={this.manageAudioPlugins}>manage audio plugins <div className="down-arrow"></div></a>
|
|
<div className="settings-holder">
|
|
<a onClick={this.vstSettings} className={vstSettingBtnClasses}>SETTINGS . . .</a>
|
|
</div>
|
|
{initialScan}
|
|
{scan}
|
|
</div>
|
|
</div>`
|
|
|
|
renderMidi: () ->
|
|
midiInterfaces = []
|
|
midiInterfaces.push(`<option key="" value="">Select a MIDI interface</option>`)
|
|
midiInstruments = []
|
|
|
|
instruments = []
|
|
for instrument in context.JK.server_to_client_instrument_alpha
|
|
instruments.push(`<option key={instrument.server_id} value={instrument.server_id}>{instrument.display}</option>`)
|
|
|
|
selectedMidiInterface = ''
|
|
selectedInstrument = context.JK.client_to_server_instrument_map[50].server_id # default to electric guitar
|
|
selectedMidiInstrument = ''
|
|
|
|
instrumentDisabled = true
|
|
midiInstrumentDisabled = true
|
|
vstAssignedThisTrack = false
|
|
|
|
if @state.configureTracks?
|
|
|
|
if @state.configureTracks.scanningVsts
|
|
scan =
|
|
`<div className="vstScan">
|
|
<div className="spinner-small"></div><span>Scanning your system<br/>for VST & AU plug-ins...</span>
|
|
</div>`
|
|
|
|
if @state.configureTracks.unscanned
|
|
initialScan = `<p className="initial-scan">“If you want to use a midi instrument, click the <b>manage audio plugins</b> link above, and then click the <b>scan for new or updated plugins</b> link in the menu.</p>`
|
|
|
|
logger.debug("current midi device: " + @state.configureTracks.editingTrack.midiDeviceIndex)
|
|
selectedMidiInterface = @state.midiInterface || @state.configureTracks.editingTrack.midiDeviceIndex
|
|
|
|
selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id?
|
|
instrumentDisabled = !@state.midiInterface? || !selectedMidiInterface?
|
|
midiInstrumentDisabled = @state.configureTracks.unscanned
|
|
instrumentDisabled = false
|
|
|
|
if @state.configureTracks.editingTrack.vst?
|
|
vstAssignedThisTrack = true
|
|
selectedMidiInstrument = @state.configureTracks.editingTrack.vst.file
|
|
vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack})
|
|
|
|
for midiDevice in @state.configureTracks.attachedMidiDevices.midiDevices
|
|
midiInterfaces.push(`<option value={midiDevice.deviceIndex}>{midiDevice.deviceName}</option>`)
|
|
|
|
for plugin in @state.configureTracks.vstPluginList.vsts
|
|
if plugin.isInstrument == true
|
|
midiInstruments.push(`<option key={plugin.file} value={plugin.file}>{plugin.name} by {plugin.manuf}</option>`)
|
|
else if plugin.category == 'NONE'
|
|
midiInstruments.push(`<option key={plugin.file} value={plugin.file}>Select a VST or AU instrument</option>`)
|
|
|
|
`<div className="midi">
|
|
<div className="midi-interface">
|
|
<h3>MIDI Interface</h3>
|
|
<select className="midi-select" name="midi-select" onChange={this.midiInterfaceChanged} value={selectedMidiInterface} disabled={midiInstrumentDisabled} >
|
|
{midiInterfaces}
|
|
</select>
|
|
<a className="scan-midi" onClick={this.scanMidi}>scan for connected MIDI interfaces</a>
|
|
</div>
|
|
<div className="instrument-selection">
|
|
<h3>Instrument</h3>
|
|
<select className="instrument-pick" name="instrument" onChange={async () => { await this.instrumentSelected()}} value={selectedInstrument} disabled={instrumentDisabled}>
|
|
{instruments}
|
|
</select>
|
|
</div>
|
|
<div className="midi-instrument">
|
|
<h3>MIDI Instrument (VST or AU Plugin)</h3>
|
|
<select className="vsts" name="midi-instrument" onChange={this.vstsChanged} value={selectedMidiInstrument} disabled={midiInstrumentDisabled}>
|
|
{midiInstruments}
|
|
</select>
|
|
<a className="manage-audio-plugins" onClick={this.manageAudioPlugins}>manage audio plugins <div className="down-arrow"></div></a>
|
|
<div className="settings-holder">
|
|
<a onClick={this.vstSettings} className={vstSettingBtnClasses}>SETTING . . .</a>
|
|
</div>
|
|
{initialScan}
|
|
{scan}
|
|
</div>
|
|
</div>`
|
|
|
|
render: () ->
|
|
|
|
action = 'ADD TRACK'
|
|
header = 'add track'
|
|
|
|
isAudio = !@state.configureTracks? || @state.configureTracks.trackType == 'audio'
|
|
isMidi = !isAudio
|
|
|
|
if isAudio
|
|
activeElement = @renderAudio()
|
|
scanHelpRight = `<a className="dont-see-plugin right-side" onClick={this.dontSeePlugin}>Don't see your plug-in in the list above?</a>`
|
|
else
|
|
activeElement = @renderMidi()
|
|
scanHelpLeft = `<a className="dont-see-plugin left-side" onClick={this.dontSeePlugin}>Don't see your plug-in in the list above?</a>`
|
|
|
|
|
|
if !@state.configureTracks?.newTrack
|
|
action = 'CLOSE'
|
|
header = 'update track'
|
|
else
|
|
cancelBtn = `<a onClick={this.onCancel} className="button-grey">CANCEL</a>`
|
|
|
|
|
|
`<div>
|
|
<div className="content-head">
|
|
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
|
<h1>{header}</h1>
|
|
</div>
|
|
<div className="dialog-inner">
|
|
|
|
{activeElement}
|
|
|
|
<div className="actions">
|
|
{scanHelpLeft}
|
|
{cancelBtn}
|
|
<a onClick={this.doClose} className="button-orange">{action}</a>
|
|
{scanHelpRight}
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
|
|
inputChanged: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select1 = $root.find('.input-one')
|
|
$select2 = $root.find('.input-two')
|
|
|
|
audioInput1 = $select1.val()
|
|
audioInput2 = $select2.val()
|
|
|
|
if audioInput1 == ''
|
|
audioInput1 = null
|
|
|
|
if audioInput2 == ''
|
|
audioInput2 = null
|
|
|
|
logger.debug("ConfigureLiveTracksDialog: ", audioInput1, audioInput2)
|
|
if audioInput1? && audioInput1 == audioInput2
|
|
e.preventDefault()
|
|
# TODO: tell user they can't do this
|
|
return
|
|
|
|
ConfigureTracksActions.associateInputsWithTrack(audioInput1, audioInput2)
|
|
|
|
|
|
vstsChanged: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select = $root.find('select.vsts')
|
|
vstSelected = $select.val()
|
|
#if vstSelected != 'NONE'
|
|
vstSelected = {file: vstSelected}
|
|
|
|
if @state.configureTracks?.trackType == 'midi'
|
|
@updateMidiAssociations()
|
|
else
|
|
logger.debug("associating vst", vstSelected)
|
|
ConfigureTracksActions.associateVSTWithTrack(vstSelected)
|
|
|
|
|
|
@setState({midiInterface: null})
|
|
|
|
# instrumentSelected: (e) ->
|
|
# $root = $(@getDOMNode())
|
|
# $select = $root.find('.instrument-pick')
|
|
|
|
# instrumentId = $select.val()
|
|
# ConfigureTracksActions.associateInstrumentWithTrack(instrumentId)
|
|
|
|
instrumentSelected: `async function(e) {
|
|
const $root = $(this.getDOMNode());
|
|
const $select = $root.find('.instrument-pick');
|
|
|
|
const instrumentId = $select.val();
|
|
ConfigureTracksActions.associateInstrumentWithTrack.trigger(instrumentId);
|
|
}`
|
|
|
|
|
|
doClose: (e) ->
|
|
e.preventDefault()
|
|
# check that instrument is selected
|
|
|
|
$root = $(@getDOMNode())
|
|
$instrument = $root.find('.instrument-pick')
|
|
|
|
instrumentId = $instrument.val()
|
|
|
|
$select1 = $root.find('.input-one')
|
|
$select2 = $root.find('.input-two')
|
|
|
|
audioInput1 = $select1.val()
|
|
audioInput2 = $select2.val()
|
|
|
|
if audioInput1 == ''
|
|
audioInput1 = null
|
|
|
|
if audioInput2 == ''
|
|
audioInput2 = null
|
|
|
|
if audioInput1 == null && audioInput2 == null
|
|
context.JK.Banner.showAlert("At least one input must be specified.")
|
|
return
|
|
|
|
if instrumentId == null || instrumentId == ''
|
|
context.JK.Banner.showAlert("Please select an instrument.")
|
|
return
|
|
|
|
@app.layout.closeDialog('configure-live-tracks-dialog', false)
|
|
|
|
onCancel: (e) ->
|
|
|
|
ConfigureTracksActions.cancelEdit()
|
|
|
|
@app.layout.closeDialog('configure-live-tracks-dialog', true)
|
|
|
|
vstSettings: (e) ->
|
|
e.preventDefault()
|
|
ConfigureTracksActions.showVstSettings()
|
|
|
|
|
|
componentDidMount: () ->
|
|
$root = $(@getDOMNode())
|
|
|
|
componentWillUpdate: () ->
|
|
$root = $(@getDOMNode())
|
|
|
|
# componentDidUpdate: () ->
|
|
# $root = $(@getDOMNode())
|
|
|
|
# $manageAudioPlugins = $root.find('.manage-audio-plugins')
|
|
|
|
# unless $manageAudioPlugins.data('initialized')
|
|
# $manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, @vstOperation).data('initialized', true)
|
|
|
|
# if true # easyDropdown support
|
|
|
|
# context.JK.dropdown($root.find('select'))
|
|
# $root.find('select.input-selectors').unbind('change').change(@inputChanged)
|
|
# $root.find('select.instrument-pick').unbind('change').change(@instrumentSelected)
|
|
# $root.find('select.vsts').unbind('change').change(@vstsChanged)
|
|
|
|
componentDidUpdate: `async function() {
|
|
const $root = $(this.getDOMNode());
|
|
|
|
const $manageAudioPlugins = $root.find('.manage-audio-plugins');
|
|
|
|
if (!$manageAudioPlugins.data('initialized')) {
|
|
$manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, this.vstOperation).data('initialized', true);
|
|
}
|
|
|
|
if (true) { // easyDropdown support
|
|
|
|
context.JK.dropdown($root.find('select'));
|
|
$root.find('select.input-selectors').unbind('change').change(this.inputChanged);
|
|
$root.find('select.instrument-pick').unbind('change').change(this.instrumentSelected);
|
|
return $root.find('select.vsts').unbind('change').change(this.vstsChanged);
|
|
}
|
|
}`
|
|
|
|
trackTypeChanged: (event) ->
|
|
|
|
if @ignoreICheck
|
|
logger.debug("ignoring track type changed")
|
|
return
|
|
|
|
$checkedType = $(event.target);
|
|
value = $checkedType.val()
|
|
logger.debug("trackTypeChanged: " + value, $checkedType)
|
|
ConfigureTracksActions.desiredTrackType(value)
|
|
#@setState({trackType: value})
|
|
|
|
initialScan: (e) ->
|
|
e.preventDefault()
|
|
ConfigureTracksActions.vstScan()
|
|
|
|
dontSeePlugin: (e) ->
|
|
e.preventDefault()
|
|
context.JK.popExternalLink('https://jamkazam.desk.com/customer/portal/articles/2252557-adding-a-scan-folder-path-for-plugins')
|
|
|
|
vstOperation: (e, data) ->
|
|
|
|
if data.vstOperation == 'scan'
|
|
ConfigureTracksActions.vstScan()
|
|
else if data.vstOperation == 'clear'
|
|
ConfigureTracksActions.clearVsts()
|
|
else if data.vstOperation == 'manage'
|
|
ConfigureTracksActions.manageVsts()
|
|
|
|
manageAudioPlugins: (e) ->
|
|
e.preventDefault()
|
|
|
|
$root = $(@getDOMNode())
|
|
$manageAudioPlugins = $root.find('.manage-audio-plugins')
|
|
$manageAudioPlugins.btOn()
|
|
|
|
scanMidi: (e) ->
|
|
e.preventDefault()
|
|
|
|
ConfigureTracksActions.midiScan()
|
|
|
|
|
|
midiInterfaceChanged: (e) ->
|
|
|
|
@updateMidiAssociations()
|
|
|
|
updateMidiAssociations: (e) ->
|
|
$root = $(@getDOMNode())
|
|
$select = $root.find('select.midi-select')
|
|
midiInterface = $select.val()
|
|
|
|
$select = $root.find('select.vsts')
|
|
vstSelected = $select.val()
|
|
|
|
logger.debug("updateMidiAssocations", vstSelected, midiInterface)
|
|
#if vstSelected != 'NONE'
|
|
vstSelected = {file: vstSelected}
|
|
#else
|
|
# vstSelected = null
|
|
|
|
if midiInterface == ''
|
|
midiInterface = null
|
|
|
|
midi = @state.midiInterface || midiInterface
|
|
|
|
if vstSelected? && midi?
|
|
logger.debug("updating midi:#{midi} & vst: #{vstSelected.file}")
|
|
|
|
ConfigureTracksActions.associateVSTWithTrack(vstSelected)
|
|
setTimeout((() =>
|
|
ConfigureTracksActions.associateMIDIWithTrack(midi)
|
|
), 250)
|
|
|
|
else if midi?
|
|
logger.debug("updating midi:#{midiInterface}")
|
|
ConfigureTracksActions.associateMIDIWithTrack(midiInterface)
|
|
else
|
|
logger.debug("unassociating midi:#{midiInterface}")
|
|
ConfigureTracksActions.associateMIDIWithTrack(null)
|
|
|
|
@setState({midiInterface: midiInterface})
|
|
|
|
})
|