diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-06-06 22:45:25 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-06-06 22:45:25 +0200 |
| commit | 26b80e09cd64d5bb5b40bc7872aff397d9cc80ea (patch) | |
| tree | b98217f3e7694f7e896a9bca21bc0506676f794d /app/client | |
| parent | 954c81596701e4948a7e9cc3133f601b067ba31c (diff) | |
play frames
Diffstat (limited to 'app/client')
| -rw-r--r-- | app/client/audio/pix2wav.js | 10 | ||||
| -rw-r--r-- | app/client/audio/wav2pix.js | 1 | ||||
| -rw-r--r-- | app/client/common/fileList.component.js | 12 | ||||
| -rw-r--r-- | app/client/dataset/dataset.component.js | 114 | ||||
| -rw-r--r-- | app/client/modules/pix2pix/index.js | 6 | ||||
| -rw-r--r-- | app/client/modules/pix2pix/views/pix2pix.live.js | 46 | ||||
| -rw-r--r-- | app/client/modules/pix2wav/views/spectrogram.upload.js | 33 | ||||
| -rw-r--r-- | app/client/util/index.js | 12 |
8 files changed, 152 insertions, 82 deletions
diff --git a/app/client/audio/pix2wav.js b/app/client/audio/pix2wav.js index beccc56..73dce85 100644 --- a/app/client/audio/pix2wav.js +++ b/app/client/audio/pix2wav.js @@ -9,7 +9,7 @@ import spectrum from './lib/spectrum' const _r = 8 const _i = 8 -function play(frame) { +export function play(frame) { // const { canvas, imageData } = draw.raw_spectrum(fft, 0, 256, 0, 256, 1, 1) // console.log(_r, _i) // const { canvas, imageData } = draw.raw_spectrum(player.fft, 0, 256, 0, 256, _r, _i) @@ -21,8 +21,8 @@ function play(frame) { const _p = new Tone.Player(buf) _p.connect(output) _p.start(Tone.now()) - redraw(new_fft) -} -function redraw(new_fft){ - const { canvas, imageData } = draw.raw_spectrum(new_fft, 0, 256, 0, 256, _r, _i) + // redraw(new_fft) } +// function redraw(new_fft){ +// const { canvas, imageData } = draw.raw_spectrum(new_fft, 0, 256, 0, 256, _r, _i) +// } diff --git a/app/client/audio/wav2pix.js b/app/client/audio/wav2pix.js index 1a84e16..e561bae 100644 --- a/app/client/audio/wav2pix.js +++ b/app/client/audio/wav2pix.js @@ -126,4 +126,3 @@ function render(pcm, sr, count, zip){ } return { fft, canvas, imageData } } - diff --git a/app/client/common/fileList.component.js b/app/client/common/fileList.component.js index 70ee5b6..2114acc 100644 --- a/app/client/common/fileList.component.js +++ b/app/client/common/fileList.component.js @@ -5,7 +5,7 @@ import { Link } from 'react-router-dom'; import moment from 'moment' import util from '../util' -const defaultFields = new Set(['name', 'date', 'size']) +const fieldSet = util.fieldSet(new Set(['name', 'date', 'size'])) export const FileList = props => { const { @@ -56,16 +56,6 @@ export const FileList = props => { ) } -export const fieldSet = fields => { - if (fields) { - if (fields instanceof Set) { - return fields - } - return new Set(fields.split(' ')) - } - return defaultFields -} - export const FileRow = props => { const { file, linkFiles, onDelete, onClick, className='row file', username='' } = props const fields = fieldSet(props.fields) diff --git a/app/client/dataset/dataset.component.js b/app/client/dataset/dataset.component.js index 12f7987..9de0b69 100644 --- a/app/client/dataset/dataset.component.js +++ b/app/client/dataset/dataset.component.js @@ -8,9 +8,11 @@ import actions from '../actions' import { FileList, FileRow } from '../common/fileList.component' import Loading from '../common/loading.component' +const fieldSet = util.fieldSet(new Set(['input', 'status', 'checkpoint', 'output'])) + class DatasetComponent extends Component { render(){ - const { loading, progress, module, data, folder, match, history } = this.props + let { loading, progress, fields, module, data, folder, match, history } = this.props if (loading) { return <Loading progress={progress} /> } @@ -19,20 +21,30 @@ class DatasetComponent extends Component { return history.push('/' + module.name + '/new/') } if (!folder || !folder.name) return + fields = fieldSet(fields) return ( <div class='rows params datasets'> <div class='row row-heading dataset'> - <div class='col'>input</div> - <div class='col'>status</div> - <div class='col'>checkpoint</div> - <div class='col'>output</div> + {fields.has('input') && + <div class='col'>input</div> + } + {fields.has('status') && + <div class='col'>status</div> + } + {fields.has('checkpoint') && + <div class='col'>checkpoint</div> + } + {fields.has('output') && + <div class='col'>output</div> + } </div> {this.renderGroups()} </div> ) } renderGroups(){ - const { module, data, folder, runner, onPickDataset, onPickFile, datasetActions } = this.props + let { module, data, folder, fields, runner, onPickDataset, onPickFile, datasetActions } = this.props + fields = fieldSet(fields) const { datasetLookup, fileLookup } = data const { mapFn, sortFn } = util.sort.orderByFn('date desc') const moduleOnCPU = runner && runner.cpu.task && runner.cpu.task.module === module.name @@ -51,47 +63,55 @@ class DatasetComponent extends Component { return ( <div key={dataset.name} className='row dataset' onClick={() => onPickDataset && onPickDataset(dataset)}> {this.props.beforeRow && this.props.beforeRow(dataset)} - <div className='col'> - {!!dataset.input.length && - <FileList - files={dataset.input.map(id => fileLookup[id])} - className='input_files' - fileListClassName='' - rowClassName='input_file' - fields={'name date size delete'} - onClick={onPickFile} - onDelete={(file) => this.onDeleteFile(file)} - /> - } - </div> - <div className={[ - 'col', 'quiet', - (dataset.isBuilt ? 'built' : 'not_built'), - (isProcessing ? 'processing': 'not_processing') - ].join(' ')}> - {this.props.datasetActions && this.props.datasetActions(dataset, isFetching, isProcessing)} - {status} - </div> - <div className='col checkpoint'> - {!!dataset.checkpoints.length && - <FileRow - file={dataset.checkpoints[0]} - fields={'name date epoch'} - className='row checkpoint' - /> - } - </div> - <div className='col'> - {!!dataset.output.length && - <FileList - files={dataset.output.map(id => fileLookup[id])} - orderBy='epoch desc' - fields={'name date epoch size'} - onPickFile={onPickFile} - onDelete={(file) => this.onDeleteFile(file)} - /> - } - </div> + {fields.has('input') && + <div className='col'> + {!!dataset.input.length && + <FileList + files={dataset.input.map(id => fileLookup[id])} + className='input_files' + fileListClassName='' + rowClassName='input_file' + fields={'name date size delete'} + onClick={onPickFile} + onDelete={(file) => this.onDeleteFile(file)} + /> + } + </div> + } + {fields.has('status') && + <div className={[ + 'col', 'quiet', + (dataset.isBuilt ? 'built' : 'not_built'), + (isProcessing ? 'processing': 'not_processing') + ].join(' ')}> + {this.props.datasetActions && this.props.datasetActions(dataset, isFetching, isProcessing)} + {status} + </div> + } + {fields.has('checkpoint') && + <div className='col checkpoint'> + {!!dataset.checkpoints.length && + <FileRow + file={dataset.checkpoints[0]} + fields={'name date epoch'} + className='row checkpoint' + /> + } + </div> + } + {fields.has('output') && + <div className='col'> + {!!dataset.output.length && + <FileList + files={dataset.output.map(id => fileLookup[id])} + orderBy='epoch desc' + fields={'name date epoch size'} + onPickFile={onPickFile} + onDelete={(file) => this.onDeleteFile(file)} + /> + } + </div> + } {this.props.afterRow && this.props.afterRow(dataset)} </div> ) diff --git a/app/client/modules/pix2pix/index.js b/app/client/modules/pix2pix/index.js index 076fef9..f3a4050 100644 --- a/app/client/modules/pix2pix/index.js +++ b/app/client/modules/pix2pix/index.js @@ -12,8 +12,8 @@ function router () { return ( <section> <Route exact path='/pix2pix/new/' component={Pix2PixNew} /> - <Route exact path='/pix2pix/datasets/' component={Pix2PixShow} /> - <Route exact path='/pix2pix/datasets/:id/' component={Pix2PixShow} /> + <Route exact path='/pix2pix/sequences/' component={Pix2PixShow} /> + <Route exact path='/pix2pix/sequences/:id/' component={Pix2PixShow} /> <Route exact path='/pix2pix/live/' component={Pix2PixLive} /> </section> ) @@ -22,7 +22,7 @@ function router () { function links(){ return ( <span> - <span><Link to="/pix2pix/datasets/">datasets</Link></span> + <span><Link to="/pix2pix/sequences/">sequences</Link></span> <span>train</span> <span>process</span> <span><Link to="/pix2pix/live/">live</Link></span> diff --git a/app/client/modules/pix2pix/views/pix2pix.live.js b/app/client/modules/pix2pix/views/pix2pix.live.js index eebb364..76b6727 100644 --- a/app/client/modules/pix2pix/views/pix2pix.live.js +++ b/app/client/modules/pix2pix/views/pix2pix.live.js @@ -44,6 +44,12 @@ class Pix2PixLive extends Component { const frame = Math.floor(percentage * (parseInt(this.props.frame.sequence_len) || 1) + 1) this.props.actions.seek(frame) } + start(){ + // + } + kill(){ + // + } togglePlaying(){ if (this.props.opt.processing) { this.props.actions.pause() @@ -99,12 +105,7 @@ class Pix2PixLive extends Component { value={(this.props.frame.sequence_i || 0) / (this.props.frame.sequence_len || 1)} onChange={this.seek} /> - <Button - title={'Processing: ' + (this.props.opt.processing ? 'yes' : 'no')} - onClick={this.togglePlaying} - > - {this.props.opt.processing ? 'Pause' : 'Restart'} - </Button> + {this.renderRestartButton()} <Button title={ this.props.opt.savingVideo @@ -234,6 +235,38 @@ class Pix2PixLive extends Component { </div> ) } + renderRestartButton(){ + if (this.props.runner.gpu.status === 'IDLE') { + return ( + <Button + title={'GPU Idle'} + onClick={this.start} + >Start</Button> + ) + } + if (this.props.runner.gpu.task.module !== 'pix2pix') { + return ( + <Button + title={'GPU Busy'} + onClick={this.kill} + >Kill</Button> + ) + } + if (! this.props.opt.processing) { + return ( + <Button + title={'Not processing'} + onClick={this.togglePlaying} + >Restart</Button> + ) + } + return ( + <Button + title={'Processing'} + onClick={this.togglePlaying} + >Restart</Button> + ) + } } function timeInSeconds(n){ return (n / 10).toFixed(1) + ' s.' @@ -244,6 +277,7 @@ const mapStateToProps = state => ({ checkpoints: state.live.checkpoints, epochs: state.live.epochs, sequences: state.live.sequences, + runner: state.system.runner, }) const mapDispatchToProps = (dispatch, ownProps) => ({ diff --git a/app/client/modules/pix2wav/views/spectrogram.upload.js b/app/client/modules/pix2wav/views/spectrogram.upload.js index efbfca7..111a2a7 100644 --- a/app/client/modules/pix2wav/views/spectrogram.upload.js +++ b/app/client/modules/pix2wav/views/spectrogram.upload.js @@ -14,6 +14,7 @@ import { import * as datasetActions from '../../../dataset/dataset.actions' import * as wav2pixActions from '../../../audio/wav2pix' +import * as pix2wavPlayer from '../../../audio/pix2wav' import pix2wavModule from '../pix2wav.module' @@ -30,6 +31,7 @@ class SpectrogramUpload extends Component { frames: [], frame_start: 0, max: 1000, + preview_count: 8*4, frame_step: wav2pixActions.FRAME_STEP, } const audioElement = document.createElement('audio') @@ -59,8 +61,8 @@ class SpectrogramUpload extends Component { this.audioElement.src = URL.createObjectURL(file) } rebuildFrames(){ - const { file, pcm, frame_step, frame_start } = this.state - this.props.wav2pix.renderFrames(pcm || file, { frame_start, frame_step }) + const { file, pcm, frame_step, frame_start, preview_count } = this.state + this.props.wav2pix.renderFrames(pcm || file, { frame_start, frame_step, max: preview_count }) .then(data => { console.log('got frames', data.frames.length) this.setState({ @@ -83,6 +85,12 @@ class SpectrogramUpload extends Component { ) }) } + playFrame(i){ + return () => { + const frame = this.state.frames[i] + pix2wavPlayer.play(frame) + } + } render(){ // loading={pix2wav.loading} // progress={pix2wav.progress} @@ -90,7 +98,11 @@ class SpectrogramUpload extends Component { // module={pix2wavModule} // data={pix2wav.data} // folder={folder} - const { file, frames } = this.state + const { file, frames, preview_count } = this.state + const canvases = [] + for (let i = 0, _len = preview_count; i < _len; i++) { + canvases.push(<canvas key={i} onClick={this.playFrame(i)} />) + } return ( <div className='row'> <div className='col spectrogramBuilder'> @@ -107,12 +119,14 @@ class SpectrogramUpload extends Component { {file && this.renderMetadata(file)} </Group> </div> - <div ref={(c) => { this.canvases = c }} className='thumbs' id='pix2wav_canvases' /> + <div ref={(c) => { this.canvases = c }} className='thumbs' id='pix2wav_canvases'> + {canvases} + </div> </div> ) } renderMetadata(file){ - const { duration } = this.state + const { duration, preview_count } = this.state const size = util.hush_size(file.size) const total_frame_count = Math.floor((duration * 44100 - wav2pixActions.FRAME_LENGTH) / this.state.frame_step) const frame_size = Math.round(wav2pixActions.FRAME_LENGTH / 44100 * 1000) + ' ms.' @@ -185,9 +199,12 @@ class SpectrogramUpload extends Component { ) } componentDidUpdate(){ - this.canvases.innerHTML = '' - const canvases = (this.state.frames || []).map(c => { - this.canvases.append(c.canvas) + (this.state.frames || []).map((frame, i) => { + const canvas = this.canvases.children[i] + const ctx = canvas.getContext('2d-lodpi') + canvas.width = frame.canvas.width + canvas.height = frame.canvas.height + ctx.drawImage(frame.canvas, 0, 0) }) } } diff --git a/app/client/util/index.js b/app/client/util/index.js index 4ce1245..56fdbce 100644 --- a/app/client/util/index.js +++ b/app/client/util/index.js @@ -31,10 +31,20 @@ const allProgress = (promises, progress_cb) => { document.body.style.backgroundImage = 'linear-gradient(' + (maths.randint(40)+40) + 'deg, #fde, #ffe)' +const fieldSet = defaultFields => fields => { + if (fields) { + if (fields instanceof Set) { + return fields + } + return new Set(fields.split(' ')) + } + return defaultFields +} + export default { ...maths, ...format, sort, - allProgress, + allProgress, fieldSet, is_iphone, is_ipad, is_android, is_mobile, is_desktop, } |
