jam-cloud/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee

283 lines
10 KiB
CoffeeScript

context = window
logger = context.JK.logger
MIX_MODES = context.JK.MIX_MODES
rest = context.JK.Rest()
@MixerStore = Reflux.createStore(
{
METRO_SOUND_LOOKUP: {
0 : "BuiltIn",
1 : "SineWave",
2 : "Beep",
3 : "Click",
4 : "Kick",
5 : "Snare",
6 : "MetroFile"
}
metro: {tempo: 120, cricket: false, sound: "Beep" }
noAudioUsers : {}
checkingMissingPeers : {}
missingMixerPeers : {}
recheckTimeout : null
init: ->
# Register with the app store to get @app
this.listenTo(context.AppStore, this.onAppInit);
this.listenTo(context.SessionStore, this.onSessionChange)
this.listenTo(context.MixerActions.mute, this.onMute)
this.listenTo(context.MixerActions.faderChanged, this.onFaderChanged)
this.listenTo(context.MixerActions.initGain, this.onInitGain)
this.listenTo(context.MixerActions.initPan, this.onInitPan)
this.listenTo(context.MixerActions.panChanged, this.onPanChanged)
this.listenTo(context.MixerActions.mixersChanged, this.onMixersChanged)
this.listenTo(context.MixerActions.syncTracks, this.onSyncTracks)
this.listenTo(context.MixerActions.mixerModeChanged, this.onMixerModeChanged)
this.listenTo(context.MixerActions.loopChanged, this.onLoopChanged)
this.listenTo(context.MixerActions.openMetronome, this.onOpenMetronome)
this.listenTo(context.MixerActions.metronomeChanged, this.onMetronomeChanged)
this.listenTo(context.MixerActions.deadUserRemove, this.onDeadUserRemove)
this.listenTo(context.MixerActions.missingPeerMixer, this.onMissingPeerMixer)
context.JK.HandleVolumeChangeCallback2 = @handleVolumeChangeCallback
context.JK.HandleMetronomeCallback2 = @handleMetronomeCallback
context.JK.HandleBridgeCallback2 = @handleBridgeCallback
context.JK.HandleBackingTrackSelectedCallback2 = @handleBackingTrackSelectedCallback
#setInterval(@dumpVUStats, 5000)
dumpVUStats: () ->
@mixers.dumpVUStats() if @mixers?
issueChange: () ->
@trigger({session: @session, mixers: @mixers})
handleVolumeChangeCallback: (mixerId, isLeft, value, isMuted) ->
# TODO
# Visually update mixer
# There is no need to actually set the back-end mixer value as the
# back-end will already have updated the audio mixer directly prior to sending
# me this event. I simply need to visually show the new fader position.
# TODO: Use mixer's range
#faderValue = percentFromMixerValue(-80, 20, value);
#context.JK.FaderHelpers.setFaderValue(mixerId, faderValue);
#var $muteControl = $('[control="mute"][mixer-id="' + mixerId + '"]');
#_toggleVisualMuteControl($muteControl, isMuted);
logger.debug("volume change")
handleMetronomeCallback: (args) ->
logger.debug("MetronomeCallback: ", args)
@metro.tempo = args.bpm
@metro.cricket = args.cricket;
@metro.sound = @METRO_SOUND_LOOKUP[args.sound];
# This isn't actually there, so we rely on the metroSound as set from select on form:
# metroSound = args.sound
SessionActions.syncWithServer()
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
handleBridgeCallback: (vuData) ->
eventName = null
mixerId = null
value = null
vuInfo = null
for vuInfo in vuData
eventName = vuInfo[0];
vuVal = 0.0;
if eventName == "vu"
mixerId = vuInfo[1];
mode = vuInfo[2];
leftValue = vuInfo[3];
leftClipping = vuInfo[4];
rightValue = vuInfo[5];
rightClipping = vuInfo[6];
# TODO - no guarantee range will be -80 to 20. Get from the
# GetControlState for this mixer which returns min/max
# value is a DB value from -80 to 20. Convert to float from 0.0-1.0
@mixers.updateVU(mixerId, mode, (leftValue + 80) / 80, leftClipping, (rightValue + 80) / 80, rightClipping)
#@mixers.updateVU(mixerId + "_vur", (rightValue + 80) / 80, rightClipping)
handleBackingTrackSelectedCallback: () ->
logger.debug("backing track selected")
onAppInit: (@app) ->
@gearUtils = context.JK.GearUtilsInstance
@sessionUtils = context.JK.SessionUtils
context.jamClient.SetVURefreshRate(150)
context.jamClient.RegisterVolChangeCallBack("JK.HandleVolumeChangeCallback2")
context.jamClient.setMetronomeOpenCallback("JK.HandleMetronomeCallback2")
sessionEnded: () ->
@checkingMissingPeers = {}
@noAudioUsers = {}
@missingMixerPeers = {}
clearTimeout(@recheckTimeout) if @recheckTimeout?
onSessionChange: (session) ->
@sessionEnded() unless session.inSession()
@session = session
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
onMute: (mixers, muting) ->
mixers = [mixers] unless $.isArray(mixers)
for mixer in mixers
@mixers.mute(mixer.id, mixer.mode, muting);
# simulate a state change to cause a UI redraw
@issueChange()
onFaderChanged: (data, mixers, gainType) ->
@mixers.faderChanged(data, mixers, gainType)
@issueChange()
onPanChanged: (data, mixers, groupId) ->
@mixers.panChanged(data, mixers, groupId)
@issueChange()
onLoopChanged: (mixer, shouldLoop) ->
@mixers.loopChanged(mixer, shouldLoop)
onOpenMetronome: () ->
context.jamClient.SessionStopPlay()
context.jamClient.SessionOpenMetronome(@mixers.metro.tempo, @mixers.metro.sound, 1, 0)
onMetronomeChanged: (tempo, sound) ->
logger.debug("onMetronomeChanged", tempo, sound)
@metro.tempo = tempo
@metro.sound = sound
context.jamClient.SessionSetMetronome(@metro.tempo, @metro.sound, 1, 0);
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
onDeadUserRemove: (clientId) ->
return unless @session.inSession()
participant = @session.participantsEverSeen[clientId];
if participant?
logger.debug("todo :notify dead user")
# XXX TODO trigger some notification store
#app.notify({
# "title": ALERT_TYPES[type].title,
# "text": participant.user.name + " is no longer sending audio.",
# "icon_url": context.JK.resolveAvatarUrl(participant.user.photo_url)
#});
@noAudioUsers[clientId] = true
@issueChange()
onMissingPeerMixer: (clientId) ->
missingPeerAttempts = @missingMixerPeers[clientId]
# check for 5 tries (10 seconds if setTimeout is 2000ms)
if !missingPeerAttempts? || missingPeerAttempts < 5
@checkingMissingPeers[clientId] = true
@recheckTimeout = setTimeout(@recheckForMixers, 2000) unless @recheckTimeout?
else
logger.debug("ignoring missing peer recheck. missingPeerAttempts: #{missingPeerAttempts}")
recheckForMixers: () ->
# increment how many times we've checked for this particular peer
for clientId, meh of @checkingMissingPeers
missingPeerAttempts = @missingMixerPeers[clientId]
missingPeerAttempts = 0 unless missingPeerAttempts?
missingPeerAttempts++
@missingMixerPeers[clientId] = missingPeerAttempts
# reset the peers we are looking for
@checkingMissingPeers = {}
@recheckTimeout = null
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: recheckForMixers")
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
onInitGain: (mixer) ->
@mixers.initGain(mixer)
onInitPan: (mixer) ->
@mixers.initPan(mixer)
onMixersChanged: (type, text) ->
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: onMixersChanged")
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo())
@issueChange()
onMixerModeChanged: (mode) ->
if mode == MIX_MODES.MASTER
@app.layout.showDialog('session-master-mix-dialog') unless @app.layout.isDialogShowing('session-master-mix-dialog')
else
@app.layout.closeDialog('session-master-mix-dialog') if @app.layout.isDialogShowing('session-master-mix-dialog')
onSyncTracks: () ->
logger.debug("MixerStore: onSyncTracks")
unless @session.inSession()
logger.debug("dropping sync tracks because no longer in session")
return
allTracks = @mixers.getTrackInfo()
inputTracks = allTracks.userTracks;
backingTracks = allTracks.backingTracks;
metronomeTracks = allTracks.metronomeTracks;
# create a trackSync request based on backend data
syncTrackRequest = {}
syncTrackRequest.client_id = @app.clientId
syncTrackRequest.tracks = inputTracks
syncTrackRequest.backing_tracks = backingTracks
syncTrackRequest.metronome_open = metronomeTracks.length > 0
syncTrackRequest.id = @session.id()
rest.putTrackSyncChange(syncTrackRequest)
.fail((jqXHR)=>
if jqXHR.status != 404
@app.notify({
"title": "Can't Sync Local Tracks",
"text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
"icon_url": "/assets/content/icon_alert_big.png"
})
else
logger.debug("Unable to sync local tracks because session is gone.")
)
}
)