Skip to content

Commit

Permalink
Merge pull request #20 from stagas/dsp
Browse files Browse the repository at this point in the history
feat: dsp
  • Loading branch information
stagas authored Oct 23, 2024
2 parents c17bfa0 + 58a7cd2 commit fcb93c0
Show file tree
Hide file tree
Showing 181 changed files with 10,128 additions and 193 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ jobs:
with:
node-version: 22.x

- name: Uninstall dev deps with scripts
run: npm remove @vite-pwa/assets-generator --force --ignore-scripts=true

- name: Install dependencies
run: npm install --ignore-scripts --force
run: npm i --force --ignore-scripts=true

- name: Install dev deps with scripts
run: npm i @vite-pwa/assets-generator -D --force

- name: Build
run: bun run build
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ jobs:
with:
node-version: 22.x

- name: Uninstall dev deps with scripts
run: npm remove @vite-pwa/assets-generator --force --ignore-scripts=true

- name: Install dependencies
run: npm install --ignore-scripts --force
run: npm i --force --ignore-scripts=true

- name: Install dev deps with scripts
run: npm i @vite-pwa/assets-generator -D --force

- name: Build
run: bun run build
Expand Down
4 changes: 3 additions & 1 deletion admin/client.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import '~/lib/watcher.ts'

import { cleanup, hmr, mount } from 'sigui'
import { Admin } from '~/admin/Admin.tsx'
import { setState, state } from '~/src/state.ts'

export const start = mount('#container', target => {
target.replaceChildren(<Admin />)
target.replaceChildren(<Admin /> as HTMLElement)
return cleanup
})

