Skip to content

Commit

Permalink
fix: remove white fast implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
danigb committed Sep 3, 2024
1 parent 867b53d commit 386c9d4
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 37 deletions.
25 changes: 4 additions & 21 deletions packages/noise/src/dsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ export type NoiseAlgorithm = (output: Float32Array) => void;

export enum NoiseType {
WHITE_RND = 0,
WHITE_FAST = 1,
PINK_COOPER = 10,
PINK_LARRY_TRAMMEL = 11,
PINK_TRAMMEL = 10,
PINK_COOPER = 11,
}

export function getNoiseAlgorithm(
Expand All @@ -14,12 +13,10 @@ export function getNoiseAlgorithm(
switch (type) {
case NoiseType.WHITE_RND:
return whiteRnd;
case NoiseType.WHITE_FAST:
return createWhiteFast();
case NoiseType.PINK_TRAMMEL:
return createPinkLarryTrammel();
case NoiseType.PINK_COOPER:
return createPinkCooper(sampleRate);
case NoiseType.PINK_LARRY_TRAMMEL:
return createPinkLarryTrammel();
default:
console.warn("Unknown noise type: " + type);
return whiteRnd;
Expand All @@ -32,20 +29,6 @@ function whiteRnd(output: Float32Array) {
}
}

// Fast white noise from https://www.musicdsp.org/en/latest/Synthesis/216-fast-whitenoise-generator.html
function createWhiteFast(): NoiseAlgorithm {
const SCALE = 2.0 / 0xffffffff;
let g_x1 = 0x67452301;
let g_x2 = 0xefcdab89;
return (output) => {
for (let i = 0; i < output.length; i++) {
g_x1 ^= g_x2;
output[i] = g_x2 * SCALE;
g_x2 += g_x1;
}
};
}

// Pink noise from http://www.cooperbaker.com/home/code/pink%20noise/
function createPinkCooper(sampleRate: number): NoiseAlgorithm {
// Coefficients
Expand Down
6 changes: 2 additions & 4 deletions packages/noise/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ export type NoiseInputParams = {

export function getNoiseTypes(): { name: string; value: number }[] {
return [
{ name: "White Random", value: NoiseType.WHITE_RND },
{ name: "White Fast", value: NoiseType.WHITE_FAST },
{ name: "Pink Cooper", value: NoiseType.PINK_COOPER },
{ name: "Pink Larry Trammel", value: NoiseType.PINK_LARRY_TRAMMEL },
{ name: "White", value: NoiseType.WHITE_RND },
{ name: "Pink Trammel", value: NoiseType.PINK_TRAMMEL },
];
}

Expand Down
2 changes: 1 addition & 1 deletion packages/noise/src/processor.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const PROCESSOR = `"use strict";(()=>{function A(r,t){switch(t){case 0:return N;case 1:return R();case 10:return M(r);case 11:return P();default:return console.warn("Unknown noise type: "+t),N}}function N(r){for(let t=0;t<r.length;t++)r[t]=Math.random()*2-1}function R(){let r=4656612874161595e-25,t=1732584193,o=4023233417;return e=>{for(let n=0;n<e.length;n++)t^=o,e[n]=o*r,o+=t}}function M(r){let t=[0,0,0,0,0,0,0,0],o=[0,0,0,0,0,0,0,0],e=[0,0,0,0,0,0,0,0],n=0,h=0,a=c=>Math.pow(10,c/20),u=c=>20*Math.log10(c),l=0,i=0,p=0,m=r/(2*Math.PI)-1;for(;m>1;)t[l]=2*Math.PI*m/r,m=m/4,l++;for(h=l;l-- >0;)o[l]=a(i),p+=a(i),i-=6;return n=a(-u(p)),c=>{for(let f=0;f<c.length;f++){let b=Math.random()*2-1,d=0;for(let s=0;s<h;s++)e[s]=t[s]*b+(1-t[s])*e[s],d+=e[s]*o[s];c[f]=d*n}}}function P(){let r=[3.8024,2.9694,2.597,3.087,3.4006],t=[.00198,.01478,.06378,.23378,.91578],o=15.8564,e=[0,0,0,0,0],n=0;return h=>{for(let a=0;a<h.length;a++){let u=Math.random(),l=Math.random();for(let i=0;i<5;i++)if(u<t[i]){n-=e[i],e[i]=2*(l-.5)*r[i],n+=e[i];break}h[a]=n/o}}}var g=class extends AudioWorkletProcessor{r;t;d;constructor(){super(),this.r=!0,this.t=0,this.d=A(sampleRate,0),this.port.onmessage=t=>{switch(t.data.type){case"DISCONNECT":this.r=!1;break}}}process(t,o,e){return this.t!==e.type[0]&&(this.t=e.type[0],this.d=A(sampleRate,e.type[0])),this.d(o[0][0]),this.r}static get parameterDescriptors(){return[["type",0,0,100]].map(([t,o,e,n])=>({name:t,defaultValue:o,minValue:e,maxValue:n,automationRate:"k-rate"}))}};registerProcessor("NoiseWorkletProcessor",g);})();`;
export const PROCESSOR = `"use strict";(()=>{function g(o,t){switch(t){case 0:return N;case 10:return P();case 11:return M(o);default:return console.warn("Unknown noise type: "+t),N}}function N(o){for(let t=0;t<o.length;t++)o[t]=Math.random()*2-1}function M(o){let t=[0,0,0,0,0,0,0,0],n=[0,0,0,0,0,0,0,0],e=[0,0,0,0,0,0,0,0],i=0,c=0,a=h=>Math.pow(10,h/20),u=h=>20*Math.log10(h),l=0,r=0,d=0,m=o/(2*Math.PI)-1;for(;m>1;)t[l]=2*Math.PI*m/o,m=m/4,l++;for(c=l;l-- >0;)n[l]=a(r),d+=a(r),r-=6;return i=a(-u(d)),h=>{for(let p=0;p<h.length;p++){let b=Math.random()*2-1,f=0;for(let s=0;s<c;s++)e[s]=t[s]*b+(1-t[s])*e[s],f+=e[s]*n[s];h[p]=f*i}}}function P(){let o=[3.8024,2.9694,2.597,3.087,3.4006],t=[.00198,.01478,.06378,.23378,.91578],n=15.8564,e=[0,0,0,0,0],i=0;return c=>{for(let a=0;a<c.length;a++){let u=Math.random(),l=Math.random();for(let r=0;r<5;r++)if(u<t[r]){i-=e[r],e[r]=2*(l-.5)*o[r],i+=e[r];break}c[a]=i/n}}}var A=class extends AudioWorkletProcessor{r;t;d;constructor(){super(),this.r=!0,this.t=0,this.d=g(sampleRate,0),this.port.onmessage=t=>{switch(t.data.type){case"DISCONNECT":this.r=!1;break}}}process(t,n,e){return this.t!==e.type[0]&&(this.t=e.type[0],this.d=g(sampleRate,e.type[0])),this.d(n[0][0]),this.r}static get parameterDescriptors(){return[["type",0,0,100]].map(([t,n,e,i])=>({name:t,defaultValue:n,minValue:e,maxValue:i,automationRate:"k-rate"}))}};registerProcessor("NoiseWorkletProcessor",A);})();`;
4 changes: 1 addition & 3 deletions site/content/docs/(sources)/noise.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ noise.type.value = NoiseType.PINK_COOPER;

- `type`: The type of noise to generate. Can be one of:
- 0 `NoiseType.WHITE_RND`: White noise that uses `Math.rand` for random numbers.
- 1 `NoiseType.WHITE_FAST`: White noise that uses this algorithm https://www.musicdsp.org/en/latest/Synthesis/216-fast-whitenoise-generator.html
- 10 `NoiseType.PINK_RND`: Pink noise based on this [Cooper Baker algorithm](http://www.cooperbaker.com/home/code/pink%20noise/)
- 11: `NoiseType.PINK_LARRY_TRAMMEL`: Pink noise based on this [Larry Trammel algorithm](https://www.ridgerat-tech.us/pink/newpink.htm)
- 10: `NoiseType.PINK_TRAMMEL`: Pink noise based on this [Larry Trammel algorithm](https://www.ridgerat-tech.us/pink/newpink.htm)

Since type is an audio param, any arbitrary value can be used, but only the above values are valid. If you suply an invalid value, a warning will be printed and the noise will default to white random.

Expand Down
29 changes: 21 additions & 8 deletions site/examples/NoiseExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,35 @@ import { createNoiseNode, getNoiseTypes, NoiseWorkletNode } from "synthlet";
import { useSynth } from "./useSynth";

export function NoiseExample() {
return (
<ExampleButton label="Start Noise example">
<NoiseSynthUI />
</ExampleButton>
const [open, setOpen] = useState(false);

return open ? (
<NoiseSynthUI onClose={() => setOpen(false)} />
) : (
<button
className="border px-2 py-1 rounded bg-fd-secondary"
onClick={() => setOpen(true)}
>
Start Noise example
</button>
);
}

function NoiseSynthUI() {
function NoiseSynthUI({ onClose }: { onClose: () => void }) {
const [selectedNoiseType, setSelectedNoiseType] = useState(0);
const [volume, setVolume] = useState(-60);
const synth = useSynth((context) => new NoiseSynth(context));
if (!synth) return null;

return (
<div className="bg-slate-800 text-white p-2 border border-slate-600 rounded">
<div className="bg-fd-card text-fd-foreground p-2 border rounded">
<div className="text-xl mb-4">Noise generator example</div>
<div className="flex items-center gap-2">
<div className="w-16 text-right">Type:</div>
<select
className="p-1 rounded bg-slate-700 text-slate-200"
value={selectedNoiseType}
onChange={(e) => {
console.log(e.target.value);
const noiseType = parseInt(e.target.value);
setSelectedNoiseType(noiseType);
synth.noise.type.setValueAtTime(noiseType, 0);
Expand All @@ -40,7 +46,7 @@ function NoiseSynthUI() {
))}
</select>
</div>
<div className="flex items-center gap-2 mt-1">
<div className="flex items-center gap-2 mb-4">
<div className="w-16 text-right">Volume:</div>
<input
type="range"
Expand All @@ -58,6 +64,13 @@ function NoiseSynthUI() {
/>
<div>{volume <= -60 ? "Muted" : volume + "dB"}</div>
</div>

<button
className="border px-2 py-1 rounded bg-fd-secondary"
onClick={onClose}
>
Close
</button>
</div>
);
}
Expand Down

0 comments on commit 386c9d4

Please sign in to comment.