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) { router.post('/', function (req, res, next) {
if (!req.user) { if (!req.user) {
res.sendStatus(401) return res.sendStatus(401)
} }
console.log(req.body)
db.run(`INSERT INTO profiles ( db.run(`INSERT INTO profiles (
name, name,
user, user,
timer_enabled, timer_enabled,
timer_seconds, duration,
volume, volume,
noise_color, noise_color,
filter_enabled, filter_enabled,
filter_type, filter_type,
filter_cutoff, filter_cutoff,
filter_cutoff_lfo_enabled, lfo_filter_cutoff_enabled,
filter_cutoff_lfo_rate, lfo_filter_cutoff_frequency,
filter_cutoff_lfo_min, lfo_filter_cutoff_low,
filter_cutoff_lfo_max, lfo_filter_cutoff_high,
tremolo_enabled, tremolo_enabled,
tremolo_frequency, tremolo_frequency,
tremolo_depth) tremolo_depth)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
req.body.name, req.body.name,
req.user.id, req.user.id,
req.body.timerEnabled, req.body.isTimerEnabled,
req.body.timerSeconds, req.body.duration,
req.body.volume, req.body.volume,
req.body.noiseColor, req.body.noiseColor,
req.body.filterEnabled, req.body.isFilterEnabled,
req.body.filterType, req.body.filterType,
req.body.filterCutoff, req.body.filterCutoff,
req.body.filterCutoffLFOEnabled, req.body.isLFOFilterCutoffEnabled,
req.body.filterCutoffLFORate, req.body.lfoFilterCutoffFrequency,
req.body.filterCutoffLFOMin, req.body.lfoFilterCutoffLow,
req.body.filterCutoffLFOMax, req.body.lfoFilterCutoffHigh,
req.body.tremoloEnabled, req.body.isTremoloEnabled,
req.body.tremoloFrequency, req.body.tremoloFrequency,
req.body.tremoloDepth req.body.tremoloDepth
], ],
function (err) { function (err) {
// TODO: Handle error if (err) {
console.log(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) { router.post('/', function (req, res, next) {
const salt = crypto.randomBytes(16) const salt = crypto.randomBytes(16)
crypto.pbkdf2(req.body.password, salt, 10000, 32, 'sha256', function (err, hashedPassword) { 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 (?, ?, ?, ?)', [ db.run('INSERT INTO users (username, hashed_password, salt, name) VALUES (?, ?, ?, ?)', [
req.body.username, req.body.username,
@@ -15,7 +18,10 @@ router.post('/', function (req, res, next) {
salt, salt,
req.body.name req.body.name
], function (err) { ], function (err) {
if (err) { return next(err) } if (err) {
console.log(err)
res.sendStatus(500)
}
const user = { const user = {
id: this.lastID.toString(), id: this.lastID.toString(),
@@ -23,10 +29,14 @@ router.post('/', function (req, res, next) {
displayName: req.body.name displayName: req.body.name
} }
req.login(user, function (err) { req.login(user, function (err) {
if (err) { return next(err) } if (err) {
console.log(err)
res.sendStatus(500)
}
}) })
}) })
}) })
res.sendStatus(200)
}) })
module.exports = router module.exports = router

View File

