custom samples tweaking
This commit is contained in:
parent
56fab04753
commit
a36eb82dda
|
@ -7,13 +7,13 @@ var Sample = function (audiobuffer, toneHz, gain) {
|
|||
samples[i] += channel_samples[i] + 1;
|
||||
}
|
||||
}
|
||||
gain = (gain ? gain : 1) / (audiobuffer.numberOfChannels * 2);
|
||||
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.index = 0;
|
||||
this.sampleRate = audiobuffer.sampleRate;
|
||||
this.increment = audiobuffer.sampleRate / toneHz;
|
||||
this.prevMaxTimer = null;
|
||||
this.prevTimer = 0;
|
||||
|
@ -27,6 +27,12 @@ Sample.prototype = {
|
|||
copy.index = 0;
|
||||
return copy;
|
||||
},
|
||||
get frequency() {
|
||||
return this.sampleRate / this.increment;
|
||||
},
|
||||
set frequency(toneHz) {
|
||||
this.increment = this.sampleRate / toneHz;
|
||||
},
|
||||
advance: function(clocksPerPeriod) {
|
||||
this.clocksPerPeriod = clocksPerPeriod;
|
||||
this.index += this.increment / clocksPerPeriod;
|
||||
|
@ -56,7 +62,7 @@ Sample.prototype = {
|
|||
var index = (this.index + (((this.increment / this.clocksPerPeriod) * timerIncreasing) / maxTimer)) >> 0;
|
||||
if (index < 0) index = 0;
|
||||
if (index >= this.samples.length) index = this.samples.length - 1;
|
||||
return (this.samples[index] * volume);
|
||||
return (this.samples[index] * volume * this.gain);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
"jsnes": "file:./jsnes"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||
"svelte": "^5.1.3",
|
||||
"vite": "^5.4.10"
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.2",
|
||||
"svelte": "^5.2.10",
|
||||
"vite": "^5.4.11"
|
||||
}
|
||||
}
|
||||
|
|
64
src/lib/SampleTweak.svelte
Normal file
64
src/lib/SampleTweak.svelte
Normal 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>
|
|
@ -1,8 +1,12 @@
|
|||
import { Sample } from 'jsnes';
|
||||
|
||||
export async function loadSample(url, toneHz, gain) {
|
||||
const audioCtx = new AudioContext();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
28
yarn.lock
28
yarn.lock
|
@ -254,10 +254,10 @@
|
|||
dependencies:
|
||||
debug "^4.3.7"
|
||||
|
||||
"@sveltejs/vite-plugin-svelte@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.1.tgz#d6a36caf09eca00249add71fde17b1d01fdd89a2"
|
||||
integrity sha512-prXoAE/GleD2C4pKgHa9vkdjpzdYwCSw/kmjw6adIyu0vk5YKCfqIztkLg10m+kOYnzZu3bb0NaPTxlWre2a9Q==
|
||||
"@sveltejs/vite-plugin-svelte@^4.0.2":
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.2.tgz#b2106ce4e77f074f2f4542d33413bdcad3529863"
|
||||
integrity sha512-Y9r/fWy539XlAC7+5wfNJ4zH6TygUYoQ0Eegzp0zDDqhJ54+92gOyOX1l4MO1cJSx0O+Gp13YePT5XEa3+kX0w==
|
||||
dependencies:
|
||||
"@sveltejs/vite-plugin-svelte-inspector" "^3.0.0-next.0||^3.0.0"
|
||||
debug "^4.3.7"
|
||||
|
@ -332,10 +332,10 @@ esbuild@^0.21.3:
|
|||
"@esbuild/win32-ia32" "0.21.5"
|
||||
"@esbuild/win32-x64" "0.21.5"
|
||||
|
||||
esm-env@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.1.4.tgz#340c78b03ee2298d31c5b9fab9793468ede828b0"
|
||||
integrity sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==
|
||||
esm-env@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.0.tgz#637c0586244c0eb14bfd7f5e96a6b43b9e8f5c2b"
|
||||
integrity sha512-OhSQuHL3mUcaQHjGe8UMG8GsJIJHYYz0flR0h9fiTPNMupLMkb7TvcRD0EeJXW5a8GHBgfz08b6FDLNK7kkPQA==
|
||||
|
||||
esrap@^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"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
svelte@^5.1.3:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.2.2.tgz#a9d28dd6942e59f303298902c546909161452b45"
|
||||
integrity sha512-eHIJRcvA6iuXdRGMESTmBtWTQCcCiol4gyH9DA60ybS35W1x27cvtbndNvWDqX72blyf+AYeQ4gzZ0XGg3L8sw==
|
||||
svelte@^5.2.10:
|
||||
version "5.2.10"
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.2.10.tgz#d35399550de09e86f5344fe8e221c667bbbac68e"
|
||||
integrity sha512-ON0OyO7vOmSjTc9mLjusu3vf1I7BvjovbiRB7j84F1WZMXV6dR+Tj4btIzxQxMHfzbGskaFmRa7qjgmBSVBnhQ==
|
||||
dependencies:
|
||||
"@ampproject/remapping" "^2.3.0"
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
@ -445,14 +445,14 @@ svelte@^5.1.3:
|
|||
acorn-typescript "^1.4.13"
|
||||
aria-query "^5.3.1"
|
||||
axobject-query "^4.1.0"
|
||||
esm-env "^1.0.0"
|
||||
esm-env "^1.2.0"
|
||||
esrap "^1.2.2"
|
||||
is-reference "^3.0.3"
|
||||
locate-character "^3.0.0"
|
||||
magic-string "^0.30.11"
|
||||
zimmerframe "^1.1.2"
|
||||
|
||||
vite@^5.4.10:
|
||||
vite@^5.4.11:
|
||||
version "5.4.11"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5"
|
||||
integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==
|
||||
|
|
Loading…
Reference in a new issue