Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
yishengjiang99 committed Mar 21, 2023
1 parent 0558a47 commit 0195404
Show file tree
Hide file tree
Showing 15 changed files with 139 additions and 1,887 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"files.associations": {
"*.js": "javascriptreact",
"p1200.h": "c",
"spin.h": "c"
"spin.h": "c",
"sf2.h": "c",
"eg.h": "c",
"calc.h": "c"
}
}
2 changes: 1 addition & 1 deletion sf2-service
Submodule sf2-service updated from 261dcd to 1c8457
4 changes: 2 additions & 2 deletions spin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ clean: src/spin.c
rm -f build/*

build/spin.ll: clean
clang -O3 src/spin.c -o build/spin.ll --target=wasm32 -emit-llvm -c -S
clang -O1 src/spin.c -o build/spin.ll --target=wasm32 -emit-llvm -c -S

build/spin.o: build/spin.ll
llc -march=wasm32 -filetype=obj build/spin.ll -o build/spin.o

spin.wasm: build/spin.o
wasm-ld -O 4 --features=atomics,mutable-global,bulk-memory --no-check-features --allow-undefined --shared-memory --import-memory --no-entry --export-all -o spin.wasm build/spin.o
wasm-ld --features=atomics,mutable-global,bulk-memory --no-check-features --allow-undefined --shared-memory --import-memory --no-entry --export-all -o spin.wasm build/spin.o
1,814 changes: 0 additions & 1,814 deletions spin/build/spin.ll

This file was deleted.

Binary file removed spin/build/spin.o
Binary file not shown.
89 changes: 35 additions & 54 deletions spin/spin-proc.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import { downloadData } from "../fetch-drop-ship/download.js";
import saturate from "../saturation/index.js";
import { wasmbin } from "./spin.wasm.js";
const n_midi_channels = 16;
const n_voices = 16 * 4;
const EG_STAGES = {
INIT: 0,
DELAY: 1,
ATTACK: 2,
HOLD: 3,
DECAY: 4,
RELEASE: 5,
DONE: 99,
};

class SpinProcessor extends AudioWorkletProcessor {
constructor(options) {
super(options);
this.setup_wasm();

this.active_voices = [];
this.inst.exports.gm_reset();
this.sampleIdRefs = [];
this.presetRefs = [];
Expand All @@ -14,15 +28,14 @@ class SpinProcessor extends AudioWorkletProcessor {
this.midiccRef = new Uint8Array(
this.memory.buffer,
this.inst.exports.midi_cc_vals,
128 * 16
128 * n_midi_channels
);
this.outputfff = new Float32Array(
this.memory.buffer,
this.inst.exports.outputs.value,
128 * 32
128 * n_voices
);
this.port.postMessage({ init: 1 });
this.eg_vol_stag = new Array(16).fill(0);
}
sdtaRef(sampleId) {
return new Uint32Array(
Expand All @@ -37,18 +50,11 @@ class SpinProcessor extends AudioWorkletProcessor {
maximum: 1024 * 4,
initial: 1024 * 4,
});
let lastfl;
const imports = {
memory: this.memory,
debugFL: (fl) => {
if (!lastfl || fl != lastfl) {
lastfl = fl;
}
},
};
this.inst = new WebAssembly.Instance(new WebAssembly.Module(wasmbin), {
env: imports,
});
const mdoule = new WebAssembly.Module(wasmbin)
this.inst = new WebAssembly.Instance(mdoule,{env:imports});
this.brk = 0x30000;
this.malololc = (len) => {
const ret = this.brk;
Expand All @@ -59,7 +65,7 @@ class SpinProcessor extends AudioWorkletProcessor {
}

ch_occupied(ch) {
return this.eg_vol_stag[ch] && this.eg_vol_stag[ch] < 99;
return this.eg_vol_stag[ch] && this.eg_vol_stag[ch] < 6;
}
async handleMsg(e) {
const { data } = e;
Expand All @@ -72,7 +78,7 @@ class SpinProcessor extends AudioWorkletProcessor {
this.presetRefs[ref] = ptr;
new Int16Array(this.memory.buffer, ptr, 60).set(
new Int16Array(arr, 0, 60)
); //.set
);
}
this.port.postMessage({ zack: 1 });
} else {
Expand All @@ -94,18 +100,10 @@ class SpinProcessor extends AudioWorkletProcessor {
if (!this.presetRefs[zoneRef]) {
return;
}
if (!this.spinners[channel]) {
this.instantiate(this.presetRefs[channel], channel);
}
let ch = channel;
for (
let ch = channel;
ch < 64 && this.ch_occupied(ch); // channel occuppied
ch++ // find next one.
);
this.inst.exports.reset(this.spinners[ch]);
const spinner = this.inst.exports.get_available_spinner(channel);
this.active_voices.push([spinner, channel]);
this.inst.exports.trigger_attack(
this.spinners[ch],
spinner,
this.presetRefs[zoneRef],
ratio,
velocity
Expand All @@ -130,39 +128,22 @@ class SpinProcessor extends AudioWorkletProcessor {
);
}

instantiate(zone, i) {
this.spinners[i] = this.inst.exports.newSpinner(i);
const spIO = new Uint32Array(this.memory.buffer, this.spinners[i], 2);
this.outputs[i] = new Float32Array(this.memory.buffer, spIO[1], 128 * 2);
return this.spinners[i];
}

process(inputs, outputs, parameters) {
for (let i = 0; i < outputs.length; i++) {
if (!this.spinners[i]) continue;
if (!this.outputs[i]) continue;
for (let j = 0; j < 128 * 2; j++) {
this.outputs[i][j] = 0;
let sp_to_run=[];
for(let i=0; i<this.active_voices.length; i++){
const [spinner,channel]=this.active_voices[i];
const eg_stage = this.inst.exports.spin(spinner, 128);
var rendered = new Float32Array(this.memory.buffer, (spinner+32), 128*2);
if(eg_stage>=EG_STAGES.DONE){
this.active_voices.splice(i,1);
this.inst.exports.set_available(spinner);
}
this.eg_vol_stag[i] = this.inst.exports.spin(this.spinners[i], 128);
for (let j = 0; j < 128; j++) {
outputs[i][0][j] = saturate(this.outputs[i][2 * j] * 0.5);
outputs[i][1][j] = saturate(this.outputs[i][2 * j + 1] * 0.5);
outputs[channel][0][j] += rendered[2 * j];
outputs[channel][1][j] += rendered[2 * j + 1];
}
}

// if (
// outputs[0][15] > 0.00000001 ||
// outputs[0][44] > 0.00000001 ||
// outputs[0][66] > 0.00000001 ||
// outputs[0][22] > 0.00000001
// ) {
// const pcmplayback = new Float32Array(128 * 32);
// pcmplayback.set(this.outputfff);
// new Promise((r) => r()).then(() =>
// this.port.postMessage({ pcmplayback: pcmplayback })
// );
// }
}9
this.active_voices.push(sp_to_run)
return true;
}
}
Expand Down
Binary file modified spin/spin.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion spin/spin.wasm.js

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions spin/spin.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
(module
(type (;0;) (func (result i32)))
(type (;1;) (func))
(type (;2;) (func (param i32)))
(type (;3;) (func (param i32) (result i32)))
(func (;0;) (type 1)
call 2)
(func (;1;) (type 1)
block ;; label = @1
i32.const 1
i32.eqz
br_if 0 (;@1;)
call 0
end)
(func (;2;) (type 1)
i32.const 65536
global.set 2
i32.const 0
i32.const 15
i32.add
i32.const -16
i32.and
global.set 1)
(func (;3;) (type 0) (result i32)
global.get 0
global.get 1
i32.sub)
(func (;4;) (type 0) (result i32)
global.get 2)
(func (;5;) (type 0) (result i32)
global.get 1)
(func (;6;) (type 0) (result i32)
i32.const 65536)
(func (;7;) (type 0) (result i32)
global.get 0)
(func (;8;) (type 2) (param i32)
local.get 0
global.set 0)
(func (;9;) (type 3) (param i32) (result i32)
(local i32 i32)
global.get 0
local.get 0
i32.sub
i32.const -16
i32.and
local.tee 1
global.set 0
local.get 1)
(func (;10;) (type 0) (result i32)
global.get 0)
(table (;0;) 2 2 funcref)
(memory (;0;) 256 256)
(global (;0;) (mut i32) (i32.const 65536))
(global (;1;) (mut i32) (i32.const 0))
(global (;2;) (mut i32) (i32.const 0))
(export "memory" (memory 0))
(export "_initialize" (func 1))
(export "__indirect_function_table" (table 0))
(export "__errno_location" (func 6))
(export "emscripten_stack_init" (func 2))
(export "emscripten_stack_get_free" (func 3))
(export "emscripten_stack_get_base" (func 4))
(export "emscripten_stack_get_end" (func 5))
(export "stackSave" (func 7))
(export "stackRestore" (func 8))
(export "stackAlloc" (func 9))
(export "emscripten_stack_get_current" (func 10))
(elem (;0;) (i32.const 1) func 0))
16 changes: 10 additions & 6 deletions spin/src/calc.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
#include "p1200.h"
#ifndef CALC_H
#define CALC_H

#include "p1200.h"
#define log_2_10 3.321928094f
#define bit23_normalize 1.000f / 0x7fffff
#ifndef SAMPLE_RATE
#define SAMPLE_RATE 44100.0f
#endif
#define SAMPLE_BLOCK 128
#define BLOCKS_PER_SECOND SAMPLE_RATE / SAMPLE_BLOCK

#ifndef
#define clamp(val, min, max) val > max ? max : val < min ? min : val
#endif


double midi_volume_log10(int val) {
if (val < 0) return 1440;
if (val > 128) return 0;
return midi_log_10[val];
}

double timecent2second(short tc) {
if (tc < 0) return 1.0f / timecent2second(-1 * tc);
Expand Down Expand Up @@ -51,4 +50,9 @@ static inline short sf2midiPan(short sf2pan) {
if (sf2pan < -500) return 1;
return (short)64 + sf2pan / 500 * 64;
}
double midi_volume_log10(int val) {
if (val < 0) return 1440;
if (val > 128) return 0;
return midi_log_10[val];
}
#endif
1 change: 0 additions & 1 deletion spin/src/sf2.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#ifndef SF2_H
#define SF2_H
#include <stdint.h>
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
Expand Down
13 changes: 10 additions & 3 deletions spin/src/spin.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define nchannels 64
#define nmidiChannels 16
extern void debugFL(float fl);
#define export __attribute__((used))

spinner sps[nchannels];
EG eg[nchannels * 2];
Expand All @@ -18,16 +19,21 @@ float silence[40];
char spsIndx = 0;
pcm_t pcms[2222];

spinner* get_available_spinner(int channelId) {
export spinner* get_available_spinner(int channelId) {
spinner* sp;
for (int i = 0; i < nchannels; i++) {
if (sps[i].sp_avail == SP_AVAIL) {
sp = &sps[i];
sp->channelId=channelId;
sp->sp_avail=sp_NOT_AVAIL;
return sp;
}
}
return 0;
}

export void set_available(spinner*x){
x->sp_avail=sp_NOT_AVAIL;
}
spinner* newSpinner(int idx) {
spinner* x = &sps[idx];
x->outputf = &outputs[idx * RENDQ * 2];
Expand All @@ -44,7 +50,7 @@ spinner* newSpinner(int idx) {
return x;
}

void gm_reset() {
export void gm_reset() {
for (int idx = 0; idx < 128; idx++) {
midi_cc_vals[idx * nmidiChannels + TML_VOLUME_MSB] = 100;
midi_cc_vals[idx * nmidiChannels + TML_PAN_MSB] = 64;
Expand Down Expand Up @@ -82,6 +88,7 @@ void set_midi_cc_val(int channel, int metric, int val) {

spinner* spRef(int idx) { return &sps[idx]; }
pcm_t* pcmRef(int idx) { return &pcms[idx]; }
export float* spOutput(spinner* sp) { return sp->outputf; }

LFOEffects lfo_effects(float lfoval, zone_t* z) {
float mod2vol = (1 - lfoval) * z->ModLFO2Vol;
Expand Down
3 changes: 2 additions & 1 deletion spin/src/spin.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ void set_zone(spinner* x, zone_t* z, unsigned int pcm_sampleRate);
spinner* newSpinner(int idx);
void eg_release(spinner* x);
void reset(spinner* x);
int spin(spinner* x, int n);
int spin(spinner* x, int n);
float* spOutput(spinner*x);

// borrowed from tml.h
enum TMLController {
Expand Down
4 changes: 2 additions & 2 deletions src/createChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function createChannel(uiController, channelId, sf2, spinner) {
},
keyOn(key, vel) {
const zones = program.filterKV(key, vel);
zones.slice(2).map((zone, i) => {
zones.slice(3).map((zone, i) => {
key_on_map[key] = channelId * +i;
spinner.keyOn(channelId * 2 + i, zone, key, vel);
});
Expand Down Expand Up @@ -51,7 +51,7 @@ export function createChannel(uiController, channelId, sf2, spinner) {
});
},
keyOff(key, vel) {
while (key_on_map[key].length) {
while ((key_on_map[key] || []).length) {
spinner.keyOff(key_on_map[key].shift(), key, vel);
}
// spinner.keyOff(channelId * 2 + 1, key, vel);
Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,10 @@ async function main(sf2file, midifile) {
mkdiv2({ tag: "option", value: n, children: n }).attachTo(drumList);
}
});
channels.forEach((c) => c.setSF2(sf2));
channels.forEach((c,i) => {
c.setSF2(sf2);
c.setProgram(i,i==9 ? 128 : 0);
});
for (const [section, text] of sf2.meta) {
stderr(section + ": " + text);
}
Expand Down

0 comments on commit 0195404

Please sign in to comment.