Skip to content

Commit

Permalink
Initial commit. Previously developed as part of mvls.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholas Schreiber authored and Nicholas Schreiber committed Feb 25, 2024
0 parents commit 4d92387
Show file tree
Hide file tree
Showing 334 changed files with 26,994 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
build
npm-debug.log
.DS_Store
*.code-workspace
674 changes: 674 additions & 0 deletions COPYING

Large diffs are not rendered by default.

58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AWSM
This is the second Version of the *AwesomeWaveSplineMachine*. It is a quite unique modular software synthesizer that utilizes dynamic *WaveSpline* synthesis.

Click the link below to try the AWSM in your browser.

🚀 [AWSM - AwesomeWaveSplineMachine](https://rnd7.github.io/awsm/dist/index.html)

For more information consider one of the following links.

📚 [User Guide](#user-guide)

🏗 [Developer Guide](#developer-guide)

🏛 [License](#license)

# User guide

[Back to top](#awsm)

## Modes
Toggle between Database

## Views


# Developer guide

[Back to top](#awsm)


```bash
npm install
```

```bash
npm run build
```

```bash
npm run serve
```


# License

[Back to top](#awsm)

Feel free to use this tool to make music or to test the limits of your speakers. I encourage this. When redistributing the software, be sure to understand the underlying license. Since I'm donating a considerable amount of my time to the opensource community, it's important to me that everything that builds on this is also available to everyone.

This project is licensed under the GNU General Public License v3.0

Copyright (C) 2024 C. Nicholas Schreiber

See [COPYING](https://rnd7.github.io/awsm-mkii/COPYING) for the license text or contact me for more information.

The license applies to every file within this repository even if not explicitly stated within the source code of every module.

Official GNU license page: [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html)
45 changes: 45 additions & 0 deletions dist/audio/audio-metrics-analyzer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

export default class AudioMetricsAnalyzer {

#audioContext
#analyserNode
#audioMetrics
#source
#lastFrame = 0
constructor(audioContext) {
this.#audioContext = audioContext
this.#analyserNode = this.#audioContext.createAnalyser()
this.#analyserNode.fftSize = 2048
this.#analyserNode.smoothingTimeConstant = 0.8
}

connect(source) {
if (this.#source) this.#source.disconnect(this.#analyserNode)
this.#source = source
this.#source.connect(this.#analyserNode)
}

update() {
const now = Date.now()
if (!this.#audioMetrics || this.#lastFrame >= now-10) return
this.#lastFrame = now
this.#analyserNode.getByteTimeDomainData(this.#audioMetrics.frame)
}

set audioMetrics(value) {
this.#audioMetrics = value
this.#audioMetrics.frame = new Uint8Array(this.#analyserNode.frequencyBinCount)
this.#audioMetrics.callback = this.update.bind(this)
}

get audioMetrics() {
return this.#audioMetrics
}

destroy() {
this.#source.disconnect(this.#analyserNode)
this.#audioMetrics = null
this.#audioContext = null
this.#analyserNode = null
}
}
141 changes: 141 additions & 0 deletions dist/audio/audio-squeeze-processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import interpolateLinear from "../math/interpolate-linear.js"

class AudioSqueezeProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [{
name: 'threshold', // threshold (0-1 normalized)
defaultValue: 0.5,
minValue: 0.0,
maxValue: 1.0,
automationRate: "a-rate",
}, {
name: 'scale', // scale
defaultValue: 1,
minValue: 0,
maxValue: 10,
automationRate: "a-rate",
}, {
name: 'potential', // loudness factor
defaultValue: 0.0,
minValue: 0,
maxValue: 1,
automationRate: "a-rate",
}, {
name: 'inputs',
defaultValue: 0,
minValue: 0,
maxValue: 128,
automationRate: "k-rate",
}]
}

#bufferIndex = 0

#targetPeak = 0
#peak = 0
#peakIncrement = 0
#peakTime = 0

#buffer = new Float32Array(512)
#output = new Float32Array(128)
#delay = 512

constructor(...args) {
super(...args)
this.port.onmessage = (message) => {
if (message.data.type === "destroy") {
this.onDestroy()
}
}
}

onDestroy() {
this.port.onmessage = null
this.port.close()
}

process(inputs, outputs, parameters) {
for (let outputIndex = 0; outputIndex < outputs.length; outputIndex++) {
const output = outputs[outputIndex]
for (let channelIndex = 0; channelIndex < output.length; channelIndex++) {
const channel = output[channelIndex]
if (outputIndex == 0 && channelIndex == 0) {
if (channel.length != this.#buffer.length) {
this.#output = new Float32Array(channel.length)
}
if (this.#buffer.length != this.#delay) {
this.#buffer = new Float32Array(this.#delay)
}
}
for (let sample = 0; sample < channel.length; sample++) {
if (channelIndex == 0 && outputIndex == 0) {

let amplitude = 0
for (let inputIndex = 0; inputIndex < inputs.length; inputIndex++) {
const input = inputs[inputIndex]
if (input.length) amplitude += input[channelIndex][sample]
}

this.#buffer[this.#bufferIndex] = amplitude

let magnitude = Math.abs(amplitude)

if (magnitude >= this.#targetPeak *.9) {
this.#peakTime = 0
}
if (magnitude >= this.#targetPeak) {
this.#targetPeak = magnitude
}
this.#peakIncrement = (8 * this.#targetPeak) / this.#delay // min value to get from -peak to peak within delay

if (this.#peak - this.#peakIncrement > this.#targetPeak) {
this.#peak -= this.#peakIncrement
} else if (this.#peak + this.#peakIncrement < this.#targetPeak) {
this.#peak += this.#peakIncrement
} else {
this.#peak = this.#targetPeak
}

let liveAmplitude = this.#buffer[(this.#bufferIndex+1)%this.#buffer.length] || 0
let liveMagnitude = Math.abs(liveAmplitude)
let liveSign = Math.sign(liveAmplitude)
const overdrive = parameters.potential.length>1?parameters.potential[sample]:parameters.potential[0]
const threshold = (parameters.threshold.length>1?parameters.threshold[sample]:parameters.threshold[0]) * .99
const scale = parameters.scale.length>1?parameters.scale[sample]:parameters.scale[0]
let out = 0
let scaledMax = Math.max(
threshold + (1-threshold) * scale,
threshold + (1-threshold) * .5
)

if (this.#peak > 0) {
out = liveMagnitude / this.#peak
if (out > threshold) {
let rel = out - threshold
let scaledRel = rel * scale
out = threshold + interpolateLinear(rel, scaledRel, rel/(1-threshold))
}
}
out /= scaledMax
if (this.#peak < 1) out = interpolateLinear(out * this.#peak, out, overdrive)

this.#output[sample] = out * liveSign * .9999

if (this.#peakTime > this.#delay ) {
this.#targetPeak = this.#targetPeak * .99999
}

this.#bufferIndex = (this.#bufferIndex+1)%this.#buffer.length
this.#peakTime++

}
channel[sample] = this.#output[sample]


}
}
}
return true
}
}
registerProcessor("audio-squeeze-processor", AudioSqueezeProcessor);
Loading

0 comments on commit 4d92387

Please sign in to comment.