webaudiofont
Version:
Soundfonts for web. About of 2000 musical instruments. GM MIDI compatible.
278 lines (275 loc) • 9.36 kB
HTML
<html>
<head>
<script src='https://surikov.github.io/webaudiofontdata/sound/0000_SoundBlasterOld_sf2.js'></script>
<script>
/*var afterTime = 0.05;
var nearZero = 0.000001;
function noZeroVolume (n) {
if (n > nearZero) {
return n;
} else {
return nearZero;
}
};
function setupEnvelope (audioContext, envelope, zone, volume, when, sampleDuration, noteDuration) {
envelope.gain.setValueAtTime(noZeroVolume(0), audioContext.currentTime);
var lastTime = 0;
var lastVolume = 0;
var duration = noteDuration;
var ahdsr = zone.ahdsr;
if (sampleDuration < duration + afterTime) {
duration = sampleDuration - afterTime;
}
if (ahdsr) {
if (!(ahdsr.length > 0)) {
ahdsr = [{
duration: 0,
volume: 1
}, {
duration: 0.5,
volume: 1
}, {
duration: 1.5,
volume: 0.5
}, {
duration: 3,
volume: 0
}
];
}
} else {
ahdsr = [{
duration: 0,
volume: 1
}, {
duration: duration,
volume: 1
}
];
}
envelope.gain.cancelScheduledValues(when);
envelope.gain.setValueAtTime(noZeroVolume(ahdsr[0].volume * volume), when);
for (var i = 0; i < ahdsr.length; i++) {
if (ahdsr[i].duration > 0) {
if (ahdsr[i].duration + lastTime > duration) {
var r = 1 - (ahdsr[i].duration + lastTime - duration) / ahdsr[i].duration;
var n = lastVolume - r * (lastVolume - ahdsr[i].volume);
envelope.gain.linearRampToValueAtTime(noZeroVolume(volume * n), when + duration);
break;
}
lastTime = lastTime + ahdsr[i].duration;
lastVolume = ahdsr[i].volume;
envelope.gain.linearRampToValueAtTime(noZeroVolume(volume * lastVolume), when + lastTime);
}
}
envelope.gain.linearRampToValueAtTime(noZeroVolume(0), when + duration + afterTime);
};
function findEnvelope(audioContext, target, when, duration) {
var envelope = null;
if (!(envelope)) {
envelope = audioContext.createGain();
envelope.target = target;
envelope.connect(target);
envelope.cancel = function () {
if (envelope.when + envelope.duration > audioContext.currentTime) {
envelope.gain.cancelScheduledValues(0);
envelope.gain.setTargetAtTime(0.00001, audioContext.currentTime, 0.1);
envelope.when = audioContext.currentTime + 0.00001;
envelope.duration = 0;
}
};
}
return envelope;
};*/
function numValue (aValue, defValue) {
if (typeof aValue === "number") {
return aValue;
} else {
return defValue;
}
};
function adjustZone (audioContext, zone) {
if (zone.buffer) {
//
} else {
zone.delay = 0;
if (zone.sample) {
var decoded = atob(zone.sample);
console.log('decoded',decoded);
zone.buffer = audioContext.createBuffer(1, decoded.length / 2, zone.sampleRate);
var float32Array = zone.buffer.getChannelData(0);
var b1,
b2,
n;
for (var i = 0; i < decoded.length / 2; i++) {
b1 = decoded.charCodeAt(i * 2);
b2 = decoded.charCodeAt(i * 2 + 1);
if (b1 < 0) {
b1 = 256 + b1;
}
if (b2 < 0) {
b2 = 256 + b2;
}
n = b2 * 256 + b1;
if (n >= 65536 / 2) {
n = n - 65536;
}
float32Array[i] = n / 65536.0;
}
console.log('float32Array',float32Array);
} else {
if (zone.file) {
var datalen = zone.file.length;
var arraybuffer = new ArrayBuffer(datalen);
var view = new Uint8Array(arraybuffer);
var decoded = atob(zone.file);
var b;
for (var i = 0; i < decoded.length; i++) {
b = decoded.charCodeAt(i);
view[i] = b;
}
audioContext.decodeAudioData(arraybuffer, function (audioBuffer) {
zone.buffer = audioBuffer;
});
}
}
zone.loopStart = numValue(zone.loopStart, 0);
zone.loopEnd = numValue(zone.loopEnd, 0);
zone.coarseTune = numValue(zone.coarseTune, 0);
zone.fineTune = numValue(zone.fineTune, 0);
zone.originalPitch = numValue(zone.originalPitch, 6000);
zone.sampleRate = numValue(zone.sampleRate, 44100);
zone.sustain = numValue(zone.originalPitch, 0);
}
};/*
function findZone (audioContext, preset, pitch) {
var zone = null;
for (var i = preset.zones.length - 1; i >= 0; i--) {
zone = preset.zones[i];
if (zone.keyRangeLow <= pitch && zone.keyRangeHigh + 1 >= pitch) {
break;
}
}
try {
adjustZone(audioContext, zone);
} catch (ex) {
console.log('adjustZone', ex);
}
return zone;
};
function limitVolume (volume) {
if (volume) {
volume = 1.0 * volume;
} else {
volume = 0.5;
}
return volume;
};*/
function queueWaveTable(audioContext, target, preset, when, pitch, duration, volume, slides) {
if (audioContext.state == 'suspended') {
console.log('audioContext.resume');
audioContext.resume();
}
/*volume = limitVolume(volume);
var zone = findZone(audioContext, preset, pitch);
if (!(zone.buffer)) {
console.log('empty buffer ', zone);
return;
}*/
//var baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune;
//var playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0);
//var sampleRatio = zone.sampleRate / audioContext.sampleRate;
/*var startWhen = when;
if (startWhen < audioContext.currentTime) {
startWhen = audioContext.currentTime;
}*/
//var waveDuration = duration + afterTime;
/*var loop = true;
if (zone.loopStart < 1 || zone.loopStart >= zone.loopEnd) {
loop = false;
}
if (!loop) {
if (waveDuration > zone.buffer.duration / playbackRate) {
waveDuration = zone.buffer.duration / playbackRate;
}
}*/
//var envelope = findEnvelope(audioContext, target, startWhen, waveDuration);
//setupEnvelope(audioContext, envelope, zone, volume, startWhen, waveDuration, duration);
//envelope.audioBufferSourceNode = audioContext.createBufferSource();
var envelope_audioBufferSourceNode = audioContext.createBufferSource();
//envelope.audioBufferSourceNode.playbackRate.setValueAtTime(playbackRate, 0);
/*if (slides) {
if (slides.length > 0) {
envelope.audioBufferSourceNode.playbackRate.setValueAtTime(playbackRate, when);
for (var i = 0; i < slides.length; i++) {
var newPlaybackRate = 1.0 * Math.pow(2, (100.0 * slides[i].pitch - baseDetune) / 1200.0);
var newWhen = when + slides[i].when;
envelope.audioBufferSourceNode.playbackRate.linearRampToValueAtTime(newPlaybackRate, newWhen);
}
}
}*/
console.log('preset',preset);
var zone1=preset.zones[1];
adjustZone(audioContext,zone1);
envelope_audioBufferSourceNode.buffer = zone1.buffer;
console.log('buffer',envelope_audioBufferSourceNode.buffer);
/*for(var i=0;i<100;i++){
console.log(envelope_audioBufferSourceNode.getChannelData()[i]);
}*/
/*if (loop) {
envelope.audioBufferSourceNode.loop = true;
envelope.audioBufferSourceNode.loopStart = zone.loopStart / zone.sampleRate + zone.delay;
envelope.audioBufferSourceNode.loopEnd = zone.loopEnd / zone.sampleRate + zone.delay;
} else {*/
envelope_audioBufferSourceNode.loop = false;
//}
envelope_audioBufferSourceNode.connect(audioContext.destination);
//console.log('duration', waveDuration);
//envelope.audioBufferSourceNode.connect(envelope);
//envelope.audioBufferSourceNode.start(startWhen, zone.delay);
envelope_audioBufferSourceNode.start();
//envelope_audioBufferSourceNode.stop(startWhen + waveDuration);
//envelope.when = startWhen;
//envelope.duration = waveDuration;
//envelope.pitch = pitch;
//envelope.preset = preset;
//return envelope;
};
var selectedPreset=_tone_0000_SoundBlasterOld_sf2;
var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContextFunc();
var clickCOunt=0;
function playStart(){
clickCOunt++;
console.log('audioContext',audioContext);
console.log('click '+14+'+'+clickCOunt);
console.log('state '+audioContext.state);
console.log('time '+audioContext.currentTime);
console.log('latency '+audioContext.baseLatency);
for(var i=0;i<selectedPreset.zones.length;i++){
console.log(''+i+': '+selectedPreset.zones[i].sample.length);
}
var envelope=queueWaveTable(audioContext, audioContext.destination, selectedPreset, 0, 55, 3.5);
//console.log('envelope',envelope);
}
</script>
</head>
<body>
<h1><a href="#" onmousedown="playStart();">Test 17</a></h1>
<hr/>
<h2><button onclick="testo();">play</button></h2>
<script>
function testo(){
console.log('start');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// create Oscillator node
var oscillator = audioCtx.createOscillator();
oscillator.type = 'square';
oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // value in hertz
oscillator.connect(audioCtx.destination);
oscillator.start();
console.log('started',oscillator);
}
</script>
</body>
</html>