Add profile saving and loading, cleanup variable names

This commit is contained in:
Kevin Thomas
2021-08-02 18:18:30 -07:00
parent 9068ffe494
commit 5170a31355
5 changed files with 228 additions and 86 deletions

View File

@@ -5,47 +5,78 @@ const router = express.Router()
router.post('/', function (req, res, next) {
if (!req.user) {
res.sendStatus(401)
return res.sendStatus(401)
}
console.log(req.body)
db.run(`INSERT INTO profiles (
name,
user,
timer_enabled,
timer_seconds,
duration,
volume,
noise_color,
filter_enabled,
filter_type,
filter_cutoff,
filter_cutoff_lfo_enabled,
filter_cutoff_lfo_rate,
filter_cutoff_lfo_min,
filter_cutoff_lfo_max,
lfo_filter_cutoff_enabled,
lfo_filter_cutoff_frequency,
lfo_filter_cutoff_low,
lfo_filter_cutoff_high,
tremolo_enabled,
tremolo_frequency,
tremolo_depth)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
req.body.name,
req.user.id,
req.body.timerEnabled,
req.body.timerSeconds,
req.body.isTimerEnabled,
req.body.duration,
req.body.volume,
req.body.noiseColor,
req.body.filterEnabled,
req.body.isFilterEnabled,
req.body.filterType,
req.body.filterCutoff,
req.body.filterCutoffLFOEnabled,
req.body.filterCutoffLFORate,
req.body.filterCutoffLFOMin,
req.body.filterCutoffLFOMax,
req.body.tremoloEnabled,
req.body.isLFOFilterCutoffEnabled,
req.body.lfoFilterCutoffFrequency,
req.body.lfoFilterCutoffLow,
req.body.lfoFilterCutoffHigh,
req.body.isTremoloEnabled,
req.body.tremoloFrequency,
req.body.tremoloDepth
],
function (err) {
// TODO: Handle error
console.log(err)
if (err) {
return res.sendStatus(500)
}
res.sendStatus(200)
}
)
})
router.get('/', function (req, res, next) {
if (!req.user) {
return res.sendStatus(401)
}
const profiles = []
db.all('SELECT name FROM profiles WHERE user = ?', [req.user.id], (err, rows) => {
if (err) {
console.log('Error getting profiles')
console.log(err)
return res.sendStatus(500)
}
rows.forEach((row) => {
profiles.push(row.name)
console.log(row.name)
});
console.log('PROFILES: ')
res.json({ profiles: profiles })
})
})
module.exports = router

View File

@@ -7,7 +7,10 @@ const router = express.Router()
router.post('/', function (req, res, next) {
const salt = crypto.randomBytes(16)
crypto.pbkdf2(req.body.password, salt, 10000, 32, 'sha256', function (err, hashedPassword) {
if (err) { return next(err) }
if (err) {
console.log(err)
res.sendStatus(500)
}
db.run('INSERT INTO users (username, hashed_password, salt, name) VALUES (?, ?, ?, ?)', [
req.body.username,
@@ -15,7 +18,10 @@ router.post('/', function (req, res, next) {
salt,
req.body.name
], function (err) {
if (err) { return next(err) }
if (err) {
console.log(err)
res.sendStatus(500)
}
const user = {
id: this.lastID.toString(),
@@ -23,10 +29,14 @@ router.post('/', function (req, res, next) {
displayName: req.body.name
}
req.login(user, function (err) {
if (err) { return next(err) }
if (err) {
console.log(err)
res.sendStatus(500)
}
})
})
})
res.sendStatus(200)
})
module.exports = router

View File

@@ -16,6 +16,67 @@
</h1>
</v-col>
<v-col cols="12">
<h2 class="headline font-weight-bold mb-5">
Profiles
</h2>
<v-select
v-model="selectedProfile"
:items="profileItems"
label="Profiles"
class="mx-3"
@click="loadProfiles"
/>
<v-dialog
v-model="profileDialog"
max-width="600px"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
v-bind="attrs"
v-on="on"
>
Save Profile
</v-btn>
</template>
<v-card>
<v-card-title>
<span class="text-h5">Profile Name</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="profileName"
label="Profile Name"
required
/>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
text
@click="profileDialog = false"
>
Close
</v-btn>
<v-btn
text
@click="saveProfile"
>
Save
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-col>
<v-col cols="12">
<h2 class="headline font-weight-bold mb-5">
Playback
@@ -23,32 +84,32 @@
<v-row justify="center">
<v-btn
:disabled="startDisabled"
:disabled="playDisabled"
class="mx-3 mb-5"
@click="playNoise"
@click="play"
>
Start
</v-btn>
<v-btn
class="mx-3 mb-5"
@click="stopTransport"
@click="stop"
>
Stop
</v-btn>
<v-checkbox
v-model="isTimerEnabled"
:disabled="startDisabled"
:disabled="playDisabled"
label="Enable Timer"
class="mx-3"
/>
<v-text-field
v-model="noiseDuration"
v-model="duration"
label="Seconds"
class="mx-3"
:disabled="startDisabled || !isTimerEnabled"
:disabled="playDisabled || !isTimerEnabled"
/>
<v-text-field
@@ -70,7 +131,7 @@
<v-row justify="center">
<v-slider
v-model="noiseVolume"
v-model="volume"
label="Volume"
thumb-label="always"
:thumb-size="40"
@@ -82,7 +143,7 @@
<v-select
v-model="noiseColor"
:items="noiseColorOptions"
:items="noiseColorItems"
label="Noise Color"
class="mx-3"
@change="updateNoiseColor"
@@ -110,26 +171,26 @@
<v-select
v-model="filterType"
:disabled="!isFilterEnabled"
:items="filterTypeOptions"
:items="filterTypeItems"
label="Filter Type"
class="mx-3"
@change="updateFilterType"
/>
<v-slider
v-model="frequencyCutoff"
:disabled="!isFilterEnabled || isFilterCutoffLFOEnabled"
v-model="filterCutoff"
:disabled="!isFilterEnabled || isLFOFilterCutoffEnabled"
label="Frequency Cutoff (Hz)"
thumb-label="always"
:thumb-size="40"
max="20000"
min="0"
class="mx-3"
@change="updateFrequencyCutoff"
@change="updateFilterCutoff"
/>
<v-checkbox
v-model="isFilterCutoffLFOEnabled"
v-model="isLFOFilterCutoffEnabled"
:disabled="!isFilterEnabled"
label="Filter Cutoff LFO"
class="mb-5"
@@ -137,28 +198,28 @@
/>
<v-slider
v-model="filterCutoffLFOFrequency"
:disabled="!isFilterCutoffLFOEnabled || !isFilterEnabled"
label="Rate (Hz)"
v-model="lfoFilterCutoffFrequency"
:disabled="!isLFOFilterCutoffEnabled || !isFilterEnabled"
label="Frequency (Hz)"
thumb-label="always"
:thumb-size="40"
max="10"
min="0.1"
step="0.1"
class="mx-3"
@change="updateFilterCutoffLFOFrequency"
@change="updateLFOFilterCutoffFrequency"
/>
<v-range-slider
v-model="filterCutoffLFORange"
:disabled="!isFilterCutoffLFOEnabled || !isFilterEnabled"
v-model="lfoFilterCutoffRange"
:disabled="!isLFOFilterCutoffEnabled || !isFilterEnabled"
label="Frequency Range (Hz)"
thumb-label="always"
:thumb-size="40"
:min="filterCutoffLFOMin"
:max="filterCutoffLFOMax"
:min="lfoFilterCutoffMin"
:max="lfoFilterCutoffMax"
class="mx-3"
@change="updateFilterCutoffLFORange"
@change="updateLFOFilterCutoffRange"
/>
</v-row>
</v-col>

View File

@@ -77,7 +77,7 @@ export default {
})
.then(response => {
if (response.status === 200) {
this.$router.push('/')
this.$router.push('/login')
}
})
.catch(function (error) {

View File

@@ -4,26 +4,26 @@ export default {
name: 'Noise',
data: () => ({
startDisabled: false,
selectedProfile: '',
profileItems: [''],
profileDialog: false,
profileName: '',
playDisabled: false,
isTimerEnabled: false,
noiseDuration: 60,
duration: 60,
timeRemaining: 0,
noiseColorOptions: ['pink', 'white', 'brown'],
noiseColor: 'pink',
noiseVolume: -10,
noiseColorItems: ['pink', 'white', 'brown'],
volume: -10,
isFilterEnabled: false,
frequencyCutoff: 20000,
filterTypeOptions: ['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'notch', 'allpass', 'peaking'],
filterCutoff: 20000,
filterType: 'lowpass',
isFilterCutoffLFOEnabled: false,
filterCutoffLFOFrequency: 1,
filterCutoffLFOMin: 0,
filterCutoffLFOMax: 20000,
filterCutoffLFORange: [100, 1000],
rules: {
number: value => !isNaN(parseInt(value, 10)) || 'Invalid number',
negative: value => (!isNaN(parseInt(value, 10)) && value <= 0) || "Can't be greater than 0"
},
filterTypeItems: ['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'notch', 'allpass', 'peaking'],
isLFOFilterCutoffEnabled: false,
lfoFilterCutoffFrequency: 1,
lfoFilterCutoffMin: 0,
lfoFilterCutoffMax: 20000,
lfoFilterCutoffRange: [100, 1000],
isTremoloEnabled: false,
tremoloFrequency: 0.5,
tremoloDepth: 0.5
@@ -35,35 +35,35 @@ export default {
this.lfo = new LFO()
},
methods: {
playNoise () {
this.startDisabled = true
play () {
this.playDisabled = true
Transport.cancel()
// TODO: This conditional logic can be improved
if (!this.isFilterEnabled && !this.isTremoloEnabled) {
this.noise = new Noise({ volume: this.noiseVolume, type: this.noiseColor }).toDestination()
this.noise = new Noise({ volume: this.volume, type: this.noiseColor }).toDestination()
} else if (!this.isFilterEnabled && this.isTremoloEnabled) {
this.tremolo = new Tremolo({ frequency: this.tremoloFrequency, depth: this.tremoloDepth }).toDestination().start()
this.noise = new Noise({ volume: this.noiseVolume, type: this.noiseColor }).connect(this.tremolo)
this.noise = new Noise({ volume: this.volume, type: this.noiseColor }).connect(this.tremolo)
} else if (this.isFilterEnabled && !this.isTremoloEnabled) {
this.filter = new Filter(this.frequencyCutoff, this.filterType).toDestination()
this.noise = new Noise({ volume: this.noiseVolume, type: this.noiseColor }).connect(this.filter)
this.filter = new Filter(this.filterCutoff, this.filterType).toDestination()
this.noise = new Noise({ volume: this.volume, type: this.noiseColor }).connect(this.filter)
} else {
this.tremolo = new Tremolo({ frequency: this.tremoloFrequency, depth: this.tremoloDepth }).toDestination().start()
this.filter = new Filter(this.frequencyCutoff, this.filterType).connect(this.tremolo)
this.noise = new Noise({ volume: this.noiseVolume, type: this.noiseColor }).connect(this.filter)
this.filter = new Filter(this.filterCutoff, this.filterType).connect(this.tremolo)
this.noise = new Noise({ volume: this.volume, type: this.noiseColor }).connect(this.filter)
}
if (this.isFilterCutoffLFOEnabled) {
this.lfo = new LFO({ frequency: this.filterCutoffLFOFrequency, min: this.filterCutoffLFORange[0], max: this.filterCutoffLFORange[1] })
if (this.isLFOFilterCutoffEnabled) {
this.lfo = new LFO({ frequency: this.lfoFilterCutoffFrequency, min: this.lfoFilterCutoffRange[0], max: this.lfoFilterCutoffRange[1] })
this.lfo.connect(this.filter.frequency).start()
}
if (this.isTimerEnabled) {
this.noise.sync().start(0).stop(this.noiseDuration)
Transport.loopEnd = this.noiseDuration
this.timeRemaining = this.noiseDuration
this.transportInterval = setInterval(() => this.stopTransport(), this.noiseDuration * 1000 + 100)
this.noise.sync().start(0).stop(this.duration)
Transport.loopEnd = this.duration
this.timeRemaining = this.duration
this.transportInterval = setInterval(() => this.stopTransport(), this.duration * 1000 + 100)
this.timeRemainingInterval = setInterval(() => this.startTimer(), 1000)
} else {
this.noise.sync().start(0)
@@ -71,10 +71,10 @@ export default {
Transport.start()
},
stopTransport () {
stop () {
clearInterval(this.transportInterval)
Transport.stop()
this.startDisabled = false
this.playDisabled = false
clearInterval(this.timeRemainingInterval)
this.timeRemaining = 0
@@ -83,7 +83,7 @@ export default {
this.timeRemaining -= 1
},
updateVolume () {
this.noise.volume.value = this.noiseVolume
this.noise.volume.value = this.volume
},
updateNoiseColor () {
this.noise.type = this.noiseColor
@@ -91,14 +91,14 @@ export default {
updateFilterType () {
this.filter.type = this.filterType
},
updateFrequencyCutoff () {
this.filter.set({ frequency: this.frequencyCutoff })
updateFilterCutoff () {
this.filter.set({ frequency: this.filterCutoff })
},
updateFilterCutoffLFOFrequency () {
this.lfo.set({ frequency: this.filterCutoffLFOFrequency })
updateLFOFilterCutoffFrequency () {
this.lfo.set({ frequency: this.lfoFilterCutoffFrequency })
},
updateFilterCutoffLFORange () {
this.lfo.set({ min: this.filterCutoffLFORange[0], max: this.filterCutoffLFORange[1] })
updateLFOFilterCutoffRange () {
this.lfo.set({ min: this.lfoFilterCutoffRange[0], max: this.lfoFilterCutoffRange[1] })
},
updateTremoloFrequency () {
this.tremolo.set({ frequency: this.tremoloFrequency })
@@ -115,21 +115,61 @@ export default {
} else if (!this.isFilterEnabled && this.isTremoloEnabled) {
this.tremolo = new Tremolo({ frequency: this.tremoloFrequency, depth: this.tremoloDepth }).toDestination().start()
this.noise.connect(this.tremolo)
} else if (this.isFilterEnabled && !this.isFilterCutoffLFOEnabled && !this.isTremoloEnabled) {
this.filter = new Filter(this.frequencyCutoff, this.filterType).toDestination()
} else if (this.isFilterEnabled && !this.isLFOFilterCutoffEnabled && !this.isTremoloEnabled) {
this.filter = new Filter(this.filterCutoff, this.filterType).toDestination()
this.noise.connect(this.filter)
this.lfo.disconnect()
this.lfo.stop()
} else if (this.isFilterEnabled && this.isFilterCutoffLFOEnabled && !this.isTremoloEnabled) {
this.filter = new Filter(this.frequencyCutoff, this.filterType).toDestination()
} else if (this.isFilterEnabled && this.isLFOFilterCutoffEnabled && !this.isTremoloEnabled) {
this.filter = new Filter(this.filterCutoff, this.filterType).toDestination()
this.noise.connect(this.filter)
this.lfo = new LFO({ frequency: this.filterCutoffLFOFrequency, min: this.filterCutoffLFORange[0], max: this.filterCutoffLFORange[1] })
this.lfo = new LFO({ frequency: this.lfoFilterCutoffFrequency, min: this.lfoFilterCutoffRange[0], max: this.lfoFilterCutoffRange[1] })
this.lfo.connect(this.filter.frequency).start()
} else {
this.tremolo = new Tremolo({ frequency: this.tremoloFrequency, depth: this.tremoloDepth }).toDestination().start()
this.filter = new Filter(this.frequencyCutoff, this.filterType).connect(this.tremolo)
this.filter = new Filter(this.filterCutoff, this.filterType).connect(this.tremolo)
this.noise.connect(this.filter)
}
},
loadProfiles () {
this.$http.get('https://localhost:3000/profiles')
.then(response => {
if (response.status === 200) {
this.profileItems = response.data.profiles
}
})
.catch(function (error) {
console.error(error.response)
})
},
saveProfile () {
this.$http.post('https://localhost:3000/profiles', {
name: this.profileName,
isTimerEnabled: this.isTimerEnabled ? 1 : 0,
duration: this.duration,
volume: this.volume,
noiseColor: this.noiseColor,
isFilterEnabled: this.isFilterEnabled ? 1 : 0,
filterType: this.filterType,
filterCutoff: this.filterCutoff,
isLFOFilterCutoffEnabled: this.isLFOFilterCutoffEnabled ? 1 : 0,
lfoFilterCutoffFrequency: this.lfoFilterCutoffFrequency,
lfoFilterCutoffLow: this.lfoFilterCutoffRange[0],
lfoFilterCutoffHigh: this.lfoFilterCutoffRange[1],
isTremoloEnabled: this.isTremoloEnabled ? 1 : 0,
tremoloFrequency: this.tremoloFrequency,
tremoloDepth: this.tremoloDepth
})
.then(response => {
if (response.status === 200) {
console.log('Profile saved')
}
})
.catch(function (error) {
console.error(error.response)
})
this.profileDialog = false
}
}
}