summaryrefslogtreecommitdiff
path: root/app/client
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-06-06 22:45:25 +0200
committerJules Laplace <julescarbon@gmail.com>2018-06-06 22:45:25 +0200
commit26b80e09cd64d5bb5b40bc7872aff397d9cc80ea (patch)
treeb98217f3e7694f7e896a9bca21bc0506676f794d /app/client
parent954c81596701e4948a7e9cc3133f601b067ba31c (diff)
play frames
Diffstat (limited to 'app/client')
-rw-r--r--app/client/audio/pix2wav.js10
-rw-r--r--app/client/audio/wav2pix.js1
-rw-r--r--app/client/common/fileList.component.js12
-rw-r--r--app/client/dataset/dataset.component.js114
-rw-r--r--app/client/modules/pix2pix/index.js6
-rw-r--r--app/client/modules/pix2pix/views/pix2pix.live.js46
-rw-r--r--app/client/modules/pix2wav/views/spectrogram.upload.js33
-rw-r--r--app/client/util/index.js12
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,
}