File size: 4,189 Bytes
a715dd9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
// Basic Web Audio API Sound Manager
function _class_call_check(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _create_class(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
export var AudioManager = /*#__PURE__*/ function() {
"use strict";
function AudioManager() {
_class_call_check(this, AudioManager);
// Use '||' for broader browser compatibility, though 'webkit' is largely legacy
var AudioContext = window.AudioContext || window.webkitAudioContext;
this.audioCtx = null;
this.isInitialized = false;
this.lastClickTime = 0;
this.clickInterval = 200; // Milliseconds between clicks for rhythm
if (AudioContext) {
try {
this.audioCtx = new AudioContext();
this.isInitialized = true;
console.log("AudioContext created successfully.");
} catch (e) {
console.error("Error creating AudioContext:", e);
}
} else {
console.warn("Web Audio API is not supported in this browser.");
}
}
_create_class(AudioManager, [
{
// Resume audio context after user interaction (required by many browsers)
key: "resumeContext",
value: function resumeContext() {
if (this.audioCtx && this.audioCtx.state === 'suspended') {
this.audioCtx.resume().then(function() {
console.log("AudioContext resumed successfully.");
}).catch(function(e) {
return console.error("Error resuming AudioContext:", e);
});
}
}
},
{
key: "playInteractionClickSound",
value: function playInteractionClickSound() {
if (!this.isInitialized || !this.audioCtx || this.audioCtx.state !== 'running') return;
var internalCurrentTime = this.audioCtx.currentTime;
// Check if enough time has passed since the last click
if (internalCurrentTime - this.lastClickTime < this.clickInterval / 1000) {
return; // Too soon for the next click
}
this.lastClickTime = internalCurrentTime;
var oscillator = this.audioCtx.createOscillator();
var gainNode = this.audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(this.audioCtx.destination);
oscillator.type = 'sine'; // Softer waveform for a 'tic'
oscillator.frequency.setValueAtTime(1200, this.audioCtx.currentTime); // Lowered base pitch
// A very quick pitch drop can make it sound more 'clicky'
oscillator.frequency.exponentialRampToValueAtTime(600, this.audioCtx.currentTime + 0.01); // Lowered pitch drop target
var clickVolume = 0.08; // Increased volume slightly
gainNode.gain.setValueAtTime(0, this.audioCtx.currentTime); // Start silent for a clean attack
gainNode.gain.linearRampToValueAtTime(clickVolume, this.audioCtx.currentTime + 0.003); // Very fast attack
gainNode.gain.exponentialRampToValueAtTime(0.0001, this.audioCtx.currentTime + 0.005); // Keep decay short for 'tic'
oscillator.start(this.audioCtx.currentTime);
oscillator.stop(this.audioCtx.currentTime + 0.005); // Match decay duration
}
}
]);
return AudioManager;
}();
|