Skip to content

Commit

Permalink
more params....
Browse files Browse the repository at this point in the history
  • Loading branch information
blechdom committed Dec 1, 2023
1 parent 646aaf2 commit e9bf37d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 22 deletions.
75 changes: 63 additions & 12 deletions src/components/ThreeOhThree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import styled from "styled-components";

const KnobParamLabel = dynamic(() => import("el-vis-audio").then((mod) => mod.KnobParamLabel), {ssr: false});

const chunkDurationSeconds = 0.1;
const chunkDurationSeconds = 0.15;
const numChannels = 2; // currently only two channels allowed (shader uses vec2)
const workgroupSize = 256;
const maxBufferedChunks = 1;
Expand All @@ -16,13 +16,30 @@ const ThreeOhThree = () => {
const [playing, setPlaying] = useState(false);
const [audioParamBuffer, setAudioParamBuffer] = useState<GPUBuffer>();
const [partials, setPartials] = useState(256);
const [frequency, setFrequency] = useState(1);
const [frequency, setFrequency] = useState(38);
const [timeMod, setTimeMod] = useState(16);
const [timeScale, setTimeScale] = useState(9);
const [gain, setGain] = useState(0.7);
const [dist, setDist] = useState(0.5);
const [dur, setDur] = useState(0.26);
const [ratio, setRatio] = useState(2);
const [sampOffset, setSampOffset] = useState(1);
const [fundamental, setFundamental] = useState(440);
const {adapter, device} = useDevice()

function handleReset() {
setPartials(256);
setFrequency(38);
setTimeMod(16);
setTimeScale(9);
setGain(0.7);
setDist(0.5);
setDur(0.26);
setRatio(2);
setSampOffset(1);
setFundamental(440);
}

if (numChannels !== 2) {
throw new Error('Currently the number of channels has to be 2, sorry :/');
}
Expand Down Expand Up @@ -52,7 +69,7 @@ const ThreeOhThree = () => {
});

const audioParamBuffer = device.createBuffer({
size: Float32Array.BYTES_PER_ELEMENT * 6,
size: Float32Array.BYTES_PER_ELEMENT * 10,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
});

Expand Down Expand Up @@ -93,11 +110,9 @@ const ThreeOhThree = () => {
if (numBufferedChunks > maxBufferedChunks) {
const timeout = chunkDurationSeconds * 0.9;
setTimeout(createSongChunk, timeout * 1000.0);
console.log(`buffered chunks ${numBufferedChunks} (${bufferedSeconds} seconds), next chunk creation starts in ${timeout} seconds`);
return;
}

console.log('writing nextChunkOffset', nextChunkOffset);
device.queue.writeBuffer(timeInfoBuffer, 0, new Float32Array([nextChunkOffset]));

const commandEncoder = device.createCommandEncoder();
Expand Down Expand Up @@ -143,8 +158,6 @@ const ThreeOhThree = () => {

audioSource.start(nextChunkOffset);

console.log(`created new chunk, starts at ${startTime + nextChunkOffset}`);

nextChunkOffset += audioSource.buffer.duration;
await createSongChunk();
}
Expand All @@ -163,8 +176,8 @@ const ThreeOhThree = () => {

useEffect(() => {
if (!audioParamBuffer || !device) return;
device.queue.writeBuffer(audioParamBuffer, 0, new Float32Array([partials, frequency, timeMod, timeScale, gain, dist]));
}, [device, audioParamBuffer, partials, frequency, timeScale, timeMod, gain, dist]);
device.queue.writeBuffer(audioParamBuffer, 0, new Float32Array([partials, frequency, timeMod, timeScale, gain, dist, dur, ratio, sampOffset, fundamental]));
}, [device, audioParamBuffer, partials, frequency, timeScale, timeMod, gain, dist, dur, ratio, sampOffset, fundamental]);

