mirror of
https://github.com/kaythomas0/noisedash.git
synced 2025-11-14 12:18:01 +00:00
341 lines
12 KiB
JavaScript
341 lines
12 KiB
JavaScript
import { Filter, LFO, Noise, Players, Transport, Tremolo } from 'tone'
|
|
|
|
export default {
|
|
name: 'Noise',
|
|
|
|
data: () => ({
|
|
isTimerValid: false,
|
|
selectedProfile: {},
|
|
profileItems: [],
|
|
profileDialog: false,
|
|
profileName: '',
|
|
isProfileValid: false,
|
|
playDisabled: false,
|
|
isTimerEnabled: false,
|
|
hours: 0,
|
|
minutes: 0,
|
|
seconds: 30,
|
|
duration: 30,
|
|
timeRemaining: 0,
|
|
noiseColor: 'pink',
|
|
noiseColorItems: ['pink', 'white', 'brown'],
|
|
volume: -10,
|
|
isFilterEnabled: false,
|
|
filterCutoff: 20000,
|
|
filterType: 'lowpass',
|
|
filterTypeItems: ['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'notch', 'allpass', 'peaking'],
|
|
isLFOFilterCutoffEnabled: false,
|
|
lfoFilterCutoffFrequency: 0.5,
|
|
lfoFilterCutoffMin: 0,
|
|
lfoFilterCutoffMax: 20000,
|
|
lfoFilterCutoffRange: [100, 5000],
|
|
isTremoloEnabled: false,
|
|
tremoloFrequency: 0.5,
|
|
tremoloDepth: 0.5,
|
|
allSamples: [],
|
|
loadedSamples: [],
|
|
selectedSample: null,
|
|
uploadSampleDialog: false,
|
|
addSampleDialog: false,
|
|
checkedSamples: [],
|
|
sampleName: '',
|
|
file: null,
|
|
isSampleUploadValid: false,
|
|
rules: {
|
|
lt (n) {
|
|
return value => (!isNaN(parseInt(value, 10)) && value < n) || 'Must be less than ' + n
|
|
},
|
|
gt (n) {
|
|
return value => (!isNaN(parseInt(value, 10)) && value > n) || 'Must be greater than ' + n
|
|
},
|
|
required () {
|
|
return value => !!value || 'Required'
|
|
}
|
|
}
|
|
}),
|
|
computed: {
|
|
unloadedSamples: function () {
|
|
const samples = []
|
|
this.allSamples.forEach(s1 => {
|
|
const result = this.loadedSamples.find(s2 => s2.id === s1.id)
|
|
if (!result) {
|
|
samples.push(s1)
|
|
}
|
|
})
|
|
return samples
|
|
}
|
|
},
|
|
created () {
|
|
this.noise = new Noise()
|
|
this.filter = new Filter()
|
|
this.tremolo = new Tremolo()
|
|
this.lfo = new LFO()
|
|
this.players = new Players()
|
|
this.populateProfileItems()
|
|
this.getSamples()
|
|
},
|
|
methods: {
|
|
play () {
|
|
this.playDisabled = true
|
|
Transport.cancel()
|
|
|
|
// TODO: This conditional logic can be improved
|
|
if (!this.isFilterEnabled && !this.isTremoloEnabled) {
|
|
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.volume, type: this.noiseColor }).connect(this.tremolo)
|
|
} else if (this.isFilterEnabled && !this.isTremoloEnabled) {
|
|
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.filterCutoff, this.filterType).connect(this.tremolo)
|
|
this.noise = new Noise({ volume: this.volume, type: this.noiseColor }).connect(this.filter)
|
|
}
|
|
|
|
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.duration = parseInt((this.hours * 3600)) + parseInt((this.minutes * 60)) + parseInt(this.seconds)
|
|
this.noise.sync().start(0).stop(this.duration)
|
|
Transport.loopEnd = this.duration
|
|
this.timeRemaining = this.duration
|
|
this.transportInterval = setInterval(() => this.stop(), this.duration * 1000 + 100)
|
|
this.timeRemainingInterval = setInterval(() => this.startTimer(), 1000)
|
|
|
|
this.loadedSamples.forEach(s => {
|
|
this.players.player(s.id).unsync().sync().start(0).stop(this.duration)
|
|
})
|
|
} else {
|
|
this.noise.sync().start(0)
|
|
|
|
this.loadedSamples.forEach(s => {
|
|
this.players.player(s.id).unsync().sync().start(0)
|
|
})
|
|
}
|
|
|
|
Transport.start()
|
|
},
|
|
stop () {
|
|
clearInterval(this.transportInterval)
|
|
Transport.stop()
|
|
this.playDisabled = false
|
|
|
|
clearInterval(this.timeRemainingInterval)
|
|
this.timeRemaining = 0
|
|
this.duration = 0
|
|
},
|
|
startTimer () {
|
|
this.timeRemaining -= 1
|
|
},
|
|
updateVolume () {
|
|
this.noise.volume.value = this.volume
|
|
},
|
|
updateNoiseColor () {
|
|
this.noise.type = this.noiseColor
|
|
},
|
|
updateFilterType () {
|
|
this.filter.type = this.filterType
|
|
},
|
|
updateFilterCutoff () {
|
|
this.filter.set({ frequency: this.filterCutoff })
|
|
},
|
|
updateLFOFilterCutoffFrequency () {
|
|
this.lfo.set({ frequency: this.lfoFilterCutoffFrequency })
|
|
},
|
|
updateLFOFilterCutoffRange () {
|
|
this.lfo.set({ min: this.lfoFilterCutoffRange[0], max: this.lfoFilterCutoffRange[1] })
|
|
},
|
|
updateTremoloFrequency () {
|
|
this.tremolo.set({ frequency: this.tremoloFrequency })
|
|
},
|
|
updateTremoloDepth () {
|
|
this.tremolo.set({ depth: this.tremoloDepth })
|
|
},
|
|
updateAudioChain () {
|
|
this.noise.disconnect()
|
|
|
|
// TODO: This conditional logic can be improved
|
|
if (!this.isFilterEnabled && !this.isTremoloEnabled) {
|
|
this.noise.toDestination()
|
|
} 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.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.isLFOFilterCutoffEnabled && !this.isTremoloEnabled) {
|
|
this.filter = new Filter(this.filterCutoff, this.filterType).toDestination()
|
|
this.noise.connect(this.filter)
|
|
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.filterCutoff, this.filterType).connect(this.tremolo)
|
|
this.noise.connect(this.filter)
|
|
}
|
|
},
|
|
populateProfileItems () {
|
|
this.$http.get('/profiles')
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
if (response.data.profiles.length === 0) {
|
|
this.addDefaultProfile()
|
|
} else {
|
|
this.profileItems = response.data.profiles
|
|
this.selectedProfile = this.profileItems[0]
|
|
}
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
},
|
|
addDefaultProfile () {
|
|
this.$http.post('/profiles/default')
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
this.selectedProfile = { id: response.data.id, text: 'Default' }
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
},
|
|
saveProfile () {
|
|
this.$http.post('/profiles', {
|
|
name: this.profileName,
|
|
isTimerEnabled: this.isTimerEnabled,
|
|
duration: this.duration,
|
|
volume: this.volume,
|
|
noiseColor: this.noiseColor,
|
|
isFilterEnabled: this.isFilterEnabled,
|
|
filterType: this.filterType,
|
|
filterCutoff: this.filterCutoff,
|
|
isLFOFilterCutoffEnabled: this.isLFOFilterCutoffEnabled,
|
|
lfoFilterCutoffFrequency: this.lfoFilterCutoffFrequency,
|
|
lfoFilterCutoffLow: this.lfoFilterCutoffRange[0],
|
|
lfoFilterCutoffHigh: this.lfoFilterCutoffRange[1],
|
|
isTremoloEnabled: this.isTremoloEnabled,
|
|
tremoloFrequency: this.tremoloFrequency,
|
|
tremoloDepth: this.tremoloDepth,
|
|
samples: this.loadedSamples
|
|
}).then(response => {
|
|
const id = response.data.id
|
|
if (response.status === 200) {
|
|
this.profileDialog = false
|
|
this.populateProfileItems()
|
|
|
|
this.$http.get('/profiles')
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
this.profileItems = response.data.profiles
|
|
this.selectedProfile = { id: id, text: this.profileName }
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
},
|
|
loadProfile () {
|
|
this.$http.get('/profiles/'.concat(this.selectedProfile.id))
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
const profile = response.data.profile
|
|
|
|
this.isTimerEnabled = profile.isTimerEnabled
|
|
this.duration = profile.duration
|
|
this.volume = profile.volume
|
|
this.noiseColor = profile.noiseColor
|
|
this.isFilterEnabled = profile.isFilterEnabled
|
|
this.filterType = profile.filterType
|
|
this.filterCutoff = profile.filterCutoff
|
|
this.isLFOFilterCutoffEnabled = profile.isLFOFilterCutoffEnabled
|
|
this.lfoFilterCutoffFrequency = profile.lfoFilterCutoffFrequency
|
|
this.lfoFilterCutoffRange[0] = profile.lfoFilterCutoffLow
|
|
this.lfoFilterCutoffRange[1] = profile.lfoFilterCutoffHigh
|
|
this.isTremoloEnabled = profile.isTremoloEnabled
|
|
this.tremoloFrequency = profile.tremoloFrequency
|
|
this.tremoloDepth = profile.tremoloDepth
|
|
|
|
this.loadedSamples = profile.samples
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
},
|
|
deleteProfile () {
|
|
this.$http.delete('/profiles/'.concat(this.selectedProfile.id))
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
this.populateProfileItems()
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
},
|
|
getSamples () {
|
|
this.$http.get('/samples')
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
this.allSamples = response.data.samples
|
|
this.allSamples.forEach(s => {
|
|
if (!this.players.has(s.id)) {
|
|
this.players.add(s.id, '/samples/' + s.name).toDestination()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error)
|
|
})
|
|
},
|
|
uploadSample () {
|
|
const formData = new FormData()
|
|
|
|
formData.append('name', this.sampleName)
|
|
formData.append('sample', this.selectedSample)
|
|
|
|
this.$http.post('/samples', formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data'
|
|
}
|
|
})
|
|
.then(response => {
|
|
if (response.status === 200) {
|
|
this.getSamples()
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error(error.response)
|
|
})
|
|
|
|
this.uploadSampleDialog = false
|
|
},
|
|
addSample () {
|
|
this.checkedSamples.forEach(i => {
|
|
const load = this.allSamples.find(e => e.id === i)
|
|
this.loadedSamples.push(load)
|
|
})
|
|
|
|
this.addSampleDialog = false
|
|
},
|
|
updateSampleVolume (id, index) {
|
|
this.players.player(id).volume.value = this.loadedSamples[index].volume
|
|
}
|
|
}
|
|
}
|