Skip to content

Commit a5134de

Browse files
committed
Updated interpolation functions.
1 parent 5fab99f commit a5134de

File tree

8 files changed

+66
-34
lines changed

8 files changed

+66
-34
lines changed

css/index.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ footer {
8686
a, p {
8787
font-size: 12px;
8888
display: inline-block;
89-
margin: 0 12px;
89+
margin: 0 12px 0 0;
9090
font-weight: 400;
9191
letter-spacing: 0.06em;
9292
}

src/App.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class App extends React.Component {
8282
}
8383
<header>
8484
<div>
85-
<h1>Dog Synth</h1>
85+
<h1>Wavetable</h1>
8686
<HorizontalSlider
8787
id='master'
8888
name='master gain'
@@ -139,7 +139,6 @@ class App extends React.Component {
139139
<a onClick={this.onOpenAboutModal.bind(this)}>About</a>
140140
<a onClick={this.onOpenSavePatchModal.bind(this)}>Save Patch</a>
141141
<ShareButtonRow />
142-
<p>Made By Elegant Borzoi and Jordan</p>
143142
<p>
144143
<a href='https://github.com/looshi/wavetable-synth-2'>
145144
View Source Code on Github

src/data/Reducers.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,12 @@ function LFOsReducer (state, action) {
329329
}
330330

331331
// Update the computed waveform based on the current algorithm.
332-
function computeWaveform (channelDataA, channelDataB, algorithm) {
332+
function computeWaveform (channelDataA, channelDataB, algorithm, cycles) {
333333
if (!channelDataA || !channelDataB || !algorithm) {
334334
return []
335335
}
336336

337-
let cycles = 256 // 1 can be min. 1024 might be a good max.
338-
let samplesCount = (600 * cycles) // - (overlap * cycles)
337+
let samplesCount = (600 * cycles)
339338
let interpolatedData = new Float32Array(samplesCount * 2)
340339
let time = 0
341340

@@ -350,20 +349,24 @@ function computeWaveform (channelDataA, channelDataB, algorithm) {
350349
time = (k - samplesCount) / (samplesCount) // Time starts at half way point.
351350
interpolatedData[k] = slerp(channelDataB[k % 600], channelDataA[k % 600], time, algorithm)
352351
}
352+
353353
return interpolatedData
354354
}
355355

356356
// Modified lerp function based on algorithm chosen.
357357
// The 'minus' algorithm uses the normal lerp function.
358358
function slerp (v0, v1, t, algorithm) {
359359
if (algorithm === 'p') {
360-
return limit(-1, 1, v0 * (1 + t) + v1 * t) || 0.00001
361-
} else if (algorithm === 'm') {
362360
return limit(-1, 1, v0 * (1 - t) + v1 * t) || 0.00001 // Normal lerp function.
361+
} else if (algorithm === 'm') {
362+
t = Math.pow(t, 5)
363+
return limit(-1, 1, v0 * (1 - t) + v1 * t) || 0.00001
363364
} else if (algorithm === 'd') {
364-
return limit(-1, 1, v0 * (1 / t) + v1 * t) || 0.00001
365+
t = Math.pow(t, 20)
366+
return limit(-1, 1, v0 * (1 - t) + v1 * t) || 0.00001
365367
} else if (algorithm === 'x') {
366-
return limit(-1, 1, v0 * (1 * t) + v1 * t) || 0.00001
368+
t = Math.log(t + 1)
369+
return limit(-1, 1, v0 * (1 + t) + v1 * t) || 0.00001
367370
}
368371
}
369372

@@ -407,9 +410,12 @@ function OscillatorsReducer (state, action) {
407410
} else if (action.side === 'B') {
408411
osc.channelDataB = action.channelData
409412
}
410-
// When both files have loaded, compute the combined waveform.
411-
if (osc.channelDataA.length && osc.channelDataB.length) {
412-
osc.computedChannelData = computeWaveform(osc.channelDataA, osc.channelDataB, osc.algorithm)
413+
// If both are noise, just return noise.
414+
if (osc.fileA === 'noise' && osc.fileB === 'noise') {
415+
osc.computedChannelData = osc.channelDataA
416+
} else if (osc.channelDataA.length && osc.channelDataB.length) {
417+
// When both files have loaded, compute the combined waveform.
418+
osc.computedChannelData = computeWaveform(osc.channelDataA, osc.channelDataB, osc.algorithm, osc.cycles)
413419
}
414420
}
415421
return osc
@@ -422,8 +428,12 @@ function OscillatorsReducer (state, action) {
422428
if (osc.id === action.id) {
423429
osc.algorithm = action.algorithm
424430
updateURL(osc.id + 'al', action.algorithm)
431+
if (osc.fileA === 'noise' && osc.fileB === 'noise') {
432+
osc.computedChannelData = osc.channelDataA
433+
} else {
434+
osc.computedChannelData = computeWaveform(osc.channelDataA, osc.channelDataB, osc.algorithm, osc.cycles)
435+
}
425436
}
426-
osc.computedChannelData = computeWaveform(osc.channelDataA, osc.channelDataB, osc.algorithm)
427437
return osc
428438
})
429439
return [...state]
@@ -439,11 +449,17 @@ function OscillatorsReducer (state, action) {
439449
// Updates local osc values, detune, octave, and amt.
440450
case 'OSC_CYCLES_CHANGED':
441451
state = state.map(function (osc) {
442-
if (osc.id === action.id) {
452+
if (osc.id === action.id && osc.cycles !== action.value) {
443453
osc.cycles = action.value
444454
const paramName = osc.id + 'c' // id + first letter of param.
445455
updateURL(paramName, action.value)
456+
if (osc.fileA === 'noise' && osc.fileB === 'noise') {
457+
osc.computedChannelData = osc.channelDataA
458+
} else {
459+
osc.computedChannelData = computeWaveform(osc.channelDataA, osc.channelDataB, osc.algorithm, osc.cycles)
460+
}
446461
}
462+
447463
return osc
448464
})
449465
return [...state]

src/views/Components/HorizontalSlider.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Label, slider, and number value.
44
*/
55
import React from 'react'
66
import {connect} from 'react-redux'
7-
import Actions from '../../data/Actions.js'
87
import {lerp} from '../../helpers/helpers.js'
98

109
class HorizontalSlider extends React.Component {

src/views/Oscillator/OscillatorView.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ import AlgorithmSwitch from './AlgorithmSwitch.js'
1111
import HorizontalSlider from '../Components/HorizontalSlider.js'
1212
import {connect} from 'react-redux'
1313
import Actions from '../../data/Actions.js'
14+
import _ from 'lodash'
1415

1516
class OscillatorView extends React.Component {
17+
constructor (props) {
18+
super(props)
19+
this.debouncedAction = _.debounce((id, value) => {
20+
let action = Actions.oscCyclesChanged(id, value)
21+
this.props.dispatch(action)
22+
}, 200)
23+
}
1624

1725
onCyclesChanged (e) {
18-
let action = Actions.oscCyclesChanged(this.props.id, Number(e.target.value))
19-
this.props.dispatch(action)
26+
this.debouncedAction(this.props.id, Number(e.target.value))
2027
}
2128

2229
onDetuneChanged (e) {
@@ -88,16 +95,6 @@ class OscillatorView extends React.Component {
8895
channelData={this.props.computedChannelData} />
8996
</div>
9097
<div className='oscillator-sliders'>
91-
<HorizontalSlider
92-
id={this.props.id}
93-
name='cycles'
94-
label='cycles'
95-
min={1}
96-
max={1024}
97-
step={1}
98-
onChange={this.onCyclesChanged.bind(this)}
99-
color={this.props.color}
100-
value={this.props.cycles} />
10198
<HorizontalSlider
10299
id={this.props.id}
103100
name='detune'
@@ -128,6 +125,16 @@ class OscillatorView extends React.Component {
128125
onChange={this.onAmountChanged.bind(this)}
129126
color={this.props.color}
130127
value={this.props.amount} />
128+
<HorizontalSlider
129+
id={this.props.id}
130+
name='cycles'
131+
label='cycles'
132+
min={1}
133+
max={1024}
134+
step={1}
135+
onChange={this.onCyclesChanged.bind(this)}
136+
color={this.props.color}
137+
value={this.props.cycles} />
131138
</div>
132139

133140
</div>

src/views/Oscillator/WaveFileLoader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class WaveFileLoader extends React.Component {
4444
// of noise here. All other waves are 600 samples long.
4545
let channelData = new Float32Array(44100)
4646
for (var i = 0; i < 44100; i++) {
47-
channelData[i] = Math.random()
47+
channelData[i] = Math.random() * 2 - 1
4848
}
4949
let action = Actions.waveFileLoadCompleted(id, side, channelData)
5050
dispatch(action)

src/views/Oscillator/WaveLine.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@ class WaveLine extends React.Component {
2323

2424
// Check every 100th sample ( about 6 times ) to see if the data changed.
2525
let hasChanged = false
26-
for (var i = 0; i < nextProps.channelData.length; i += 100) {
26+
let longestLength = 0
27+
28+
if (this.props.channelData.length > nextProps.channelData.length) {
29+
longestLength = this.props.channelData.length
30+
} else {
31+
longestLength = nextProps.channelData.length
32+
}
33+
34+
for (var i = 0; i < longestLength; i += 100) {
2735
if (nextProps.channelData[i] !== this.props.channelData[i]) {
2836
hasChanged = true
2937
}
@@ -67,15 +75,17 @@ class WaveLine extends React.Component {
6775
}
6876

6977
const context = this.refs.canvas.getContext('2d')
78+
let lineWidth = channelData.length < (4 * 600) ? 3 : 2
79+
7080
context.clearRect(0, 0, width, height)
71-
this.drawWave(context, width, height, marginLeft, marginTop)
81+
this.drawWave(context, width, height, marginLeft, marginTop, lineWidth)
7282
}
7383

74-
drawWave (context, width, height, marginLeft, marginTop) {
84+
drawWave (context, width, height, marginLeft, marginTop, lineWidth) {
7585
let time = 0
7686
let yValue = 0
7787
let self = this
78-
context.lineWidth = 3
88+
context.lineWidth = lineWidth
7989
context.strokeStyle = this.props.color
8090

8191
function step () {

src/views/ShareButtons/ShareButtonRow.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ const ShareButtonRow = React.createClass({
3737
size={24}
3838
round />
3939
</FacebookShareButton>
40-
40+
{/*
4141
<FacebookShareCount
4242
url={shareUrl}
4343
className='share-count'>
4444
{count => count}
4545
</FacebookShareCount>
46+
*/}
4647
</div>
4748

4849
<div className='share-button-container'>

0 commit comments

Comments
 (0)