@@ -16,6 +16,67 @@
</h1> </h1>
</v-col> </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"> <v-col cols="12">
<h2 class="headline font-weight-bold mb-5"> <h2 class="headline font-weight-bold mb-5">
Playback Playback
@@ -23,32 +84,32 @@
<v-row justify="center"> <v-row justify="center">
<v-btn <v-btn
:disabled="startDisabled" :disabled="playDisabled"
class="mx-3 mb-5" class="mx-3 mb-5"
@click="playNoise" @click="play"
> >
Start Start
</v-btn> </v-btn>
<v-btn <v-btn
class="mx-3 mb-5" class="mx-3 mb-5"
@click="stopTransport" @click="stop"
> >
Stop Stop
</v-btn> </v-btn>
<v-checkbox <v-checkbox
v-model="isTimerEnabled" v-model="isTimerEnabled"
:disabled="startDisabled" :disabled="playDisabled"
label="Enable Timer" label="Enable Timer"
class="mx-3" class="mx-3"
/> />
<v-text-field <v-text-field
v-model="noiseDuration" v-model="duration"
label="Seconds" label="Seconds"
class="mx-3" class="mx-3"
:disabled="startDisabled || !isTimerEnabled" :disabled="playDisabled || !isTimerEnabled"
/> />
<v-text-field <v-text-field
@@ -70,7 +131,7 @@
<v-row justify="center"> <v-row justify="center">
<v-slider <v-slider
v-model="noiseVolume" v-model="volume"
label="Volume" label="Volume"
thumb-label="always" thumb-label="always"
:thumb-size="40" :thumb-size="40"
@@ -82,7 +143,7 @@
<v-select <v-select
v-model="noiseColor" v-model="noiseColor"
:items="noiseColorOptions" :items="noiseColorItems"
label="Noise Color" label="Noise Color"
class="mx-3" class="mx-3"
@change="updateNoiseColor" @change="updateNoiseColor"
@@ -110,26 +171,26 @@
<v-select <v-select
v-model="filterType" v-model="filterType"
:disabled="!isFilterEnabled" :disabled="!isFilterEnabled"
:items="filterTypeOptions" :items="filterTypeItems"
label="Filter Type" label="Filter Type"
class="mx-3" class="mx-3"
@change="updateFilterType" @change="updateFilterType"
/> />
<v-slider <v-slider
v-model="frequencyCutoff" v-model="filterCutoff"
:disabled="!isFilterEnabled || isFilterCutoffLFOEnabled" :disabled="!isFilterEnabled || isLFOFilterCutoffEnabled"
label="Frequency Cutoff (Hz)" label="Frequency Cutoff (Hz)"
thumb-label="always" thumb-label="always"
:thumb-size="40" :thumb-size="40"
max="20000" max="20000"
min="0" min="0"
class="mx-3" class="mx-3"
@change="updateFrequencyCutoff" @change="updateFilterCutoff"
/> />
<v-checkbox <v-checkbox
v-model="isFilterCutoffLFOEnabled" v-model="isLFOFilterCutoffEnabled"
:disabled="!isFilterEnabled" :disabled="!isFilterEnabled"
label="Filter Cutoff LFO" label="Filter Cutoff LFO"
class="mb-5" class="mb-5"
@@ -137,28 +198,28 @@
/> />
<v-slider <v-slider
v-model="filterCutoffLFOFrequency" v-model="lfoFilterCutoffFrequency"
:disabled="!isFilterCutoffLFOEnabled || !isFilterEnabled" :disabled="!isLFOFilterCutoffEnabled || !isFilterEnabled"
label="Rate (Hz)" label="Frequency (Hz)"
thumb-label="always" thumb-label="always"
:thumb-size="40" :thumb-size="40"
max="10" max="10"
min="0.1" min="0.1"
step="0.1" step="0.1"
class="mx-3" class="mx-3"
@change="updateFilterCutoffLFOFrequency" @change="updateLFOFilterCutoffFrequency"
/> />
<v-range-slider <v-range-slider
v-model="filterCutoffLFORange" v-model="lfoFilterCutoffRange"
:disabled="!isFilterCutoffLFOEnabled || !isFilterEnabled" :disabled="!isLFOFilterCutoffEnabled || !isFilterEnabled"
label="Frequency Range (Hz)" label="Frequency Range (Hz)"
thumb-label="always" thumb-label="always"
:thumb-size="40" :thumb-size="40"
:min="filterCutoffLFOMin" :min="lfoFilterCutoffMin"
:max="filterCutoffLFOMax" :max="lfoFilterCutoffMax"
class="mx-3" class="mx-3"
@change="updateFilterCutoffLFORange" @change="updateLFOFilterCutoffRange"
/> />
</v-row> </v-row>
</v-col> </v-col>

View File

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

View File

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