Skip to content

Commit

Permalink
Add better oscillator
Browse files Browse the repository at this point in the history
  • Loading branch information
oamaok committed Oct 20, 2021
1 parent a4567b2 commit 6a0b836
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 31 deletions.
113 changes: 106 additions & 7 deletions build/css-modules-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,112 @@ const cssnano = require('cssnano')
const classNames = {}

let currentId = 0

const emoji = [
'😀',
'😃',
'😄',
'😁',
'😆',
'😅',
'🤣',
'😂',
'🙂',
'🙃',
'😉',
'😊',
'😇',
'🥰',
'😍',
'🤩',
'😘',
'😗',
'😚',
'😙',
'🥲',
'😋',
'😛',
'😜',
'🤪',
'😝',
'🤑',
'🤗',
'🤭',
'🤫',
'🤔',
'🤐',
'🤨',
'😐',
'😑',
'😶',
'😏',
'😒',
'🙄',
'😬',
'😮‍💨',
'🤥',
'😌',
'😔',
'😪',
'🤤',
'😴',
'😷',
'🤒',
'🤕',
'🤢',
'🤮',
'🤧',
'🥵',
'🥶',
'🥴',
'😵',
'😵‍💫',
'🤯',
'🤠',
'🥳',
'🥸',
'😎',
'🤓',
'🧐',
'😕',
'😟',
'🙁',
'☹️',
'😮',
'😯',
'😲',
'😳',
'🥺',
'😦',
'😧',
'😨',
'😰',
'😥',
'😢',
'😭',
'😱',
'😖',
'😣',
'😞',
'😓',
'😩',
'😫',
'🥱',
'😤',
'😡',
'😠',
'🤬',
]

