(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.FakeJamClient = function (app, p2pMessageFactory) { var ChannelGroupIds = context.JK.ChannelGroupIds var logger = context.JK.logger; logger.info("*** Fake JamClient instance initialized. ***"); // Change this to false if you want to see FTUE with fake jam client var ftueStatus = true; var eventCallbackName = ''; var alertCallbackName = ''; var eventCallbackRate = 1000; var vuValue = -70; var vuChange = 10; var callbackTimer = null; var _mix = -30; var device_id = -1; var latencyCallback = null; var frameSize = 2.5; var fakeJamClientRecordings = null; var p2pCallbacks = null; var videoShared = false; var metronomeActive = false; var metronomeBPM = false; var metronomeSound = false; var metronomeMeter = 0; var backingTrackPath = ""; var backingTrackLoop = false; var simulateNoInputs = false; function dbg(msg) { logger.debug('FakeJamClient: ' + msg); } // Bummer that javascript doesn't have much in the way of reflection. // arguments.callee.name would probably do what we want, but it's deprecated // and not allowed when using "strict" // (Wishing I could write a single function which debug logs the name of the // current function and a JSON stringify of the arguments). function getClientParentChildRole() { // 0 = client // 1 = parent return 1; } function getParentClientId() { return null; } function applySubscriptionPolicy() { } function OpenSystemBrowser(href) { dbg("OpenSystemBrowser('" + href + "')"); context.window.open(href); } function RestartApplication() { } function ShutdownApplication() { } function FTUEPageEnter() { } function FTUEPageLeave() { } function FTUECancel() { } function FTUEGetMusicProfileName() { if (simulateNoInputs) { return "System Default (Playback Only)" } else { return "FTUEAttempt-1" } } function FTUESetMusicProfileName() { } function FTUESetPreferredMixerSampleRate() { } function FTUESetPreferredOutputSampleRate() { } function FTUESetPreferredChatSampleRate() { } function FTUEgetInputDeviceSampleRate() { return 44100; } function FTUEgetOutputDeviceSampleRate() { return 44100; } function FTUESelectVideoCaptureDevice(device, settings) { return true; } function FTUESetVideoEncodeResolution(resolution) { } function testVideoRender() { } function FTUEGetVideoCaptureDeviceNames() { return {"xy323ss": "Built-in Webcam HD"} } function FTUECurrentSelectedVideoDevice() { //return {} return {"xy323ss": "Built-in Webcam HD"} } function FTUEGetAvailableEncodeVideoResolutions() { return { 1: "CIF (352X288)", 2: "VGA (640X480)", 3: "4CIF (704X576)", 4: "1/2WHD (640X360)", 5: "WHD (1280X720)", 6: "FHD (1920x1080)" } } function FTUEGetVideoCaptureDeviceCapabilities() { return {} } function FTUESetSendFrameRates(fps) { } function FTUEGetSendFrameRates() { return {20: 20, 24: 24, 30: 30} } function GetCurrentVideoResolution() { return 3; } function GetCurrentVideoFrameRate() { return 30; } function GetSampleRate() { return 48; } function FTUESetVideoShareEnable() { } function FTUEGetVideoShareEnable() { return true; } function isSessVideoShared() { return videoShared; } function SessStopVideoSharing() { videoShared = false; } function SessStartVideoSharing(bitrate) { if (!bitrate || typeof(bitrate) == "undefined") { bitrate = 0 } videoShared = true; } function IsVstLoaded() { return false; } function hasVstAssignment() { return false; } function FTUEGetInputLatency() { dbg("FTUEGetInputLatency"); return 2; } function FTUESetInputLatency(latency) { dbg("FTUESetInputLatency:" + latency); } function FTUEGetOutputLatency() { dbg("FTUEGetOutputLatency"); return 2; } function FTUESetOutputLatency(latency) { dbg("FTUESetOutputLatency:" + latency); } function FTUEGetVolumeRanges() { dbg("FTUEGetVolumeRanges"); return { input_maximum: 20, input_minimum: -80, output_maximum: 20, output_minimum: -80 }; } function FTUEHasControlPanel() { dbg("FTUEHasControlPanel"); return true; } function FTUEGetFrameSize(newSize) { dbg("FTUEGetFrameSize"); return frameSize; } function FTUESetFrameSize(newSize) { dbg("FTUESetFrameSize:" + newSize); // one of 2.5, 5 or 10 frameSize = newSize; } function FTUEOpenControlPanel() { dbg("FTUEOpenControlPanel"); context.alert("Simulated ASIO Dialog"); } function FTUEInit() { dbg("FTUEInit"); } function FTUERefreshDevices() { dbg("FTUERefreshDevices()"); } function FTUESave(b) { dbg("FTUESave(" + b + ")"); return {}; } function FTUEGetStatus() { return ftueStatus; } function FTUESetStatus(b) { ftueStatus = b; } function FTUESetMusicDevice(id) { dbg("FTUESetMusicDevice"); } function FTUEGetAudioDevices() { return { "devices": [{ "display_name": "Built-in", "guid": "Built-in", "input_count": 1, "name": "Built-in", "output_count": 1, "port_audio_name": "Built-in" }, { "display_name": "JamKazam Virtual Monitor", "guid": "JamKazam Virtual Monitor", "input_count": 0, "name": "JamKazam Virtual Monitor", "output_count": 1, "port_audio_name": "JamKazam Virtual Monitor" }] } } function FTUEGetDevices() { dbg('FTUEGetMusicDevices'); return { "ASIO4ALL v2": "ASIO4ALL v2 - ASIO", "M-Audio FW ASIO": "M-AUDIO FW ASIO - ASIO" }; } function FTUEGetMusicInputs() { dbg('FTUEGetMusicInputs'); return { "i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1": "Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2" }; } function FTUEGetMusicOutputs() { dbg('FTUEGetMusicOutputs'); return { "o~11~Multichannel (FWAPMulti)~0^o~11~Multichannel (FWAPMulti)~1": "Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2" }; } function FTUEGetChatInputs() { dbg('FTUEGetChatInputs'); return { "i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1": "Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2" }; } function FTUEGetChannels() { return { "inputs": [ { "assignment": 1, "chat": false, "device_id": "Built-in Microph", "device_type": 5, "id": "i~5~Built-in Microph~0~0~Built-in", "name": "Built-in Microph - Left", "number": 0 }, { "assignment": 0, "chat": false, "device_id": "Built-in Microph", "device_type": 5, "id": "i~5~Built-in Microph~1~0~Built-in", "name": "Built-in Microph - Right", "number": 1 } ], "outputs": [ { "assignment": -1, "chat": false, "device_id": "Built-in Output", "device_type": 5, "id": "o~5~Built-in Output~0~0~Built-in", "name": "Built-in Output - Left", "number": 0 }, { "assignment": -1, "chat": false, "device_id": "Built-in Output", "device_type": 5, "id": "o~5~Built-in Output~1~0~Built-in", "name": "Built-in Output - Right", "number": 1 } ] }; } function FTUEClearChannelAssignments() { } function FTUEClearChatInput() { } function FTUEGetAudioDevices() { return { "devices": [ { "display_name": "Built-in", "guid": "Built-in", "input_count": 1, "name": "Built-in", "output_count": 1, "port_audio_name": "Built-in" }, { "display_name": "JamKazam Virtual Monitor", "guid": "JamKazam Virtual Monitor", "input_count": 0, "name": "JamKazam Virtual Monitor", "output_count": 1, "port_audio_name": "JamKazam Virtual Monitor" } ] }; } function FTUEStartIoPerfTest() { } function FTUEGetIoPerfData() { return { "in_var": 0.15, "out_var": 0.25, "in_median": 399.9, "out_median": 400.3, "in_target": 400, "out_target": 400 }; } function FTUESetInputMusicDevice() { } function FTUESetOutputMusicDevice() { } function FTUEGetInputMusicDevice() { return 'Built-in'; } function FTUEGetOutputMusicDevice() { return 'Built-in'; } function FTUESetMusicInput() { dbg('FTUESetMusicInput'); } function FTUESetChatInput() { dbg('FTUESetChatInput'); } function FTUESetMusicOutput() { dbg('FTUESetMusicOutput'); } function FTUEGetInputVolume() { dbg('FTUEGetInputVolume'); return -60; } function FTUESetInputVolume() { dbg('FTUESetInputVolume'); } function FTUEGetOutputVolume() { dbg('FTUEGetOutputVolume'); return -40; } function FTUESetOutputVolume() { dbg('FTUESetOutputVolume'); } function FTUEGetChatInputVolume() { dbg('FTUEGetChatInputVolume'); return -10; } function FTUESetChatInputVolume() { dbg('FTUESetChatInputVolume'); } function FTUERegisterVUCallbacks() { dbg('FTUERegisterVUCallbacks'); } function FTUERegisterLatencyCallback(functionName) { dbg('FTUERegisterLatencyCallback'); latencyCallback = functionName; } function FTUEStartLatency() { function cb() { // Change 4192 to modify latency MS results (in microseconds) eval(latencyCallback + "(10.0)"); } context.setTimeout(cb, 1000); } function FTUEGetExpectedLatency() { return {latencyknown: true, latency: 5} } function FTUEGetGoodConfigurationList() { return ['default']; } function FTUEGetAllAudioConfigurations() { return ['default']; } function FTUEGetGoodAudioConfigurations() { return ['default']; } function FTUEGetConfigurationDevice() { return 'Good Device'; } function FTUELoadAudioConfiguration() { return true; } function FTUEIsMusicDeviceWDM() { return false; } function FTUECreateUpdatePlayBackProfile() { return true; } function RegisterVolChangeCallBack(functionName) { dbg('RegisterVolChangeCallBack'); } function GetOS() { return 100000000; } function GetOSAsString() { //return "Win32"; return "MacOSX"; } function LatencyUpdated(map) { dbg('LatencyUpdated:' + JSON.stringify(map)); } function LeaveSession(map) { dbg('LeaveSession:' + JSON.stringify(map)); } // this is not a real bridge method; purely used by the fake jam client function RegisterP2PMessageCallbacks(callbacks) { p2pCallbacks = callbacks; } function P2PMessageReceived(from, payload) { dbg('P2PMessageReceived'); // this function is different in that the payload is a JSON ready string; // whereas a real p2p message is base64 encoded binary packaged data try { payload = JSON.parse(payload); } catch (e) { logger.warn("unable to parse payload as JSON from client %o, %o, %o", from, e, payload); } var callback = p2pCallbacks[payload.type]; if (callback) { callback(from, payload); } } function JoinSession(sessionId) { dbg('JoinSession:' + sessionId); } function ParticipantLeft(session, participant) { dbg('ParticipantLeft:' + JSON.stringify(session) + ',' + JSON.stringify(participant)); } function ParticipantJoined(session, participant) { dbg('ParticipantJoined:' + JSON.stringify(session) + ',' + JSON.stringify(participant)); } function RecordTestBegin() { dbg('RecordTestBegin'); } function RecordTestEnd() { dbg('RecordTestBegin'); } function RecordTestPlayback() { dbg('RecordTestBegin'); } function SendP2PMessage(s1, s2) { dbg('SendP2PMessage:' + s1 + ',' + s2); } function SetASIOEnabled(i1, i2, i3, i4, i5, i6) { dbg('SetASIOEnabled(' + i1 + ',' + i2 + ',' + i3 + ',' + i4 + ',' + i5 + ',' + i6 + ')'); } function SignalLatencyUpdated(client) { dbg('SignalLatencyUpdated:' + JSON.stringify(client)); } function SignalSendP2PMessage(s1, ba) { dbg('SignalSendP2PMessage:' + JSON.stringify(arguments)); } function StartPlayTest(s) { dbg('StartPlayTest' + JSON.stringify(arguments)); } function StartRecordTest(s) { dbg('StartRecordTest' + JSON.stringify(arguments)); } function StartRecording(recordingId, groupedClientTracks) { dbg('StartRecording'); fakeJamClientRecordings.StartRecording(recordingId, groupedClientTracks); } function StopPlayTest() { dbg('StopPlayTest'); } function StopRecording(recordingId, groupedTracks, errorReason, detail) { dbg('StopRecording'); fakeJamClientRecordings.StopRecording(recordingId, groupedTracks, errorReason, detail); } function AbortRecording(recordingId, errorReason, errorDetail) { dbg('AbortRecording'); fakeJamClientRecordings.AbortRecording(recordingId, errorReason, errorDetail); } function OnTrySyncCommand(cmd) { } function GetRecordingManagerState() { return {running: false} } function TestASIOLatency(s) { dbg('TestASIOLatency' + JSON.stringify(arguments)); } function TestLatency(clientID, callbackFunctionName, timeoutCallbackName) { logger.debug("Fake JamClient: TestLatency called with client, " + clientID + " and callback function name: " + callbackFunctionName); var response = { clientID: clientID, latency: 50 }; var js = callbackFunctionName + "(" + JSON.stringify(response) + ");"; eval(js); } function IsMyNetworkWireless() { // 1=true, 0 = false, -1=unknown return 1; } function SetNetworkTestScore(numClients) { } function SetVideoNetworkTestScore(numClients) { } function GetNetworkTestScore() { return 8; } function GetVideoNetworkTestScore() { return 8; } function SetLatencyTestBlocked(blocked) { } function isLatencyTestBlocked() { return false; } function GetLastLatencyTestTimes() { return {initiated: 10000, requested: 10000} } function GetASIODevices() { var response = [{ "device_id": 0, "device_name": "Realtek High Definition Audio", "device_type": 0, "interfaces": [{ "interface_id": 0, "interface_name": "Realtek HDA SPDIF Out", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "PC Speaker"}] }, { "interface_id": 1, "interface_name": "Realtek HD Audio rear output", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "PC Speaker"}] }, { "interface_id": 2, "interface_name": "Realtek HD Audio Mic input", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Recording Control"}] }, { "interface_id": 3, "interface_name": "Realtek HD Audio Line input", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Recording Control"}] }, { "interface_id": 4, "interface_name": "Realtek HD Digital input", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Capture"}] }, { "interface_id": 5, "interface_name": "Realtek HD Audio Stereo input", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Recording Control"}] }], "wavert_supported": false }, { "device_id": 1, "device_name": "M-Audio FW Audiophile", "device_type": 1, "interfaces": [{ "interface_id": 0, "interface_name": "FWAPMulti", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "Output"}, { "is_input": true, "pin_id": 1, "pin_name": "Input" }] }, { "interface_id": 1, "interface_name": "FW AP 1/2", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "Output"}, { "is_input": true, "pin_id": 1, "pin_name": "Input" }] }, { "interface_id": 2, "interface_name": "FW AP SPDIF", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "Output"}, { "is_input": true, "pin_id": 1, "pin_name": "Input" }] }, { "interface_id": 3, "interface_name": "FW AP 3/4", "pins": [{"is_input": false, "pin_id": 0, "pin_name": "Output"}] }], "wavert_supported": false }, { "device_id": 2, "device_name": "Virtual Audio Cable", "device_type": 2, "interfaces": [{ "interface_id": 0, "interface_name": "Virtual Cable 2", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Capture"}, { "is_input": false, "pin_id": 1, "pin_name": "Output" }] }, { "interface_id": 1, "interface_name": "Virtual Cable 1", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Capture"}, { "is_input": false, "pin_id": 1, "pin_name": "Output" }] }], "wavert_supported": false }, { "device_id": 3, "device_name": "WebCamDV WDM Audio Capture", "device_type": 3, "interfaces": [{ "interface_id": 0, "interface_name": "WebCamDV Audio", "pins": [{"is_input": true, "pin_id": 0, "pin_name": "Recording Control"}, { "is_input": false, "pin_id": 1, "pin_name": "Volume Control" }] }], "wavert_supported": false }]; return response; } // Session Functions function SessionCurrrentJamTrackPlayPosMs() { return 0; } function GetJamTrackSettings() { return {tracks: []} } function SessionGetJamTracksPlayDurationMs() { return 60000; } function SessionAddTrack() { } function SessionAudioResync() { logger.debug("Fake JamClient: SessionAudioResync()"); } function getConnectionDetail(arg1, arg2) { return {} } function SessionGetAllControlState(isMasterOrPersonal) { var mixerIds = SessionGetIDs() return SessionGetControlState(mixerIds, isMasterOrPersonal); } function SessionGetControlState(mixerIds, isMasterOrPersonal) { dbg("SessionGetControlState"); var groups = [ChannelGroupIds.MasterGroup, ChannelGroupIds.MonitorGroup, ChannelGroupIds.AudioInputMusicGroup, ChannelGroupIds.AudioInputChatGroup, ChannelGroupIds.AudioInputChatGroup, ChannelGroupIds.UserMusicInputGroup, ChannelGroupIds.UserChatInputGroup, ChannelGroupIds.PeerMediaTrackGroup, ChannelGroupIds.JamTrackGroup, ChannelGroupIds.MetronomeGroup]; var names = [ "FWAPMulti", "FWAPMulti", "FWAPMulti", "FWAPMulti", "", "", "", "", "", "" ]; var media_types = [ "Master", "Monitor", "AudioInputMusic", "AudioInputChat", "StreamOutMusic", "UserMusicInput", "PeerAudioInputMusic", "PeerMediaTrack", "JamTrack", "MetronomeTrack" ] var clientIds = [ "", "", "", "", "3933ebec-913b-43ab-a4d3-f21dc5f8955b", "", "", "", "", "" ]; var response = []; for (var i = 0; i < mixerIds.length; i++) { // for testing no inputs, set simulateNoInputs = true if (simulateNoInputs && i == 2) continue; response.push({ client_id: clientIds[i], group_id: groups[i], id: mixerIds[i] + (isMasterOrPersonal ? 'm' : 'p'), master: isMasterOrPersonal, media_type: media_types[i], monitor: !isMasterOrPersonal, mute: false, name: names[i], range_high: 20, range_low: -80, record: true, stereo: true, volume_left: -40, volume_right: -40, pan: 0, instrument_id: 50, // see globals.js mode: isMasterOrPersonal, rid: mixerIds[i] }); } return response; } function SessionGetIDs() { return [ "FWAPMulti_0_10000", "FWAPMulti_1_10100", "FWAPMulti_2_10200", "FWAPMulti_3_10500", "User@208.191.152.98#", "User@208.191.152.98_*" ]; } function RegisterRecordingManagerCallbacks(commandStart, commandProgress, commandStop, commandsChanged) { } function RegisterRecordingCallbacks(startRecordingCallbackName, stopRecordingCallbackName, startedRecordingCallbackName, stoppedRecordingCallbackName, abortedRecordingCallbackName) { fakeJamClientRecordings.RegisterRecordingCallbacks(startRecordingCallbackName, stopRecordingCallbackName, startedRecordingCallbackName, stoppedRecordingCallbackName, abortedRecordingCallbackName); } function SessionRegisterCallback(callbackName) { eventCallbackName = callbackName; if (callbackTimer) { context.clearInterval(callbackTimer); } if (eventCallbackName) { callbackTimer = context.setInterval(doCallbacks, eventCallbackRate); } } function SessionSetAlertCallback(callback) { alertCallbackName = callback; // simulate a backend alert /**setTimeout(function() { eval(alertCallbackName + '(27)'); }, 3000)*/ } function SessionSetConnectionStatusRefreshRate(milliseconds) { dbg('SessionSetConnectionStatusRefreshRate: ' + milliseconds); } function SessionSetControlState(stringValue, isMasterOrPersonal) { dbg('SessionSetControlState: ' + stringValue + " m/p=" + isMasterOrPersonal); } function SessionSetRecordingFilename(filename) { } function SessionSetRecordingFolder(folderName) { } function SessionStartPlay() { } function SessionStartRecording() { } function SessionStopPlay() { } function SessionStopRecording() { } function SessionAddPlayTrack() { return true; } function SessionRemoveAllPlayTracks() { } function isSessionTrackPlaying() { return false; } function SessionCurrrentPlayPosMs() { return 0; } function SessionGetTracksPlayDurationMs() { return 0; } function SessionGetDeviceLatency() { return 10.0; } function SessionPageEnter() { logger.debug("FakeJamClient: SessionPageEnter"); return {} } function SessionPageLeave() { logger.debug("FakeJamClient: SessionPageLeave") } function SetMixerMode(mode) { } function SessionGetMasterLocalMix() { logger.debug('SessionGetMasterLocalMix. Returning: ' + _mix); return _mix; } function SessionSetMasterLocalMix(level) { logger.debug('SessionSetMasterLocalMix(' + level + ')'); _mix = level; } function SessionSetUserName(client_id, name) { } function doCallbacks() { var names = ["vu"]; //var ids = ["FWAPMulti_2_10200", "FWAPMulti_0_10000"]; var ids = ["i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1", "i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~2"]; var args = []; for (var i = 0; i < ids.length; i++) { for (var j = 0; j < names.length; j++) { args.push('"' + names[j] + '"'); args.push('"' + ids[i] + '"'); args.push(vuValue); } } var js = eventCallbackName + '(' + args.join(',') + ')'; //eval(js); vuValue += vuChange; if (vuValue > 10 || vuValue < -70) { vuChange = vuChange * -1; } } function SetVURefreshRate(rateMS) { eventCallbackRate = rateMS; if (callbackTimer) { context.clearInterval(callbackTimer); } if (eventCallbackName) { callbackTimer = context.setInterval(doCallbacks, eventCallbackRate); } } // Track Functions // Returns a list of objects representing all available audio devices and // pins on the current system. On my windows box, I get 38 objects back. // First couple examples included here. Note that the list tends to come // back with all of the left inputs, then all the right inputs, then all // the left outputs, then all the right outputs. function TrackGetChannels() { // Real example: /* { device_id: "1394\\M-Audio&FW_Audiophile", full_id: "i~1~\\\\?\\1394#m-audio&fw_audiophile#d4eb0700036c0d00#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\\fwap_12", id: "\\\\?\\1394#m-audio&fw_audiophile#d4eb0700036c0d00#{6994ad04-93ef-11d0-a3cc-00a0c9223196}\\fwap_12", input: true, left: true, name: "M-Audio FW Audiophile: FW AP 1/2 - Left" }, */ // But we'll just build a list of names and fake it var devices = [ "M-Audio FW Audiophile: FW AP 1/2" //"M-Audio FW Audiophile: FW Multi 1/2", //"M-Audio FW Audiophile: FW SPDIF 1/2", //"Realtek High Definition Audio: Realtek HD Digital", // "Realtek High Definition Audio: Realtek HD Line", // "Realtek High Definition Audio: Realtek HD Audio Mic", // "Realtek High Definition Audio: Realtek HD Audio Stereo", //"WebCamDV WDM Audio Capture: WebCamDV Audio" ]; var suffixes = [" - Left", " - Right", " - Left", " - Right"]; var lefts = [true, false, true, false]; var inputs = [true, true, false, false]; var types = ["music", "non-music", "music", "non-music"]; var response = []; var name, o, i, j; for (j = 0; j < 4; j++) { for (i = 0; i < devices.length; i++) { name = devices[i] + suffixes[j]; o = { device_id: name, full_id: name, id: name, input: inputs[j], left: lefts[j], name: name, device_type: types[j] }; response.push(o); } } return response; } function TrackGetCount() { return 1; // Real version returns whatever was set } function TrackGetInstrument(trackNumber) { if (trackNumber === 1) { return 100; } else { return 200; } } function TrackGetChatEnable() { return true; } function TrackSetChatEnable(chat) { } function TrackSaveAssignments() { } function TrackGetDevices() { var response = { "Built-in": "Built-in", "ASIO4ALL v2": "ASIO4ALL v2 - ASIO", "BEHRINGER USB AUDIO": "BEHRINGER USB AUDIO - ASIO", "{2B7D1F21-FA6E-11D4-0002-DDCA793267F2}": "SoundMAX HD Audio O - WDM", "{ABCC5A6C-C263-463B-A72F-A5BF64C86EBA}": "Generic USB Audio Device - WDM" }; return response; } function TrackDeleteProfile(id) { } function TrackGetMusicDeviceID() { return device_id; } function TrackSetMusicDevice(id) { device_id = id; } function TrackGetMusicDeviceNames(input) { var names = []; names.push("Built-in"); return names; } // mock response of this method by allowing only even device IDs to open control panel function TrackHasControlPanel() { return true; } function TrackIsMusicDeviceType(type) { return true; } function TrackGetChatUsesMusic() { return 0; } function TrackSetChatUsesMusic(usesMusic) { } function TrackOpenControlPanel() { return; } function TrackLoadAssignments() { } function TrackSave() { } // Set a Track Assignment. // assignment is an enum: // CHAT = -2, OUTPUT = -1, UNASSIGNED = 0 function TrackSetAssignment(chanId, isInput, assignment) { } // Get a Track Assignment. function TrackGetAssignment(chanId, isInput) { // CHAT = -2, OUTPUT = -1, UNASSIGNED = 0 return 0; } function TrackSetCount(count) { } function TrackSetInstrument(track, instrumentId) { } function JamTrackStopPlay() { } function JamTrackPlay() { return true; } function JamTrackIsPlayable() { return true; } function JamTrackGetTrackDetail() { return {key_state: 'unknown'} } function JamTrackKeysRequest() { } function JamTrackDownload() { } // Method which sets volume function UpdateMixer(mixerId) { } // scoring knobs function GetScoreWorkTimingInterval() { return {interval: 1000, backoff: 60000} } function SetScoreWorkTimingInterval(knobs) { return true; } function SessionOpenBackingTrackFile(path, loop) { backingTrackPath = path backingTrackLoop = loop } function SessionSetBackingTrackFileLoop(path, loop) { backingTrackPath = path backingTrackLoop = loop } function SessionCloseBackingTrackFile(path) { backingTrackPath = "" } function SessionOpenMetronome(bpm, click, meter, mode) { logger.debug("Setting metronome BPM: ", bpm) metronomeActive = true metronomeBPM = bpm metronomeSound = click metronomeMeter = meter } //change setting - click. Mode 0: = mono, 1, = left ear, 2= right ear function SessionSetMetronome(bpm, click, meter, mode) { SessionOpenMetronome(bpm, click, meter, mode) } //close everywhere function SessionCloseMetronome() { metronomeActive = false } function setMetronomeOpenCallback(callback) { } function getMyNetworkState() { return { ntp_stable: Math.random() > 0.5 } } function getPeerState(clientId) { return { ntp_stable: Math.random() > 0.5 } } // stun function NetworkTestResult() { return {remote_udp_blocked: false} } // Client Update Functions function IsAppInWritableVolume() { return true; } function ClientUpdateVersion() { return "Compiled 1.2.3"; } function ClientUpdateStartDownload(url, progressCallback, successCallback, failureCallback) { // simulate a bunch of download callbacks var count = 0; var max = 100; var bytesReceived = 0; var bytesTotal = 10000; function fire() { count++; context.setTimeout(function () { bytesReceived = ( count / max ) * bytesTotal; context.JK.ClientUpdate.DownloadProgressCallback(bytesReceived, bytesTotal, 0, 0); if (count < max) { fire(); } else { context.JK.ClientUpdate.DownloadFailureCallback("/some/path/here"); } }, 50); } fire(); } function getBackingTrackList() { return { backing_tracks: [ {name: "This is a really long name for a song dude.mp3", size: 4283}, {name: "foo.mp3", size: 325783838} ] }; } function ClientUpdateStartUpdate(path, successCallback, failureCallback) { } // ------------------------------- // fake jam client methods // not a part of the actual bridge // ------------------------------- function SetFakeRecordingImpl(fakeRecordingsImpl) { fakeJamClientRecordings = fakeRecordingsImpl; } function TestNetworkPktBwRate(targetClientId, successCallback, timeoutCallback, testType, duration, numClients, payloadSize) { var progress = { progress: true, upthroughput: .95, downthroughput: .95, upjitter: 2.3, downjitter: 2.3 } var count = 0; var interval = setInterval(function () { eval(successCallback + "(" + JSON.stringify(progress) + ");"); if (progress.upthroughput < 1) { progress.upthroughput += .05; } if (progress.downthroughput < 1) { progress.downthroughput += .05; } count++; if (count == duration) { clearInterval(interval); delete progress['progress'] progress.pass = true; eval(successCallback + "(" + JSON.stringify(progress) + ");"); } }, 1000); } function StopNetworkTest(targetClientId) { } function OnLoggedIn(userId, sessionToken) { } function OnLoggedOut() { } function UserAttention(option) { } function SessionGetMacHash() { return null; } function IsFrontendVisible() { return true; } function LastUsedProfileName() { return 'default' }; function SetLastUsedProfileName(name) { return true; }; function log(level, message) { console.log("beep : " + message) } function getOperatingMode() { if (location.pathname == '/latency_tester') { return 'server'; } else { return 'client'; } } // passed an array of recording objects from the server function GetLocalRecordingState(recordings) { var result = {recordings: []}; var recordingResults = result.recordings; var possibleAnswers = ['HQ', 'RT', 'MISSING', 'PARTIALLY_MISSING']; $.each(recordings, function (i, recording) { // just make up a random yes-hq/yes-rt/missing answer var recordingResult = {}; recordingResult['aggregate_state'] = possibleAnswers[Math.floor((Math.random() * 4))]; recordingResults.push(recordingResult); }) return result; } function OpenRecording(claimedRecording) { return {success: true} } function PreviewRecording(claimedRecording) { return OpenRecording(claimedRecording); } function CloseRecording() { } function ClosePreviewRecording() { CloseRecording(); } function OnDownloadAvailable() { } function SaveToClipboard(text) { } function IsNativeClient() { /* must always return false in all scenarios due to not ruin scoring !*/ return false; } function IsAudioStarted() { logger.debug("FakeJamClient: IsAudioStarted"); return false; } function StopAudio() { logger.debug("FakeJamClient: StopAudio"); } function ResetPageCounters() { logger.debug("FakeJamClient: ResetPageCounters"); } function ReloadAudioSystem(leaveRunning, loadLastProfile, reinitAssignments) { logger.debug("FakeJamClient: ReloadAudioSystem"); return {}; } function SessionLiveBroadcastStart(host, port, mount, sourceUser, sourcePass, preferredClientId, bitrate) { logger.debug("SessionLiveBroadcastStart requested"); } function SessionLiveBroadcastStop() { logger.debug("SessionLiveBroadcastStop requested"); } function RegisterQuitCallback() { } function LeaveSessionAndMinimize() { } function SetAutoStart() { } function GetAutoStart() { return true; } function SaveSettings() { } function GetUseStaticPort() { return false; } function SetUseStaticPort() { } function GetStaticPort() { return 0 } function SetStaticPort() { } function VSTLoad() { } function VSTScan(callback) { setTimeout(eval(callback + "()"), 1000) } function hasVstHost() { return false; } function getPluginList() { return {vsts: []} } function clearPluginList() { } function listTrackAssignments() { return {} } // Javascript Bridge seems to camel-case // Set the instance functions: this.AbortRecording = AbortRecording; this.OnTrySyncCommand = OnTrySyncCommand; this.GetRecordingManagerState = GetRecordingManagerState; this.GetASIODevices = GetASIODevices; this.GetOS = GetOS; this.GetOSAsString = GetOSAsString; this.JoinSession = JoinSession; this.LatencyUpdated = LatencyUpdated; this.LeaveSession = LeaveSession; this.P2PMessageReceived = P2PMessageReceived; this.ParticipantJoined = ParticipantJoined; this.ParticipantLeft = ParticipantLeft; this.RecordTestBegin = RecordTestBegin; this.RecordTestEnd = RecordTestEnd; this.RecordTestPlayback = RecordTestPlayback; this.RegisterVolChangeCallBack = RegisterVolChangeCallBack; this.SendP2PMessage = SendP2PMessage; this.SetASIOEnabled = SetASIOEnabled; this.SignalLatencyUpdated = SignalLatencyUpdated; this.SignalSendP2PMessage = SignalSendP2PMessage; this.StartPlayTest = StartPlayTest; this.StartRecordTest = StartRecordTest; this.StartRecording = StartRecording; this.StopPlayTest = StopPlayTest; this.StopRecording = StopRecording; this.TestASIOLatency = TestASIOLatency; this.TestLatency = TestLatency; this.IsMyNetworkWireless = IsMyNetworkWireless; this.SetNetworkTestScore = SetNetworkTestScore; this.GetNetworkTestScore = GetNetworkTestScore; this.SetVideoNetworkTestScore = SetVideoNetworkTestScore; this.GetVideoNetworkTestScore = GetVideoNetworkTestScore; this.SetLatencyTestBlocked = SetLatencyTestBlocked; this.isLatencyTestBlocked = isLatencyTestBlocked; this.GetLastLatencyTestTimes = GetLastLatencyTestTimes; this.RegisterQuitCallback = RegisterQuitCallback; this.LeaveSessionAndMinimize = LeaveSessionAndMinimize; this.GetAutoStart = GetAutoStart; this.SetAutoStart = SetAutoStart; this.GetUseStaticPort = GetUseStaticPort; this.SetUseStaticPort = SetUseStaticPort; this.GetStaticPort = GetStaticPort; this.SetStaticPort = SetStaticPort; this.connected = true; // FTUE (round 3) this.FTUESetInputMusicDevice = FTUESetInputMusicDevice; this.FTUESetOutputMusicDevice = FTUESetOutputMusicDevice; this.FTUEGetInputMusicDevice = FTUEGetInputMusicDevice; this.FTUEGetOutputMusicDevice = FTUEGetOutputMusicDevice; this.FTUEGetChatInputVolume = FTUEGetChatInputVolume; this.FTUEGetChatInputs = FTUEGetChatInputs; this.FTUEGetChannels = FTUEGetChannels; this.FTUEGetAudioDevices = FTUEGetAudioDevices; this.FTUEStartIoPerfTest = FTUEStartIoPerfTest; this.FTUEGetIoPerfData = FTUEGetIoPerfData; this.FTUEGetDevices = FTUEGetDevices; this.FTUEGetFrameSize = FTUEGetFrameSize; this.FTUECancel = FTUECancel; this.FTUEPageEnter = FTUEPageEnter; this.FTUEPageLeave = FTUEPageLeave; this.FTUEGetMusicProfileName = FTUEGetMusicProfileName; this.FTUESetMusicProfileName = FTUESetMusicProfileName; this.FTUESetPreferredMixerSampleRate = FTUESetPreferredMixerSampleRate; this.FTUESetPreferredOutputSampleRate = FTUESetPreferredOutputSampleRate; this.FTUESetPreferredChatSampleRate = FTUESetPreferredChatSampleRate; this.FTUEgetInputDeviceSampleRate = FTUEgetInputDeviceSampleRate; this.FTUEgetOutputDeviceSampleRate = FTUEgetOutputDeviceSampleRate; this.FTUEGetInputLatency = FTUEGetInputLatency; this.FTUEGetInputVolume = FTUEGetInputVolume; this.FTUEGetMusicInputs = FTUEGetMusicInputs; this.FTUEGetMusicOutputs = FTUEGetMusicOutputs; this.FTUEGetOutputLatency = FTUEGetOutputLatency; this.FTUEGetOutputVolume = FTUEGetOutputVolume; this.FTUEGetStatus = FTUEGetStatus; this.FTUEGetVolumeRanges = FTUEGetVolumeRanges; this.FTUEHasControlPanel = FTUEHasControlPanel; this.FTUEInit = FTUEInit; this.FTUEOpenControlPanel = FTUEOpenControlPanel; this.FTUERegisterLatencyCallback = FTUERegisterLatencyCallback; this.FTUERegisterVUCallbacks = FTUERegisterVUCallbacks; this.FTUERefreshDevices = FTUERefreshDevices; this.FTUESave = FTUESave; this.FTUESetChatInput = FTUESetChatInput; this.FTUESetChatInputVolume = FTUESetChatInputVolume; this.FTUESetInputVolume = FTUESetInputVolume; this.FTUESetFrameSize = FTUESetFrameSize; this.FTUESetInputLatency = FTUESetInputLatency; this.FTUESetMusicDevice = FTUESetMusicDevice; this.FTUESetMusicInput = FTUESetMusicInput; this.FTUESetMusicOutput = FTUESetMusicOutput; this.FTUESetOutputLatency = FTUESetOutputLatency; this.FTUESetOutputVolume = FTUESetOutputVolume; this.FTUESetStatus = FTUESetStatus; this.FTUEStartLatency = FTUEStartLatency; this.FTUEGetExpectedLatency = FTUEGetExpectedLatency; this.FTUEGetGoodConfigurationList = FTUEGetGoodConfigurationList; this.FTUEGetAllAudioConfigurations = FTUEGetAllAudioConfigurations; this.FTUEGetGoodAudioConfigurations = FTUEGetGoodAudioConfigurations; this.FTUEGetConfigurationDevice = FTUEGetConfigurationDevice; this.FTUEIsMusicDeviceWDM = FTUEIsMusicDeviceWDM; this.FTUELoadAudioConfiguration = FTUELoadAudioConfiguration; this.FTUEClearChannelAssignments = FTUEClearChannelAssignments; this.FTUEClearChatInput = FTUEClearChatInput; this.FTUECreateUpdatePlayBackProfile = FTUECreateUpdatePlayBackProfile; // Session this.SessionAddTrack = SessionAddTrack; this.SessionCurrrentJamTrackPlayPosMs = SessionCurrrentJamTrackPlayPosMs; this.SessionGetJamTracksPlayDurationMs = SessionGetJamTracksPlayDurationMs; this.SessionGetControlState = SessionGetControlState; this.SessionGetAllControlState = SessionGetAllControlState; this.SessionSetUserName = SessionSetUserName; this.SessionGetIDs = SessionGetIDs; this.RegisterRecordingManagerCallbacks = RegisterRecordingManagerCallbacks; this.RegisterRecordingCallbacks = RegisterRecordingCallbacks; this.SessionRegisterCallback = SessionRegisterCallback; this.SessionSetAlertCallback = SessionSetAlertCallback; this.SessionSetControlState = SessionSetControlState; this.SessionSetRecordingFilename = SessionSetRecordingFilename; this.SessionSetRecordingFolder = SessionSetRecordingFolder; this.SessionStartPlay = SessionStartPlay; this.SessionStartRecording = SessionStartRecording; this.SessionStopPlay = SessionStopPlay; this.SessionAddPlayTrack = SessionAddPlayTrack; this.SessionRemoveAllPlayTracks = SessionRemoveAllPlayTracks; this.SessionStopRecording = SessionStopRecording; this.isSessionTrackPlaying = isSessionTrackPlaying; this.SessionCurrrentPlayPosMs = SessionCurrrentPlayPosMs; this.SessionGetTracksPlayDurationMs = SessionGetTracksPlayDurationMs; this.SessionPageEnter = SessionPageEnter; this.SessionPageLeave = SessionPageLeave; this.SetMixerMode = SetMixerMode; this.SetVURefreshRate = SetVURefreshRate; this.SessionGetMasterLocalMix = SessionGetMasterLocalMix; this.SessionSetMasterLocalMix = SessionSetMasterLocalMix; this.SessionGetDeviceLatency = SessionGetDeviceLatency; this.SessionAudioResync = SessionAudioResync; this.getConnectionDetail = getConnectionDetail; // Track this.TrackGetChannels = TrackGetChannels; this.TrackSetAssignment = TrackSetAssignment; this.TrackGetAssignment = TrackGetAssignment; this.TrackSetCount = TrackSetCount; this.TrackGetCount = TrackGetCount; this.TrackSave = TrackSave; this.TrackLoadAssignments = TrackLoadAssignments; this.TrackSetInstrument = TrackSetInstrument; this.TrackGetInstrument = TrackGetInstrument; this.TrackSaveAssignments = TrackSaveAssignments; this.TrackGetDevices = TrackGetDevices; this.TrackDeleteProfile = TrackDeleteProfile; this.TrackGetMusicDeviceID = TrackGetMusicDeviceID; this.TrackSetMusicDevice = TrackSetMusicDevice; this.TrackGetMusicDeviceNames = TrackGetMusicDeviceNames; this.TrackHasControlPanel = TrackHasControlPanel; this.TrackOpenControlPanel = TrackOpenControlPanel; this.TrackIsMusicDeviceType = TrackIsMusicDeviceType; this.TrackGetChatEnable = TrackGetChatEnable; this.TrackSetChatEnable = TrackSetChatEnable; this.TrackGetChatUsesMusic = TrackGetChatUsesMusic; this.TrackSetChatUsesMusic = TrackSetChatUsesMusic; this.GetJamTrackSettings = GetJamTrackSettings; this.JamTrackStopPlay = JamTrackStopPlay; this.JamTrackPlay = JamTrackPlay; this.JamTrackIsPlayable = JamTrackIsPlayable; this.JamTrackGetTrackDetail = JamTrackGetTrackDetail; this.JamTrackKeysRequest = JamTrackKeysRequest; this.JamTrackDownload = JamTrackDownload; // Scoring Knobs this.GetScoreWorkTimingInterval = GetScoreWorkTimingInterval; this.SetScoreWorkTimingInterval = SetScoreWorkTimingInterval; // Backing tracks: this.getBackingTrackList = getBackingTrackList; this.SessionCloseBackingTrackFile = SessionCloseBackingTrackFile; this.SessionOpenBackingTrackFile = SessionOpenBackingTrackFile; this.SessionSetBackingTrackFileLoop = SessionSetBackingTrackFileLoop; // Metronome: this.SessionCloseMetronome = SessionCloseMetronome; this.SessionOpenMetronome = SessionOpenMetronome; this.SessionSetMetronome = SessionSetMetronome; this.setMetronomeOpenCallback = setMetronomeOpenCallback; this.getMyNetworkState = getMyNetworkState; this.getPeerState = getPeerState; // Client Update this.IsAppInWritableVolume = IsAppInWritableVolume; this.ClientUpdateVersion = ClientUpdateVersion; this.ClientUpdateStartDownload = ClientUpdateStartDownload; this.ClientUpdateStartUpdate = ClientUpdateStartUpdate; this.getClientParentChildRole = getClientParentChildRole; this.getParentClientId = getParentClientId; this.OpenSystemBrowser = OpenSystemBrowser; this.RestartApplication = RestartApplication; this.ShutdownApplication = ShutdownApplication; // Websocket/Auth sessions this.OnLoggedIn = OnLoggedIn; this.OnLoggedOut = OnLoggedOut; this.SessionGetMacHash = SessionGetMacHash; this.UserAttention = UserAttention; this.IsFrontendVisible = IsFrontendVisible; this.LastUsedProfileName = LastUsedProfileName; this.SetLastUsedProfileName = SetLastUsedProfileName; // Recording Playback this.GetLocalRecordingState = GetLocalRecordingState; this.OpenRecording = OpenRecording; this.CloseRecording = CloseRecording; this.PreviewRecording = PreviewRecording; this.ClosePreviewRecording = ClosePreviewRecording; this.OnDownloadAvailable = OnDownloadAvailable; // Video functionality: this.testVideoRender = testVideoRender; this.FTUESelectVideoCaptureDevice = FTUESelectVideoCaptureDevice; this.FTUESetVideoEncodeResolution = FTUESetVideoEncodeResolution; this.FTUEGetVideoCaptureDeviceNames = FTUEGetVideoCaptureDeviceNames; this.FTUECurrentSelectedVideoDevice = FTUECurrentSelectedVideoDevice; this.FTUEGetAvailableEncodeVideoResolutions = FTUEGetAvailableEncodeVideoResolutions; this.FTUEGetVideoCaptureDeviceCapabilities = FTUEGetVideoCaptureDeviceCapabilities; this.FTUEGetSendFrameRates = FTUEGetSendFrameRates; this.FTUESetSendFrameRates = FTUESetSendFrameRates; this.GetCurrentVideoResolution = GetCurrentVideoResolution; this.GetCurrentVideoFrameRate = GetCurrentVideoFrameRate; this.GetSampleRate = GetSampleRate; this.FTUESetVideoShareEnable = FTUESetVideoShareEnable; this.FTUEGetVideoShareEnable = FTUEGetVideoShareEnable; this.isSessVideoShared = isSessVideoShared; this.SessStopVideoSharing = SessStopVideoSharing; this.SessStartVideoSharing = SessStartVideoSharing this.IsVstLoaded = IsVstLoaded; this.hasVstAssignment = hasVstAssignment; // Clipboard this.SaveToClipboard = SaveToClipboard; // Capabilities this.IsNativeClient = IsNativeClient; // Audio this.IsAudioStarted = IsAudioStarted; this.StopAudio = StopAudio; this.ResetPageCounters = ResetPageCounters; this.ReloadAudioSystem = ReloadAudioSystem; // Broadcasting this.SessionLiveBroadcastStart = SessionLiveBroadcastStart; this.SessionLiveBroadcastStop = SessionLiveBroadcastStop; this.SessionSetConnectionStatusRefreshRate = SessionSetConnectionStatusRefreshRate; // fake calls; not a part of the actual jam client this.RegisterP2PMessageCallbacks = RegisterP2PMessageCallbacks; this.SetFakeRecordingImpl = SetFakeRecordingImpl; // network test this.TestNetworkPktBwRate = TestNetworkPktBwRate; this.StopNetworkTest = StopNetworkTest; this.log = log; this.getOperatingMode = getOperatingMode; this.VSTLoad = VSTLoad; this.VSTScan = VSTScan; this.hasVstHost = hasVstHost; this.getPluginList = getPluginList; this.clearPluginList = clearPluginList; this.listTrackAssignments = listTrackAssignments; this.applySubscriptionPolicy = applySubscriptionPolicy; this.clientID = "devtester"; }; })(window, jQuery);