Expand Down
6 changes: 1 addition & 5 deletions admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@
<title>Vasi - Admin</title>
</head>
<body>
<script type="module">
// KEEP: required for AssemblyScript interop.
globalThis.unmanaged = () => {};
</script>
<div id="container"></div>
<script src="/as-interop.js"></script>
<script src="./client.tsx" type="module"></script>
<script src="../lib/watcher.ts" type="module"></script>
</body>
</html>
8 changes: 4 additions & 4 deletions api/auth/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// deno-lint-ignore-file require-await
import { hash } from 'jsr:@denorg/[email protected]'
import { createCookie, randomHash, timeout } from 'utils'
import { createCookie, timeout } from 'utils'
import { ADMINS } from '~/api/admin/actions.ts'
import { UserLogin, UserRegister, UserSession } from "~/api/auth/types.ts"
import { kv } from '~/api/core/app.ts'
Expand Down Expand Up @@ -60,7 +60,7 @@ export async function getUser(nickOrEmail: string) {
export async function loginUser(ctx: Context, nick: string) {
ctx.log('Login:', nick)

const sessionId = randomHash()
const sessionId = crypto.randomUUID()
const sessionKey = ['session', sessionId]

const now = new Date()
Expand Down Expand Up @@ -90,7 +90,7 @@ export async function loginUser(ctx: Context, nick: string) {
}

async function generateEmailVerificationToken(email: string) {
const token = randomHash()
const token = crypto.randomUUID()
const now = new Date()
const expires = new Date(now)
const expireAfterHours = 3 * 24 // 3 days
Expand Down Expand Up @@ -264,7 +264,7 @@ export async function forgotPassword(ctx: Context, email: string) {
return
}

const token = randomHash()
const token = crypto.randomUUID()
const now = new Date()
const expires = new Date(now)
const expireAfterMinutes = 15
Expand Down
3 changes: 1 addition & 2 deletions api/oauth/routes/common.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { randomHash } from 'utils'
import { z } from 'zod'
import { kv } from '~/api/core/app.ts'
import { Router } from '~/api/core/router.ts'
Expand Down Expand Up @@ -30,7 +29,7 @@ export function mount(app: Router) {
provider,
})

const oauthStateId = randomHash()
const oauthStateId = crypto.randomUUID()
await kv.set(['oauthState', oauthStateId], state, {
expireIn: 30 * 60 * 1000
})
Expand Down
14 changes: 2 additions & 12 deletions api/oauth/routes/github.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { randomHash } from 'utils'
import { z } from 'zod'
import { getUserByEmail, loginUser } from '~/api/auth/actions.ts'
import { kv } from '~/api/core/app.ts'
Expand Down Expand Up @@ -49,7 +48,7 @@ const OAuthUser = z.union([

const headers = {
'content-type': 'application/json',
'user-agent': 'cfw-oauth-login',
'user-agent': 'oauth-login',
accept: 'application/json',
}

Expand Down Expand Up @@ -104,7 +103,7 @@ export function mount(app: Router) {
}

// create oauth session
const id = randomHash()
const id = crypto.randomUUID()
const now = new Date()
const expires = new Date(now)
expires.setMinutes(expires.getMinutes() + 30)
Expand All @@ -122,15 +121,6 @@ export function mount(app: Router) {
url.searchParams.set('id', id)
const res = ctx.redirect(302, url.href)

// res.headers.set('set-cookie', createCookie(
// 'oauth',
// id,
// expires,
// 'HttpOnly',
// 'Secure',
// 'SameSite=Strict'
// ))

return res
}])
}
3 changes: 3 additions & 0 deletions as/assembly/common/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @ts-ignore
@external('env', 'log')
export declare function log(x: i32): void
11 changes: 11 additions & 0 deletions as/assembly/dsp/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const BUFFER_SIZE = 2048
export const MAX_AUDIOS = 1024
export const MAX_FLOATS = 4096
export const MAX_LISTS = 4096
export const MAX_LITERALS = 4096
export const MAX_OPS = 4096
export const MAX_RMSS = 1024
export const MAX_SCALARS = 4096
export const MAX_SOUNDS = 16
export const MAX_TRACKS = 16
export const MAX_VALUES = 1024
155 changes: 155 additions & 0 deletions as/assembly/dsp/core/antialias-wavetable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { nextPowerOfTwo } from '../../util'
import { ANTIALIAS_WAVETABLE_OVERSAMPLING, WAVETABLE_SIZE } from './constants'
import { fft } from './fft'

class Real {
@inline static saw(real: StaticArray<f32>, i: u32, j: u32): void {
const temp: f32 = -1.0 / f32(i)
real[i] = temp
real[j] = -temp
}

@inline static ramp(real: StaticArray<f32>, i: u32, j: u32): void {
const temp: f32 = -1.0 / f32(i)
real[i] = -temp
real[j] = temp
}

@inline static sqr(real: StaticArray<f32>, i: u32, j: u32): void {
const temp: f32 = i & 0x01 ? 1.0 / f32(i) : 0.0
real[i] = -temp
real[j] = temp
}

static sign: f32 = 1.0
@inline static tri(real: StaticArray<f32>, i: u32, j: u32): void {
const temp: f32 = i & 0x01 ? 1.0 / f32(i * i) * (this.sign = -this.sign) : 0.0
real[i] = temp
real[j] = -temp
}
}

export class AntialiasWavetable {
real: StaticArray<f32>
imag: StaticArray<f32>
freqs: StaticArray<f32>
topFreq: f64
maxHarms: u32
numOfTables: u32
tableLength: u32
tableMask: u32
tableIndex: u32 = 0
stepShift: i32 = 0
sampleRate: u32

saw: StaticArray<StaticArray<f32>>
ramp: StaticArray<StaticArray<f32>>
sqr: StaticArray<StaticArray<f32>>
tri: StaticArray<StaticArray<f32>>

constructor(sampleRate: u32) {
let topFreq: f64 = 10
let maxHarms: u32 = u32(f64(sampleRate) / (3.0 * topFreq) + 0.5)
const tableLength: u32 = nextPowerOfTwo(maxHarms) * 2 * ANTIALIAS_WAVETABLE_OVERSAMPLING
const tableMask: u32 = (tableLength - 1) << 2
const numOfTables: u32 = u32(Math.log2(f64(maxHarms)) + 1)

// logi(tableLength)
const saw = new StaticArray<StaticArray<f32>>(numOfTables)
const ramp = new StaticArray<StaticArray<f32>>(numOfTables)
const sqr = new StaticArray<StaticArray<f32>>(numOfTables)
const tri = new StaticArray<StaticArray<f32>>(numOfTables)
for (let i: u32 = 0; i < numOfTables; i++) {
saw[i] = new StaticArray<f32>(tableLength)
ramp[i] = new StaticArray<f32>(tableLength)
sqr[i] = new StaticArray<f32>(tableLength)
tri[i] = new StaticArray<f32>(tableLength)
}

const freqs = new StaticArray<f32>(numOfTables)
const real = new StaticArray<f32>(tableLength)
const imag = new StaticArray<f32>(tableLength)

this.real = real
this.imag = imag
this.freqs = freqs

this.saw = saw
this.ramp = ramp
this.sqr = sqr
this.tri = tri

this.sampleRate = sampleRate
this.topFreq = topFreq
this.maxHarms = maxHarms
this.numOfTables = numOfTables
this.tableLength = tableLength
this.tableMask = tableMask
this.stepShift = i32(Math.log2(f64(WAVETABLE_SIZE))) - i32(Math.log2(f64(this.tableLength)))

this.makeTables(this.saw, Real.saw)
this.makeTables(this.ramp, Real.ramp)
this.makeTables(this.sqr, Real.sqr)
this.makeTables(this.tri, Real.tri)
}

getTableIndex(hz: f32): u32 {
let tableIndex: u32 = 0
while (
hz >= this.freqs[tableIndex]
&& tableIndex < this.numOfTables - 1
) {
tableIndex = tableIndex + 1
}
return tableIndex
}

makeTables(target: StaticArray<StaticArray<f32>>, fn: (real: StaticArray<f32>, i: u32, j: u32) => void): void {
let topFreq: f64 = this.topFreq
let i: u32 = 0
for (let harms: u32 = this.maxHarms; harms >= 1; harms >>= 1) {
this.defineWaveform(harms, fn)
this.makeWavetable(target[i])
this.freqs[i] = f32(topFreq)
topFreq = topFreq * 2
i = i + 1
}
}

defineWaveform(harms: u32, fn: (real: StaticArray<f32>, i: u32, j: u32) => void): void {
if (harms > (this.tableLength >> 1)) {
harms = (this.tableLength >> 1)
}

this.imag.fill(0)
this.real.fill(0)

Real.sign = 1.0
for (let i: u32 = 1, j: u32 = this.tableLength - 1; i <= harms; i++, j--) {
fn(this.real, i, j)
}
}

writeSaw(i: u32, j: u32): void {
const temp: f32 = -1.0 / f32(i)
this.real[i] = temp
this.real[j] = -temp
}

makeWavetable(wave: StaticArray<f32>): void {
fft(this.tableLength, this.real, this.imag)

// calc normal
let scale: f32
let max: f32 = 0.0
for (let i: u32 = 0; i < this.tableLength; i++) {
let temp: f32 = Mathf.abs(this.imag[i])
if (max < temp) max = temp
}
scale = 1.0 / max * 0.999

for (let idx: u32 = 0; idx < this.tableLength; idx++) {
wave[idx] = this.imag[idx] * scale
}
}
}
54 changes: 54 additions & 0 deletions as/assembly/dsp/core/clock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
@unmanaged
export class Clock {
time: f64 = 0
timeStep: f64 = 0
prevTime: f64 = -1
startTime: f64 = 0
endTime: f64 = Infinity
bpm: f64 = 60
coeff: f64 = 0
barTime: f64 = 0
barTimeStep: f64 = 0
loopStart: f64 = -Infinity
loopEnd: f64 = +Infinity
sampleRate: u32 = 44100
jumpBar: i32 = -1
ringPos: u32 = 0
nextRingPos: u32 = 0

reset(): void {
const c: Clock = this
c.ringPos = 0
c.nextRingPos = 0
c.prevTime = -1
c.time = 0
c.barTime = c.startTime
}
update(): void {
const c: Clock = this

c.coeff = c.bpm / 60 / 4
c.timeStep = 1.0 / c.sampleRate
c.barTimeStep = c.timeStep * c.coeff

let bt: f64

// advance barTime
bt = c.barTime + (
c.prevTime >= 0
? (c.time - c.prevTime) * c.coeff
: 0
)
c.prevTime = c.time

// wrap barTime on clock.endTime
const startTime = Math.max(c.loopStart, c.startTime)
const endTime = Math.min(c.loopEnd, c.endTime)

if (bt >= endTime) {
bt = startTime + (bt % 1.0)
}

c.barTime = bt
}
}
3 changes: 3 additions & 0 deletions as/assembly/dsp/core/constants-internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @ts-ignore
@inline
export const k2PI: f32 = 6.28318530718
4 changes: 4 additions & 0 deletions as/assembly/dsp/core/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const WAVETABLE_SIZE: u32 = 1 << 13
export const DELAY_MAX_SIZE: u32 = 1 << 16
export const SAMPLE_MAX_SIZE: u32 = 1 << 16
export const ANTIALIAS_WAVETABLE_OVERSAMPLING: u32 = 1
Loading

0 comments on commit fcb93c0

Please sign in to comment.