return (
<>
Expand All @@ -179,13 +192,22 @@ const ThreeOhThree = () => {
max={1.0}
onKnobInput={setGain}
/>
<KnobParamLabel
id={"fundamental"}
label={"fundamental"}
knobValue={fundamental}
step={0.01}
min={1}
max={1000}
onKnobInput={setFundamental}
/>
<KnobParamLabel
id={"frequencyScale"}
label={"frequencyScale"}
knobValue={frequency}
step={0.01}
min={.2}
max={4}
max={100}
onKnobInput={setFrequency}
/>
<KnobParamLabel
Expand All @@ -197,6 +219,24 @@ const ThreeOhThree = () => {
max={256}
onKnobInput={setPartials}
/>
<KnobParamLabel
id={"ratio"}
label={"ratio"}
knobValue={ratio}
step={0.1}
min={1}
max={32}
onKnobInput={setRatio}
/>
<KnobParamLabel
id={"sampOffset"}
label={"sampOffset"}
knobValue={sampOffset}
step={1}
min={1}
max={32}
onKnobInput={setSampOffset}
/>
<KnobParamLabel
id={"dist"}
label={"dist"}
Expand All @@ -206,12 +246,21 @@ const ThreeOhThree = () => {
max={5}
onKnobInput={setDist}
/>
<KnobParamLabel
id={"dur"}
label={"dur"}
knobValue={dur}
step={0.001}
min={0.001}
max={2}
onKnobInput={setDur}
/>
<KnobParamLabel
id={"timeScale"}
label={"timeScale"}
knobValue={timeScale}
step={1}
min={1}
step={0.01}
min={0.01}
max={24}
onKnobInput={setTimeScale}
/>
Expand All @@ -225,6 +274,8 @@ const ThreeOhThree = () => {
onKnobInput={setTimeMod}
/>
</KnobsFlexBox>
<br/>
<button onClick={handleReset}>RESET PARAMS</button>
</>
)
}
Expand Down
24 changes: 14 additions & 10 deletions src/shaders/threeOhThree/compute.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ struct AudioParam {
timeScale: f32,
gain: f32,
dist: f32,
dur: f32,
ratio: f32,
sampOffset: f32,
fundamental: f32
}

@group(0) @binding(0) var<uniform> time_info: TimeInfo;
Expand Down Expand Up @@ -49,28 +53,28 @@ fn nse(x: f32) -> f32 {
return fract(sin(x * 110.082) * 19871.8972);
}

fn ntof(n: f32) -> f32 {
return 440.0 * pow(2.0, (n - 69.0) / 12.0);
fn ntof(n: f32, fundamental: f32) -> f32 {
return fundamental * pow(2.0, (n - 69.0) / 12.0);
}

fn synth(tseq: f32, t: f32, audio_param: AudioParam) -> vec2<f32> {
var v: vec2<f32> = vec2(0.0);
let tnote: f32 = fract(tseq);
let dr: f32 = 0.26;
let dr: f32 = audio_param.dur;
let amp: f32 = smoothstep(0.05, 0.0, abs(tnote - dr - 0.05) - dr) * exp(tnote * -1.0);
let seqn: f32 = nse(floor(tseq));
let n: f32 = 20.0 + floor(seqn * 38.0);
let f: f32 = ntof(n);
let sqr: f32 = smoothstep(0.0, 0.01, abs((t*9.0)%64.0 - 20.0) - 20.0);
let base: f32 = f * audio_param.frequency;
let n: f32 = 20.0 + floor(seqn * audio_param.frequency);
let f: f32 = ntof(n, audio_param.fundamental);
let sqr: f32 = smoothstep(0.0, 0.01, abs((t*audio_param.timeScale)%(audio_param.timeMod * 4.0) - 20.0) - 20.0);
let base: f32 = f;
let flt: f32 = exp(tnote * -1.5) * 50.0 + pow(cos(t * 1.0) * 0.5 + 0.5, 4.0) * 80.0 - 0.0;

for (var i = 0u; i < u32(audio_param.partials); i += 1) {
var h: f32 = f32(i + 1);
var h: f32 = f32(i + u32(audio_param.sampOffset));
var inten: f32 = 1.0 / h;

inten = mix(inten, inten * (h%2.0), sqr);
inten *= exp(-1.0 * max(2.0 - h, 0.0));
inten = mix(inten, inten * (h%audio_param.ratio), sqr);
inten *= exp(-1.0 * max(audio_param.ratio - h, 0.0));
inten *= _filter(h, flt, 4.0);

var vx = v.x + (inten * sin((PI2 + 0.01) * (t * base * h)));
Expand Down

0 comments on commit e9bf37d

Please sign in to comment.