Mercurial > hg > ugly-duckling
changeset 306:cd117c836ca7
Merge remote-tracking branch 'lucas/dev/tracks-shape' into dev/tracks-shape
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Fri, 12 May 2017 08:46:12 +0100 |
parents | 1d39cc796046 (current diff) 75a234459d3b (diff) |
children | 930f712f687c |
files | |
diffstat | 5 files changed, 82 insertions(+), 143 deletions(-) [+] |
line wrap: on
line diff
--- a/package.json Thu May 11 11:46:07 2017 +0100 +++ b/package.json Fri May 12 08:46:12 2017 +0100 @@ -24,7 +24,7 @@ "@angular/router": "^4.0.0", "core-js": "^2.4.1", "hammerjs": "^2.0.8", - "piper": "github:cannam/piper-js#dev-tracks", + "piper": "github:LucasThompson/piper-js#dev-tracks", "requirejs": "^2.3.3", "rxjs": "^5.1.0", "waves-ui-piper": "piper-audio/waves-ui-piper",
--- a/src/app/services/feature-extraction/FeatureExtractionWorker.ts Thu May 11 11:46:07 2017 +0100 +++ b/src/app/services/feature-extraction/FeatureExtractionWorker.ts Fri May 12 08:46:12 2017 +0100 @@ -63,11 +63,7 @@ return this.dispatch('process', request); } - collect(request: SimpleRequest): Observable<StreamingResponse> { - return this.dispatch('collect', request); - } - - protected dispatch(method: 'process' | 'collect', + protected dispatch(method: 'process', request: SimpleRequest): Observable<StreamingResponse> { const key = request.key.split(':')[0]; return this.services.has(key) ? @@ -80,19 +76,27 @@ super(); } - protected dispatch(method: 'process' | 'collect', + protected dispatch(method: 'process', request: SimpleRequest): Observable<StreamingResponse> { let lastPercentagePoint = 0; + let shouldClear = false; return super.dispatch(method, request) - .scan(streamingResponseReducer) + .scan((acc, value) => { + if (shouldClear) { + acc.features = []; + } + return streamingResponseReducer(acc, value); + }) .filter(val => { + const progress = val.progress; const percentage = - 100 * (val.processedBlockCount / val.totalBlockCount) | 0; + 100 * (progress.processedBlockCount / progress.totalBlockCount) | 0; const pointDifference = (percentage - lastPercentagePoint); const shouldEmit = pointDifference === 1 || percentage === 100; if (shouldEmit) { lastPercentagePoint = percentage; } + shouldClear = shouldEmit; return shouldEmit; }); }
--- a/src/app/services/feature-extraction/FeatureReducers.ts Thu May 11 11:46:07 2017 +0100 +++ b/src/app/services/feature-extraction/FeatureReducers.ts Fri May 12 08:46:12 2017 +0100 @@ -1,15 +1,12 @@ /** * Created by lucast on 26/04/2017. */ -import {StreamingResponse} from 'piper/StreamingService'; -import {Feature, FeatureList} from 'piper/Feature'; -import {SampleType} from 'piper'; -import { - VectorFeature, MatrixFeature, TracksFeature -} from "piper/HigherLevelUtilities"; +import {StreamingResponse} from "piper/StreamingService"; export const arrayReducer = <T>(acc: T[], val: T[]): T[] => { - acc.push.apply(acc, val); + for (let i = 0, len = val.length; i < len; ++i) { + acc.push(val[i]); + } return acc; }; @@ -26,80 +23,12 @@ }; export const streamingResponseReducer = (acc: StreamingResponse, - val: StreamingResponse, - i: number): StreamingResponse => - { - if (acc.features.shape !== val.features.shape) { - throw new Error(`Unexpected feature shape ${val.features.shape} (expected ${acc.features.shape})`); - } - - acc.processedBlockCount = val.processedBlockCount; - - const isOneSamplePerStep = acc.outputDescriptor.configured.sampleType === - SampleType.OneSamplePerStep; - - let incoming, collected; - - console.log("i = " + i + ", shape = " + acc.features.shape + ", count = " + acc.processedBlockCount); - - switch (acc.features.shape) { - - case "vector": - incoming = val.features.collected as VectorFeature; - collected = acc.features.collected as VectorFeature; - if (isOneSamplePerStep) { - // for one sample per step vectors we know there will be - // totalBlockCount number of samples - so pre-allocate the - // Float32Array when we know the totalBlockCount (after - // receiving the first feature) - if (i === 1) { - const newBlock = new Float32Array(acc.totalBlockCount); - newBlock[0] = collected.data[0]; - collected.data = newBlock; - } - collected.data = inPlaceTypedArrayReducer( - collected.data, - incoming.data, - i - ); - } else { - // if not OneSamplePerStep we have to make a new array each time - collected.data = typedArrayReducer( - collected.data, - incoming.data - ); - } - break; - - case "matrix": - incoming = val.features.collected as MatrixFeature; - collected = acc.features.collected as MatrixFeature; - collected.data = arrayReducer<Float32Array>( - collected.data, - incoming.data - ); - break; - - case "list": - incoming = val.features.collected as FeatureList; - collected = acc.features.collected as FeatureList; - acc.features.collected = arrayReducer<Feature>( - collected, - incoming - ); - break; - - case "tracks": - incoming = val.features.collected as TracksFeature; - collected = acc.features.collected as TracksFeature; - acc.features.collected = arrayReducer<VectorFeature>( - collected, incoming - ); - break; - - default: - throw new Error('Invalid feature output. Aborting'); - } - - return acc; - }; + val: StreamingResponse): + StreamingResponse => { + acc.progress = val.progress; + if (val.configuration) { + acc.configuration = val.configuration; + } + arrayReducer(acc.features, val.features); + return acc; +};
--- a/src/app/services/feature-extraction/feature-extraction.service.ts Thu May 11 11:46:07 2017 +0100 +++ b/src/app/services/feature-extraction/feature-extraction.service.ts Fri May 12 08:46:12 2017 +0100 @@ -14,6 +14,7 @@ WebWorkerStreamingClient } from 'piper/client-stubs/WebWorkerStreamingClient'; import {RequestId} from 'piper/protocols/WebWorkerProtocol'; +import {collect, StreamingConfiguration} from "piper/StreamingService"; type RepoUri = string; export interface AvailableLibraries { @@ -66,19 +67,24 @@ } extract(analysisItemId: string, request: SimpleRequest): Promise<void> { - return this.client.collect(request) - .do(val => { - if (val.totalBlockCount > 0) { - this.progressUpdated.next({ - id: analysisItemId, - value: (val.processedBlockCount / val.totalBlockCount) * 100 - }); - } - }) - .toPromise() - .then((response) => { - this.featuresExtracted.next(response); + let config: StreamingConfiguration; + return collect(this.client.process(request), val => { + if (val.configuration) { + config = val.configuration; + } + const progress = val.progress; + if (progress.totalBlockCount > 0) { + this.progressUpdated.next({ + id: analysisItemId, + value: (progress.processedBlockCount / progress.totalBlockCount) * 100 + }); + } + }).then(features => { + this.featuresExtracted.next({ + features: features, + outputDescriptor: config.outputDescriptor }); + }); } updateAvailableLibraries(): Observable<AvailableLibraries> {
--- a/src/app/waveform/waveform.component.ts Thu May 11 11:46:07 2017 +0100 +++ b/src/app/waveform/waveform.component.ts Fri May 12 08:46:12 2017 +0100 @@ -389,7 +389,7 @@ isZooming = false; zoomGestureJustEnded = true; } - }); + }); element.addEventListener('touchmove', zoom); } // this.timeline.createTrack(track, height/2, `wave-${this.trackIdPrefix}`); @@ -425,17 +425,17 @@ } if (sample.length === 0) { console.log('WARNING: No samples gathered, even though we hoped for ' + - (m_per * w) + ' of them'); + (m_per * w) + ' of them'); return 0.0; } sample.sort((a, b) => { return a - b; }); const ix = Math.floor((sample.length * percentile) / 100); console.log('Estimating ' + percentile + '-%ile of ' + - n + '-sample dataset (' + w + ' x ' + h + ') as value ' + ix + - ' of sorted ' + sample.length + '-sample subset'); + n + '-sample dataset (' + w + ' x ' + h + ') as value ' + ix + + ' of sorted ' + sample.length + '-sample subset'); const estimate = sample[ix]; console.log('Estimate is: ' + estimate + ' (where min sampled value = ' + - sample[0] + ' and max = ' + sample[sample.length - 1] + ')'); + sample[0] + ' and max = ' + sample[sample.length - 1] + ')'); return estimate; } @@ -443,8 +443,8 @@ const colours = hexColours.map(n => { const i = parseInt(n, 16); return [ ((i >> 16) & 255) / 255.0, - ((i >> 8) & 255) / 255.0, - ((i) & 255) / 255.0 ]; + ((i >> 8) & 255) / 255.0, + ((i) & 255) / 255.0 ]; }); const last = colours.length - 1; return (value => { @@ -461,8 +461,8 @@ const c0 = colours[base]; const c1 = colours[base + 1]; return [ c0[0] * prop0 + c1[0] * prop1, - c0[1] * prop0 + c1[1] * prop1, - c0[2] * prop0 + c1[2] * prop1 ]; + c0[1] * prop0 + c1[1] * prop1, + c0[2] * prop0 + c1[2] * prop1 ]; }); } @@ -484,12 +484,12 @@ const t = v * (1 - (1 - f) * s); let r = 0, g = 0, b = 0; switch (i % 6) { - case 0: r = v; g = t; b = p; break; - case 1: r = q; g = v; b = p; break; - case 2: r = p; g = v; b = t; break; - case 3: r = p; g = q; b = v; break; - case 4: r = t; g = p; b = v; break; - case 5: r = v; g = p; b = q; break; + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; } return [ r, g, b ]; } @@ -610,8 +610,8 @@ } private addLineLayer(stepDuration: number, - featureData: Float32Array, - colour: Colour) { + featureData: Float32Array, + colour: Colour) { if (featureData.length === 0) { return; @@ -671,7 +671,7 @@ this.timeline.timeContext ); } - + // TODO refactor - this doesn't belong here private renderFeatures(extracted: SimpleResponse, colour: Colour): void { if (this.isOneShotExtractor && !this.hasShot) { @@ -680,11 +680,11 @@ } if (!extracted.hasOwnProperty('features') - || !extracted.hasOwnProperty('outputDescriptor')) { + || !extracted.hasOwnProperty('outputDescriptor')) { return; } if (!extracted.features.hasOwnProperty('shape') - || !extracted.features.hasOwnProperty('collected')) { + || !extracted.features.hasOwnProperty('collected')) { return; } const features: FeatureCollection = (extracted.features as FeatureCollection); @@ -697,15 +697,15 @@ case 'vector': { const collected = features.collected as VectorFeature; - const startTime = collected.startTime; //!!! + make use of - const stepDuration = collected.stepDuration; - const featureData = collected.data; - this.addLineLayer(stepDuration, featureData, colour); - break; + const startTime = collected.startTime; //!!! + make use of + const stepDuration = collected.stepDuration; + const featureData = collected.data; + this.addLineLayer(stepDuration, featureData, colour); + break; } - + case 'list': { - const featureData = features.collected as FeatureList; + const featureData = features.collected as FeatureList; if (featureData.length === 0) { return; } @@ -717,8 +717,8 @@ const isRegion = hasDuration && featureData[0].timestamp != null; console.log('Have list features: length ' + featureData.length + - ', isMarker ' + isMarker + ', isRegion ' + isRegion + - ', hasDuration ' + hasDuration); + ', isMarker ' + isMarker + ', isRegion ' + isRegion + + ', hasDuration ' + hasDuration); // TODO refactor, this is incomprehensible if (isMarker) { const plotData = featureData.map(feature => ({ @@ -807,7 +807,7 @@ break; } case 'matrix': { - const collected = features.collected as MatrixFeature; + const collected = features.collected as MatrixFeature; const startTime = collected.startTime; //!!! + make use of const stepDuration = collected.stepDuration; const matrixData = collected.data; @@ -823,8 +823,8 @@ console.log('setting gain to ' + gain); const matrixEntity = new wavesUI.utils.PrefilledMatrixEntity(matrixData, - 0, // startTime - stepDuration); + 0, // startTime + stepDuration); const matrixLayer = new wavesUI.helpers.MatrixLayer(matrixEntity, { gain, top: 0, @@ -880,17 +880,17 @@ if (mustPageForward) { const hasSkippedMultiplePages = offsetTimestamp - visibleDuration > visibleDuration; - this.timeline.timeContext.offset = hasSkippedMultiplePages ? - -currentTime + 0.5 * visibleDuration : - currentOffset - visibleDuration; + this.timeline.timeContext.offset = hasSkippedMultiplePages ? + -currentTime + 0.5 * visibleDuration : + currentOffset - visibleDuration; this.timeline.tracks.update(); } if (mustPageBackward) { const hasSkippedMultiplePages = currentTime + visibleDuration < -currentOffset; - this.timeline.timeContext.offset = hasSkippedMultiplePages ? - -currentTime + 0.5 * visibleDuration : - currentOffset + visibleDuration; + this.timeline.timeContext.offset = hasSkippedMultiplePages ? + -currentTime + 0.5 * visibleDuration : + currentOffset + visibleDuration; this.timeline.tracks.update(); }