custom samples tweaking

This commit is contained in:
Jeremy Penner 2024-11-27 22:36:55 -05:00
parent 56fab04753
commit a36eb82dda
5 changed files with 98 additions and 24 deletions

View file

@ -7,13 +7,13 @@ var Sample = function (audiobuffer, toneHz, gain) {
samples[i] += channel_samples[i] + 1; samples[i] += channel_samples[i] + 1;
} }
} }
gain = (gain ? gain : 1) / (audiobuffer.numberOfChannels * 2);
for (i = 0; i < samples.length; i ++) { for (i = 0; i < samples.length; i ++) {
samples[i] = samples[i] * gain; samples[i] = samples[i] / audiobuffer.numberOfChannels;
} }
this.gain = gain || 1;
this.samples = samples; this.samples = samples;
this.index = 0; this.index = 0;
this.sampleRate = audiobuffer.sampleRate;
this.increment = audiobuffer.sampleRate / toneHz; this.increment = audiobuffer.sampleRate / toneHz;
this.prevMaxTimer = null; this.prevMaxTimer = null;
this.prevTimer = 0; this.prevTimer = 0;
@ -27,6 +27,12 @@ Sample.prototype = {
copy.index = 0; copy.index = 0;
return copy; return copy;
}, },
get frequency() {
return this.sampleRate / this.increment;
},
set frequency(toneHz) {
this.increment = this.sampleRate / toneHz;
},
advance: function(clocksPerPeriod) { advance: function(clocksPerPeriod) {
this.clocksPerPeriod = clocksPerPeriod; this.clocksPerPeriod = clocksPerPeriod;
this.index += this.increment / clocksPerPeriod; this.index += this.increment / clocksPerPeriod;
@ -56,7 +62,7 @@ Sample.prototype = {
var index = (this.index + (((this.increment / this.clocksPerPeriod) * timerIncreasing) / maxTimer)) >> 0; var index = (this.index + (((this.increment / this.clocksPerPeriod) * timerIncreasing) / maxTimer)) >> 0;
if (index < 0) index = 0; if (index < 0) index = 0;
if (index >= this.samples.length) index = this.samples.length - 1; if (index >= this.samples.length) index = this.samples.length - 1;
return (this.samples[index] * volume); return (this.samples[index] * volume * this.gain);
} }
} }

View file

@ -13,8 +13,8 @@
"jsnes": "file:./jsnes" "jsnes": "file:./jsnes"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.2",
"svelte": "^5.1.3", "svelte": "^5.2.10",
"vite": "^5.4.10" "vite": "^5.4.11"
} }
} }

View file

@ -0,0 +1,64 @@
<script>
import { untrack } from 'svelte';
import { loadSample, decodeSample } from './sampload.js'
let { opts = $bindable() } = $props();
let samplefile = $state();
let frequency = $state(880)
let gain = $state(1)
$effect(() => {
if (opts.sampleSquare1) {
opts.sampleSquare1.frequency = frequency;
}
});
$effect(() => {
if (opts.sampleSquare1) {
opts.sampleSquare1.gain = gain;
}
});
$inspect(frequency)
function setSample(sample) {
if (sample) {
frequency = sample.frequency;
gain = sample.gain;
opts = { sampleSquare1: sample, sampleSquare2: sample.clone(), sampleTriangle: sample.clone() };
} else {
opts = {};
}
}
async function meow() {
setSample(await loadSample("samples/meow1.wav", 720, 10));
}
async function yeargh() {
setSample(await loadSample("samples/YEARGH.WAV", 1300, 1));
}
meow();
$effect(() => {
if (samplefile && samplefile.length > 0) {
let reader = new FileReader();
reader.onload = async () => { setSample(await decodeSample(reader.result, 880, 1)); }
reader.readAsArrayBuffer(samplefile[0]);
}
});
</script>
<main>
<div>
<button onclick={() => { opts = {} }}>Normal</button>
<button onclick={meow}>Meow</button>
<button onclick={yeargh}>Yeargh</button>
<input bind:files={samplefile} type="file" />
</div>
<div>
<label>
Frequency:
<input type="range" bind:value={frequency} min="220" max="2200" step="10"/>
{frequency}
</label>
<label>
Gain:
<input type="range" bind:value={gain} min="0.1" max="10" step="0.1" />
{gain}
</label>
</div>
</main>

View file

