From 3707a3abd67295d6790c0718db685055d2ae307d Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 11 Dec 2015 21:14:00 -0600 Subject: [PATCH] * stats working decently --- .../ConfigureLiveTracksDialog.js.jsx.coffee | 5 +- .../SessionMyTrack.js.jsx.coffee | 2 +- .../SessionOtherTrack.js.jsx.coffee | 2 +- .../SessionOtherTracks.js.jsx.coffee | 3 +- .../SessionStatsHover.js.jsx.coffee | 52 ++++++++++---- .../stores/SessionStatsStore.js.coffee | 70 ++++++++++++------- .../react-components/SessionScreen.css.scss | 4 +- .../react-components/SessionTrack.css.scss | 5 +- web/config/application.rb | 24 ++++--- 9 files changed, 109 insertions(+), 58 deletions(-) diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index 633d69030..3329591dd 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -257,12 +257,13 @@ ConfigureTracksStore = @ConfigureTracksStore $root = $(@getDOMNode()) $select = $root.find('select.vsts') vstSelected = $select.val() - if vstSelected != 'NONE' - vstSelected = {file: vstSelected} + #if vstSelected != 'NONE' + vstSelected = {file: vstSelected} if @state.configureTracks?.trackType == 'midi' @updateMidiAssociations() else + logger.debug("associating vst", vstSelected) ConfigureTracksActions.associateVSTWithTrack(vstSelected) diff --git a/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee index 4f46ca51d..1e7c94092 100644 --- a/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee @@ -118,7 +118,7 @@ ConfigureTracksActions = @ConfigureTracksActions () => {participant: {client_id: this.props.clientId, user: name: 'You', possessive: 'Your'}, } , - {width:380, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'}) + {width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'}) unless this.props.hasMixer $mute.on("mouseenter", false) diff --git a/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee index 0460c9819..14781ff71 100644 --- a/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee @@ -125,7 +125,7 @@ MixerActions = @MixerActions () => {participant: this.props.participant} , - {width:380, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) + {width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) unless this.props.hasMixer $mute.on("mouseenter", false) diff --git a/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee index c78245c1a..bd3ceb07b 100644 --- a/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee @@ -17,8 +17,9 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup for participant in session.otherParticipants() - if participant.user.id == context.JK.currentUserId + if participant.client_id == @app.clientId participant.user.possessive = "Your" + participant.self = true else participant.user.possessive = participant.user.name + "'s" diff --git a/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee index d0120d481..ff6df015d 100644 --- a/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee @@ -4,6 +4,13 @@ MixerActions = @MixerActions ptrCount = 0 StatsInfo = { + aggregate: { + latency: { + good: (user, stats) -> "#{user.possessive} total latency from them to you is very low.", + warn: (user, stats) -> "#{user.possessive} total latency from them to you is typical.", + poor: (user, stats) -> "#{user.possessive} total latency from them to you is poor." + } + }, system: { cpu: { good: (user, stats) -> "#{user.possessive} computer processor is not overworked by JamKazam or the your system.", @@ -106,21 +113,39 @@ StatsInfo = { if info? extraInfo = info - # "Windows WDM-KS" - computerStats = [] networkStats = [] audioStats = [] + aggregateStats = [] + aggregate = @state.stats?.aggregate network = @state.stats?.network system = @state.stats?.system audio = @state.stats?.audio + aggregateTag = null + if aggregate? + if aggregate.latency + aggregateStats.push(@stat(aggregate, 'aggregate', 'Latency', 'latency', Math.round(aggregate.latency))) + + aggregateTag = + `
+

Aggregate

