Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/AudioManager.js
2026-01-16 02:43:46 +01:00

569 lines
16 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AUDIO MANAGER - Centralized Audio System
* Handles all music, voiceover, and SFX playback
* Includes DEBUG MODE for tracking what plays where
*/
class AudioManager {
constructor() {
this.scene = null;
this.debugMode = true; // SET TO FALSE TO DISABLE LOGGING
// 🎥 STREAMER MODE (DMCA Protection)
this.streamerMode = false;
this.loadStreamerMode();
// Current playback tracking
this.currentMusic = null;
this.currentVoice = null;
this.musicVolume = 0.7;
this.voiceVolume = 0.8;
this.sfxVolume = 0.5;
// Copyright-safe tracks (CC BY 4.0)
this.safeMusicTracks = [
'intro_ambient', 'main_theme', 'farm_ambient', 'forest_ambient',
'night_theme', 'town_theme', 'wilderness_theme', 'combat_theme',
'ana_theme', 'raid_warning', 'victory_theme'
];
// Audio mapping
this.audioMap = {
music: {
intro: 'intro_ambient',
menu: 'main_theme',
farm: 'farm_ambient',
forest: 'forest_ambient',
night: 'night_theme',
town: 'town_theme',
wilderness: 'wilderness_theme',
combat: 'combat_theme',
ana: 'ana_theme',
raid: 'raid_warning',
victory: 'victory_theme'
},
voice: {
kai_en: Array.from({ length: 12 }, (_, i) => `kai_en_${String(i + 1).padStart(2, '0')}`),
ana_en: Array.from({ length: 8 }, (_, i) => `ana_en_${String(i + 1).padStart(2, '0')}`),
gronk_en: ['gronk_en_01']
},
sfx: {
ui_click: 'ui_click',
ui_hover: 'ui_hover',
plant: 'plant_seed',
water: 'water_crops',
harvest: 'harvest_crop',
cat_meow: 'cat_meow',
dog_bark: 'dog_bark',
susi_bark: 'susi_bark',
memory_found: 'memory_found',
level_up: 'level_up'
}
};
// License attribution
this.attribution = {
music: 'Music by Kevin MacLeod (incompetech.com)\nLicensed under Creative Commons: By Attribution 3.0\nhttp://creativecommons.org/licenses/by/3.0/',
voices: 'Voices generated using Microsoft Azure Edge TTS\nVoices: en-US-ChristopherNeural, en-US-AriaNeural, en-GB-RyanNeural'
};
}
/**
* INITIALIZE AUDIO MANAGER
*/
init(scene) {
this.scene = scene;
this.log('AudioManager initialized', 'INIT');
}
/**
* DEBUG LOGGER
*/
log(message, type = 'INFO', details = {}) {
if (!this.debugMode) return;
const emoji = {
'MUSIC': '🎵',
'VOICE': '🎤',
'SFX': '🔊',
'INIT': '🎛️',
'STOP': '⏹️',
'ERROR': '❌',
'INFO': ''
};
const timestamp = new Date().toLocaleTimeString();
console.log(`${emoji[type] || '📢'} [${type}] ${timestamp} - ${message}`);
if (Object.keys(details).length > 0) {
console.log(' Details:', details);
}
}
/**
* PLAY MUSIC
*
* COPYRIGHT ATTRIBUTION:
* All music tracks are by Kevin MacLeod (incompetech.com)
* Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0)
* License URL: http://creativecommons.org/licenses/by/4.0/
*
* REQUIRED CREDIT:
* "Music by Kevin MacLeod (incompetech.com)
* Licensed under Creative Commons: By Attribution 4.0
* http://creativecommons.org/licenses/by/4.0/"
*
* See /docs/CREDITS.txt for complete attribution
*/
playMusic(key, options = {}) {
if (!this.scene) {
this.log('Scene not initialized!', 'ERROR');
return null;
}
// Stop current music
if (this.currentMusic) {
this.stopMusic();
}
// Get file key from map
const fileKey = this.audioMap.music[key] || key;
// Check if audio exists
if (!this.scene.cache.audio.exists(fileKey)) {
this.log(`Music not found: ${fileKey}`, 'ERROR');
return null;
}
// Play music
const config = {
volume: options.volume || this.musicVolume,
loop: options.loop !== undefined ? options.loop : true,
...options
};
this.currentMusic = this.scene.sound.add(fileKey, config);
this.currentMusic.play();
// Debug log
this.log(`Playing: ${fileKey}.mp3`, 'MUSIC', {
scene: this.scene.scene.key,
volume: config.volume,
loop: config.loop,
attribution: 'Kevin MacLeod (incompetech.com)'
});
return this.currentMusic;
}
/**
* STOP MUSIC
*/
stopMusic(fadeOut = true) {
if (!this.currentMusic) return;
this.log(`Stopping: ${this.currentMusic.key}`, 'STOP');
if (fadeOut) {
this.scene.tweens.add({
targets: this.currentMusic,
volume: 0,
duration: 1000,
onComplete: () => {
if (this.currentMusic) {
this.currentMusic.stop();
this.currentMusic = null;
}
}
});
} else {
this.currentMusic.stop();
this.currentMusic = null;
}
}
/**
* CROSSFADE MUSIC
*/
crossfadeMusic(newKey, duration = 2000) {
const oldMusic = this.currentMusic;
// Start new music at volume 0
const newMusic = this.playMusic(newKey, { volume: 0 });
if (!newMusic) return;
// Fade out old, fade in new
if (oldMusic) {
this.scene.tweens.add({
targets: oldMusic,
volume: 0,
duration: duration,
onComplete: () => {
oldMusic.stop();
}
});
}
this.scene.tweens.add({
targets: newMusic,
volume: this.musicVolume,
duration: duration
});
this.log(`Crossfading to: ${newKey}`, 'MUSIC', {
duration: `${duration}ms`,
from: oldMusic ? oldMusic.key : 'none'
});
this.currentMusic = newMusic;
}
/**
* PLAY VOICE
*
* COPYRIGHT ATTRIBUTION:
* Voice Acting - Internal Assets
*
* PROJECT: Hipodevil666 Studios - Antigravity IDE Internal Assets
* VOICES: Christopher & Aria (AI High-Fidelity Voice Synthesis)
* LANGUAGES: English (EN) & Slovenian (SL)
*
* CHARACTERS:
* - Kai (Protagonist): Christopher Voice (AI-generated, male, young adult)
* - Ana (Twin Sister): Aria Voice (AI-generated, female, young adult)
* - Gronk (Orc Mentor): Custom deep voice synthesis
*
* TECHNOLOGY:
* High-fidelity AI voice synthesis technology
* Internal studio assets - Hipodevil666 Studios
* Licensed for commercial use in this project
*
* See /docs/CREDITS.txt for complete attribution
*/
playVoice(key, subtitleText = '') {
if (!this.scene) {
this.log('Scene not initialized!', 'ERROR');
return null;
}
// Stop current voice
if (this.currentVoice && this.currentVoice.isPlaying) {
this.currentVoice.stop();
}
// Check if audio exists
if (!this.scene.cache.audio.exists(key)) {
this.log(`Voice not found: ${key}`, 'ERROR');
return null;
}
// Play voice
this.currentVoice = this.scene.sound.add(key, {
volume: this.voiceVolume
});
this.currentVoice.play();
// Debug log
this.log(`Playing: ${key}.mp3`, 'VOICE', {
scene: this.scene.scene.key,
subtitle: subtitleText || '(no subtitle)',
volume: this.voiceVolume,
duration: `~3s`
});
return this.currentVoice;
}
/**
* PLAY SFX
*
* COPYRIGHT ATTRIBUTION:
* Sound effects from Freesound.org (CC BY 4.0)
* License: https://creativecommons.org/licenses/by/4.0/
*
* CREDITED AUTHORS:
*
* 1. COW SOUND EFFECT
* Author: Benboncan
* Link: https://freesound.org/s/58277/
* License: CC BY 4.0
*
* 2. MINING & HAMMER SOUNDS
* Author: InspectorJ (www.jshaw.co.uk)
* Link: https://freesound.org/s/420878/
* License: CC BY 4.0
*
* 3. INTRO FOREST AMBIENCE
* Author: reinsamba
* Link: https://freesound.org/s/18765/
* License: CC BY 4.0
*
* 4. BASEMENT WATER DROPS
* Author: erlipresidente
* Link: https://freesound.org/s/415885/
* License: CC BY 4.0
*
* 5. COMBAT / ZOMBIE HIT
* Author: MisterKidX
* Link: https://freesound.org/s/454837/
* License: CC BY 4.0
*
* TOOLS USED:
* - Audacity (GPL v2) - https://www.audacityteam.org/
* - LMMS (GPL v2) - https://lmms.io/
*
* See /docs/CREDITS.txt for complete attribution
*/
playSFX(key, options = {}) {
if (!this.scene) {
this.log('Scene not initialized!', 'ERROR');
return null;
}
// Get file key from map
const fileKey = this.audioMap.sfx[key] || key;
// Check if audio exists
if (!this.scene.cache.audio.exists(fileKey)) {
this.log(`SFX not found: ${fileKey}`, 'ERROR');
return null;
}
// Play SFX
const config = {
volume: options.volume || this.sfxVolume,
loop: options.loop || false,
detune: options.detune || 0,
...options
};
const sfx = this.scene.sound.add(fileKey, config);
sfx.play();
// Debug log
this.log(`Playing: ${fileKey}.wav`, 'SFX', {
scene: this.scene.scene.key,
trigger: options.trigger || 'manual',
volume: config.volume,
loop: config.loop
});
return sfx;
}
/**
* PLAY UI SOUND
*/
playUI(action) {
const sounds = {
click: 'ui_click',
hover: 'ui_hover',
open: 'ui_open',
close: 'ui_close',
error: 'ui_error'
};
if (sounds[action]) {
this.playSFX(sounds[action], {
trigger: `UI ${action}`,
volume: this.sfxVolume * 0.8
});
}
}
/**
* PLAY FARMING SOUND
*/
playFarming(action) {
const sounds = {
plant: 'plant',
water: 'water',
harvest: 'harvest',
hoe: 'hoe_dirt'
};
if (sounds[action]) {
this.playSFX(sounds[action], {
trigger: `Farming: ${action}`,
volume: this.sfxVolume
});
}
}
/**
* PLAY ANIMAL SOUND
*/
playAnimal(type) {
const sounds = {
cat: 'cat_meow',
dog: 'dog_bark',
susi: 'susi_bark'
};
if (sounds[type]) {
this.playSFX(sounds[type], {
trigger: `Animal: ${type}`,
volume: this.sfxVolume * 0.7,
detune: Phaser.Math.Between(-200, 200) // Vary pitch
});
}
}
/**
* PLAY SPECIAL EFFECT
*/
playSpecial(event) {
const sounds = {
memory: 'memory_found',
levelup: 'level_up',
quest: 'quest_complete',
unlock: 'companion_unlock'
};
if (sounds[event]) {
this.playSFX(sounds[event], {
trigger: `Special: ${event}`,
volume: this.sfxVolume * 1.2 // Louder for important events
});
}
}
/**
* SET VOLUMES
*/
setMusicVolume(volume) {
this.musicVolume = Phaser.Math.Clamp(volume, 0, 1);
if (this.currentMusic) {
this.currentMusic.setVolume(this.musicVolume);
}
this.log(`Music volume set to: ${this.musicVolume}`, 'INFO');
}
setVoiceVolume(volume) {
this.voiceVolume = Phaser.Math.Clamp(volume, 0, 1);
this.log(`Voice volume set to: ${this.voiceVolume}`, 'INFO');
}
setSFXVolume(volume) {
this.sfxVolume = Phaser.Math.Clamp(volume, 0, 1);
this.log(`SFX volume set to: ${this.sfxVolume}`, 'INFO');
}
/**
* MUTE ALL AUDIO
*/
muteAll() {
if (this.scene) {
this.scene.sound.mute = true;
this.log('All audio muted', 'INFO');
}
}
/**
* UNMUTE ALL AUDIO
*/
unmuteAll() {
if (this.scene) {
this.scene.sound.mute = false;
this.log('All audio unmuted', 'INFO');
}
}
/**
* STOP ALL AUDIO
*/
stopAll() {
if (this.scene) {
this.scene.sound.stopAll();
this.currentMusic = null;
this.currentVoice = null;
this.log('All audio stopped', 'STOP');
}
}
/**
* GET ATTRIBUTION TEXT
*/
getAttribution(type = 'all') {
if (type === 'music') {
return this.attribution.music;
} else if (type === 'voices') {
return this.attribution.voices;
} else {
return `${this.attribution.music}\n\n${this.attribution.voices}`;
}
}
/**
* ENABLE/DISABLE DEBUG MODE
*/
setDebugMode(enabled) {
this.debugMode = enabled;
this.log(`Debug mode ${enabled ? 'enabled' : 'disabled'}`, 'INFO');
}
/**
* 🎥 STREAMER MODE - DMCA PROTECTION
*/
enableStreamerMode() {
this.streamerMode = true;
localStorage.setItem('streamer_mode', 'true');
// Mute music if currently playing non-safe track
if (this.currentMusic && !this.isSafeTrack(this.currentMusic.key)) {
this.stopMusic();
console.log('🎥 STREAMER MODE: Music stopped (DMCA protection)');
}
console.log('🎥 STREAMER MODE ENABLED');
console.log(' ✅ Safe for Twitch/YouTube');
console.log(' ✅ All music is CC BY 4.0 (Kevin MacLeod)');
console.log(' ✅ No copyright strikes possible');
}
disableStreamerMode() {
this.streamerMode = false;
localStorage.setItem('streamer_mode', 'false');
console.log('🎥 Streamer mode disabled');
}
loadStreamerMode() {
const saved = localStorage.getItem('streamer_mode');
if (saved === 'true') {
this.streamerMode = true;
console.log('🎥 Streamer mode loaded from settings');
}
}
isStreamerModeEnabled() {
return this.streamerMode;
}
isSafeTrack(trackKey) {
return this.safeMusicTracks.includes(trackKey);
}
getStreamerStatus() {
if (this.streamerMode) {
return {
enabled: true,
status: 'Streamer Mode: ON - Safe for Twitch/YouTube',
license: 'All music: CC BY 4.0 (Kevin MacLeod)',
safe: true
};
} else {
return {
enabled: false,
status: 'Streamer Mode: OFF',
license: 'Music may be copyrighted',
safe: false
};
}
}
}
// Singleton export
const audioManager = new AudioManager();
export default audioManager;