@ -1,8 +1,12 @@
import { Sample } from 'jsnes'; import { Sample } from 'jsnes';
export async function loadSample(url, toneHz, gain) { export async function loadSample(url, toneHz, gain) {
const audioCtx = new AudioContext();
const response = await fetch(url); const response = await fetch(url);
const buffer = await audioCtx.decodeAudioData(await response.arrayBuffer()); return await decodeSample(await response.arrayBuffer(), toneHz, gain);
}
export async function decodeSample(arraybuffer, toneHz, gain) {
const audioCtx = new AudioContext();
const buffer = await audioCtx.decodeAudioData(arraybuffer);
return new Sample(buffer, toneHz, gain); return new Sample(buffer, toneHz, gain);
} }

View file

@ -254,10 +254,10 @@
dependencies: dependencies:
debug "^4.3.7" debug "^4.3.7"
"@sveltejs/vite-plugin-svelte@^4.0.0": "@sveltejs/vite-plugin-svelte@^4.0.2":
version "4.0.1" version "4.0.2"
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.1.tgz#d6a36caf09eca00249add71fde17b1d01fdd89a2" resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.2.tgz#b2106ce4e77f074f2f4542d33413bdcad3529863"
integrity sha512-prXoAE/GleD2C4pKgHa9vkdjpzdYwCSw/kmjw6adIyu0vk5YKCfqIztkLg10m+kOYnzZu3bb0NaPTxlWre2a9Q== integrity sha512-Y9r/fWy539XlAC7+5wfNJ4zH6TygUYoQ0Eegzp0zDDqhJ54+92gOyOX1l4MO1cJSx0O+Gp13YePT5XEa3+kX0w==
dependencies: dependencies:
"@sveltejs/vite-plugin-svelte-inspector" "^3.0.0-next.0||^3.0.0" "@sveltejs/vite-plugin-svelte-inspector" "^3.0.0-next.0||^3.0.0"
debug "^4.3.7" debug "^4.3.7"
@ -332,10 +332,10 @@ esbuild@^0.21.3:
"@esbuild/win32-ia32" "0.21.5" "@esbuild/win32-ia32" "0.21.5"
"@esbuild/win32-x64" "0.21.5" "@esbuild/win32-x64" "0.21.5"
esm-env@^1.0.0: esm-env@^1.2.0:
version "1.1.4" version "1.2.0"
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.1.4.tgz#340c78b03ee2298d31c5b9fab9793468ede828b0" resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.0.tgz#637c0586244c0eb14bfd7f5e96a6b43b9e8f5c2b"
integrity sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg== integrity sha512-OhSQuHL3mUcaQHjGe8UMG8GsJIJHYYz0flR0h9fiTPNMupLMkb7TvcRD0EeJXW5a8GHBgfz08b6FDLNK7kkPQA==
esrap@^1.2.2: esrap@^1.2.2:
version "1.2.2" version "1.2.2"
@ -433,10 +433,10 @@ source-map-js@^1.2.1:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
svelte@^5.1.3: svelte@^5.2.10:
version "5.2.2" version "5.2.10"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.2.2.tgz#a9d28dd6942e59f303298902c546909161452b45" resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.2.10.tgz#d35399550de09e86f5344fe8e221c667bbbac68e"
integrity sha512-eHIJRcvA6iuXdRGMESTmBtWTQCcCiol4gyH9DA60ybS35W1x27cvtbndNvWDqX72blyf+AYeQ4gzZ0XGg3L8sw== integrity sha512-ON0OyO7vOmSjTc9mLjusu3vf1I7BvjovbiRB7j84F1WZMXV6dR+Tj4btIzxQxMHfzbGskaFmRa7qjgmBSVBnhQ==
dependencies: dependencies:
"@ampproject/remapping" "^2.3.0" "@ampproject/remapping" "^2.3.0"
"@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/sourcemap-codec" "^1.5.0"
@ -445,14 +445,14 @@ svelte@^5.1.3:
acorn-typescript "^1.4.13" acorn-typescript "^1.4.13"
aria-query "^5.3.1" aria-query "^5.3.1"
axobject-query "^4.1.0" axobject-query "^4.1.0"
esm-env "^1.0.0" esm-env "^1.2.0"
esrap "^1.2.2" esrap "^1.2.2"
is-reference "^3.0.3" is-reference "^3.0.3"
locate-character "^3.0.0" locate-character "^3.0.0"
magic-string "^0.30.11" magic-string "^0.30.11"
zimmerframe "^1.1.2" zimmerframe "^1.1.2"
vite@^5.4.10: vite@^5.4.11:
version "5.4.11" version "5.4.11"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q== integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==