const nextName = () => {
let i = ++currentId
let a = ''
while (i > 0) {
const mod = i % 26
a += String.fromCharCode(mod + 65)
i = Math.floor((i - mod) / 26)
let id = currentId++
let name = ''
for (;;) {
const mod = id % emoji.length
name += emoji[mod]
if (id < emoji.length) return name
id = (id - mod) / emoji.length - 1
}
return a
}

const CssModulesPlugin = () => ({
Expand Down Expand Up @@ -55,6 +152,8 @@ const CssModulesPlugin = () => ({

const { css } = await postcss([cssnano({ preset: 'default' })]).process(
Object.keys(cssContent)
.sort()
.reverse()
.map((key) => cssContent[key])
.join('\n')
)
Expand Down
1 change: 1 addition & 0 deletions client/src/components/modules/LFO.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LFO extends Component<Props> implements IModule {
super(props)
const audioContext = getAudioContext()
this.node = audioContext.createOscillator()
this.node.type = 'sine'
this.node.start()

connectKnobToParam(props.id, 'frequency', this.node.frequency)
Expand Down
77 changes: 60 additions & 17 deletions client/src/components/modules/Oscillator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { h, Component } from 'kaiku'
import { IModule, Id } from '../../types'
import { IModule } from '../../types'
import { getAudioContext } from '../../audio'
import { WorkletNode } from '../../worklets'
import Socket from '../module-parts/Socket'
Expand All @@ -9,45 +9,88 @@ import { connectKnobToParam } from '../../modules'

import { ModuleInputs, ModuleOutputs } from '../module-parts/ModuleSockets'
type Props = {
id: Id
id: string
}

class Oscillator extends Component<Props> implements IModule {
node: OscillatorNode
frequencyNode: WorkletNode<'ModulationHelper'>
node: WorkletNode<'Oscillator'>

constructor(props: Props) {
super(props)
const audioContext = getAudioContext()
this.node = audioContext.createOscillator()
this.node.frequency.value = 0
this.node.start()
this.node.type = 'sawtooth'

this.frequencyNode = new WorkletNode(audioContext, 'ModulationHelper')
this.frequencyNode.connect(this.node.frequency)
this.node = new WorkletNode(audioContext, 'Oscillator', {
numberOfInputs: 3,
numberOfOutputs: 4,
})

const freq = this.frequencyNode.parameters.get('level')

connectKnobToParam(props.id, 'frequency', freq)
connectKnobToParam(props.id, 'CV', this.node.parameters.get('cv'))
connectKnobToParam(props.id, 'FM', this.node.parameters.get('fm'))
connectKnobToParam(props.id, 'Fine', this.node.parameters.get('fine'))
connectKnobToParam(props.id, 'PW', this.node.parameters.get('pw'))
}

render({ id }: Props) {
return (
<Module id={id} name="Oscillator">
<Knob moduleId={id} name="frequency" min={-1} max={10} initial={5} />
<Knob moduleId={id} name="CV" min={-5} max={5} initial={0} />
<Knob moduleId={id} name="FM" min={-1} max={1} initial={0} />
<Knob moduleId={id} name="Fine" min={-1} max={1} initial={0} />
<Knob moduleId={id} name="PW" min={0} max={1} initial={0.5} />

<ModuleInputs>
<Socket
moduleId={id}
type="input"
name="freq"
node={this.frequencyNode}
name="CV"
input={0}
node={this.node}
/>
<Socket
moduleId={id}
type="input"
name="FM"
input={1}
node={this.node}
/>
<Socket
moduleId={id}
type="input"
name="PW"
input={2}
node={this.node}
/>
</ModuleInputs>

<ModuleOutputs>
<Socket moduleId={id} type="output" name="out" node={this.node} />
<Socket
moduleId={id}
type="output"
name="SIN"
output={0}
node={this.node}
/>
<Socket
moduleId={id}
type="output"
name="TRI"
output={1}
node={this.node}
/>
<Socket
moduleId={id}
type="output"
name="SAW"
output={2}
node={this.node}
/>
<Socket
moduleId={id}
type="output"
name="SQR"
output={3}
node={this.node}
/>
</ModuleOutputs>
</Module>
)
Expand Down
11 changes: 6 additions & 5 deletions client/src/components/modules/Sequencer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ type Props = {
}

const NOTE_NAMES = [
'A',
'A#',
'B',
'C',
'C#',
'D',
Expand All @@ -31,6 +28,9 @@ const NOTE_NAMES = [
'F#',
'G',
'G#',
'A',
'A#',
'B',
] as const
type NoteName = typeof NOTE_NAMES[number]

Expand Down Expand Up @@ -64,7 +64,7 @@ class Sequencer extends Component<Props> implements IModule {
notes: Array(16)
.fill(null)
.map(() => ({
name: 'A',
name: 'C',
octave: 4,
gate: true,
})),
Expand All @@ -75,7 +75,8 @@ class Sequencer extends Component<Props> implements IModule {
const { notes } = getModuleState<SequencerState>(props.id)
this.node.port.postMessage(
notes.map((note) => ({
voltage: note.octave + (NOTE_NAMES.indexOf(note.name) * 1) / 12,
voltage:
note.octave - 4 + (NOTE_NAMES.indexOf(note.name) * 1 - 9) / 12,
gate: note.gate,
}))
)
Expand Down
4 changes: 3 additions & 1 deletion client/src/generated/worklets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import Delay from '../../worklets/Delay'
import Gain from '../../worklets/Gain'
import Mixer from '../../worklets/Mixer'
import ModulationHelper from '../../worklets/ModulationHelper'
import Oscillator from '../../worklets/Oscillator'
import Sequencer from '../../worklets/Sequencer'
export const workletNames = ["ADSR","Clock","Delay","Gain","Mixer","ModulationHelper","Sequencer"] as const
export const workletNames = ["ADSR","Clock","Delay","Gain","Mixer","ModulationHelper","Oscillator","Sequencer"] as const
export type Worklets = {
ADSR: typeof ADSR
Clock: typeof Clock
Delay: typeof Delay
Gain: typeof Gain
Mixer: typeof Mixer
ModulationHelper: typeof ModulationHelper
Oscillator: typeof Oscillator
Sequencer: typeof Sequencer
}
2 changes: 1 addition & 1 deletion client/src/reset.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ h1,
h2 {
color: var(--primary);
}
b ody,
body,
html {
overflow: hidden;
width: 100vw;
Expand Down
Loading

0 comments on commit 6a0b836

Please sign in to comment.