+ {aggregateStats} +
` + if system? if system.cpu? computerStats.push(@stat(system, 'system', 'Processor', 'cpu', Math.round(system.cpu) + ' %')) if audio? + if audio.latency? + audioStats.push(@stat(audio, 'audio', 'Latency', 'latency', audio.latency.toFixed(1) + ' ms')) + if audio.input_jitter? + audioStats.push(@stat(audio, 'audio', 'Input Jitter', 'input_jitter', audio.input_jitter.toFixed(2))) + if audio.output_jitter? + audioStats.push(@stat(audio, 'audio', 'Output Jitter', 'output_jitter', audio.output_jitter.toFixed(2))) + if audio.audio_in_type? audio_type = '?' audio_long = audio.audio_in_type.toLowerCase() @@ -140,33 +165,31 @@ StatsInfo = { else if audio.framesize == 10 framesize = '10' audioStats.push(@stat(audio, 'audio', 'Frame Size', 'framesize', framesize)) - if audio.latency? - audioStats.push(@stat(audio, 'audio', 'Latency', 'latency', audio.latency.toFixed(1) + ' ms')) - if audio.input_jitter? - audioStats.push(@stat(audio, 'audio', 'Input Jitter', 'input_jitter', audio.input_jitter.toFixed(2))) - if audio.output_jitter? - audioStats.push(@stat(audio, 'audio', 'Output Jitter', 'output_jitter', audio.output_jitter.toFixed(2))) networkTag = null if network? - if network.net_bitrate? - networkStats.push(@stat(network, 'network', 'Bandwidth', 'net_bitrate', Math.round(network.net_bitrate) + ' k')) - if network.ping? networkStats.push(@stat(network, 'network', 'Latency', 'ping', (network.ping / 2).toFixed(1) + ' ms')) - #if network.jitter? if network.audiojq_median? networkStats.push(@stat(network, 'network', 'Jitter Queue', 'audiojq_median', network.audiojq_median.toFixed(1))) - # networkStats. + if network.jitter_var? + networkStats.push(@stat(network, 'network', 'Jitter', 'jitter_var', network.jitter_var.toFixed(1))) if network.pkt_loss? networkStats.push(@stat(network, 'network', 'Packet Loss', 'pkt_loss', network.pkt_loss.toFixed(1) + ' %')) - if network.wifi? if network.wifi value = 'Wi-Fi' else value = 'Ethernet' networkStats.push(@stat(network, 'network', 'Connectivity', 'wifi', value)) + if network.audio_bitrate_rx? + networkStats.push(@stat(network, 'network', 'Audio Bw Rx', 'audio_bitrate_rx', Math.round(network.net_bitrate_rx) + ' k')) + if network.audio_bitrate_tx? + networkStats.push(@stat(network, 'network', 'Audio Bw Tx', 'audio_bitrate_tx', Math.round(network.net_bitrate_tx) + ' k')) + if network.video_rtpbw_rx? + networkStats.push(@stat(network, 'network', 'Video Bw Rx', 'video_rtpbw_rx', Math.round(network.video_rtpbw_rx) + ' k')) + if network.video_rtpbw_tx? + networkStats.push(@stat(network, 'network', 'Video Bw Tx', 'video_rtpbw_tx', Math.round(network.video_rtpbw_tx) + ' k')) networkTag = `
@@ -178,6 +201,7 @@ StatsInfo = {

Session Diagnostics & Stats: {this.props.participant.user.name}

+ {aggregateTag}

Computer

{computerStats} diff --git a/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee index 22a1347bf..05c6ef6f2 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee @@ -11,12 +11,19 @@ SessionStatThresholds = gon.session_stat_thresholds NetworkThresholds = SessionStatThresholds.network SystemThresholds = SessionStatThresholds.system AudioThresholds = SessionStatThresholds.audio +AggregateThresholds = SessionStatThresholds.aggregate @SessionStatsStore = Reflux.createStore( { listenables: @SessionStatsActions rawStats: null + init: -> + # Register with the app store to get @app + this.listenTo(context.AppStore, this.onAppInit) + + onAppInit: (@app) -> + onPushStats: (stats) -> @rawStats = stats @changed() @@ -25,10 +32,13 @@ AudioThresholds = SessionStatThresholds.audio value = holder[field] fieldLevel = field + '_level' fieldThreshold = threshold[field] + if value? && fieldThreshold? if fieldThreshold.inverse - if value <= fieldThreshold.poor + if fieldThreshold.zero_is_good + holder[fieldLevel] = 'good' + else if value <= fieldThreshold.poor holder[fieldLevel] = 'poor' @participantClassification = 3 else if value <= fieldThreshold.warn @@ -59,11 +69,19 @@ AudioThresholds = SessionStatThresholds.audio changed: () -> @stats = {} + console.log("rawStats", @rawStats) + self = null + for participant in @rawStats + if participant.id == @app.clientId + self = participant + break + for participant in @rawStats @participantClassification = 1 # 1=good, 2=warn, 3=poor - # CPU is 0-100 + total_latency = 0 + if participant.cpu? system = {cpu: participant.cpu} @@ -74,39 +92,24 @@ AudioThresholds = SessionStatThresholds.audio network = participant.network if network? - # audio_bitrate: 256 - # net_bitrate: 286.19244384765625 - # ping: 0.08024691045284271 - # ping_var: 0.6403124332427979 - # pkt_loss: 100 - # wifi: false - @classify(network, 'audiojq_median', NetworkThresholds) - @classify(network, 'net_bitrate', NetworkThresholds) + @classify(network, 'jitter_var', NetworkThresholds) + @classify(network, 'audio_bitrate_rx', NetworkThresholds) + @classify(network, 'audio_bitrate_tx', NetworkThresholds) + @classify(network, 'video_rtpbw_tx', NetworkThresholds) + @classify(network, 'video_rtpbw_rx', NetworkThresholds) @classify(network, 'ping', NetworkThresholds) @classify(network, 'pkt_loss', NetworkThresholds) @classify(network, 'wifi', NetworkThresholds) + total_latency += network.ping / 2 + total_latency += network.audiojq_median * 2.5 + else + total_latency = null + audio = participant.audio if audio? - # acpu: 5.148329734802246 - # audio_in: "Fast Track" - # audio_in_type: "Core Audio" - # cpu: 22.44668960571289 - # framesize: 2.5 - # in_latency: 5.020833492279053 - # input_iio_jitter: -0.0015926361083984375 - # input_jitter: 0.2977011799812317 - # input_median: 400.16632080078125 - # io_out_latency: "Expected Latency = 9.54 +/- 1.00 ms [Raw/PaBuff/PaRing Latency: 9.54 / 12.04 / 0.00 ms]" - # out_latency: 4.520833492279053 - # output_iio_jitter: -0.07366180419921875 - # output_jitter: 0.40290364623069763 - # output_median: 400.0581970214844 - # output_name: 4 - # samplerate: 48000 - if audio.cpu? system = {cpu: audio.cpu} @classify(system, 'cpu', SystemThresholds) @@ -122,6 +125,19 @@ AudioThresholds = SessionStatThresholds.audio @classify(audio, 'output_jitter', AudioThresholds) @classify(audio, 'audio_in_type', AudioThresholds) + if total_latency != null + total_latency += audio.out_latency + total_latency += self.audio.in_latency + else + total_latency = null + + if !self? + aggregate = {latency: total_latency} + + @classify(aggregate, 'latency', AggregateThresholds) + + participant.aggregate = aggregate + switch @participantClassification when 1 then participant.classification = 'good' when 2 then participant.classification = 'warn' diff --git a/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss b/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss index 89ee81304..f0b2a7fe2 100644 --- a/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss +++ b/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss @@ -116,12 +116,12 @@ $session-screen-divider: 1190px; border-width: 1px; border-style: solid; padding:10px; - height: 341px; + height: 477px; margin-top: 20px; } .stats-area { float: left; - padding: 0 20px 20px 20px; + padding: 0 25px 20px 20px; color: #cccccc; h3 { diff --git a/web/app/assets/stylesheets/client/react-components/SessionTrack.css.scss b/web/app/assets/stylesheets/client/react-components/SessionTrack.css.scss index af76f6614..888c88a26 100644 --- a/web/app/assets/stylesheets/client/react-components/SessionTrack.css.scss +++ b/web/app/assets/stylesheets/client/react-components/SessionTrack.css.scss @@ -398,14 +398,15 @@ } &.SessionStatsHover { - width:380px; - height:450px; + width:385px; + height:571px; @include border_box_sizing; h3 { margin-top:20px; color: white; margin-left:20px; + font-weight:bold; } &.self { diff --git a/web/config/application.rb b/web/config/application.rb index 12445911a..22758e55e 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -379,22 +379,30 @@ if defined?(Bundler) config.max_multiple_users_same_ip = 2 config.session_stat_thresholds = { network: { - wifi: {warn: true, poor: true, eql: true}, - net_bitrate: {warn: 210, poor: 155, inverse:true}, - ping: {warn: 40, poor: 70}, - pkt_loss: {warn: 3, poor: 10}, - audiojq_median: {warn: 2.1, poor: 5.1} + wifi: {warn: true, poor: true, eql: true}, + net_bitrate: {warn: 210, poor: 155, inverse:true}, + audio_bitrate_tx:{warn: 128, poor: 96, inverse:true}, + audio_bitrate_rx:{warn: 128, poor: 96, inverse:true}, + video_rtpbw_tx: {warn: 600.1, poor: 400.1, inverse: true, zero_is_good: true}, + video_rtpbw_rx: {warn: 600.1, poor: 400.1, inverse: true, zero_is_good: true}, + ping: {warn: 30.1, poor: 50.1}, + pkt_loss: {warn: 2.1, poor: 5.1}, + audiojq_median: {warn: 4.1, poor: 6.1}, + jitter_var: {warn: 2.1, poor: 4.1} }, system: { - cpu: {warn: 70, poor:85} + cpu: {warn: 60.1, poor:80.1} }, audio: { audio_in_type: {warn: 'Windows WDM-KS', poor: nil, eql:true}, audio_out_type: {warn: 'Windows WDM-KS', poor: nil, eql:true}, framesize: {warn: 2.6, poor: 2.6}, latency: {warn: 10, poor: 20}, - input_jitter: {warn: 0.5, poor: 1}, - output_jitter: {warn: 0.5, poor: 1}, + input_jitter: {warn: 0.51, poor: 1.01}, + output_jitter: {warn: 0.51, poor: 1.01}, + }, + aggregate: { + latency: {warn: 20.1, poor: 35.1} } } config.vst_enabled = true