diff --git a/AUDIO_SYSTEM_CHANGES.md b/AUDIO_SYSTEM_CHANGES.md new file mode 100644 index 0000000..2318420 --- /dev/null +++ b/AUDIO_SYSTEM_CHANGES.md @@ -0,0 +1,80 @@ +# Simplified Audio System Documentation + +## Overview +The audio system has been completely refactored to use a simple, dynamic approach with a streamlined directory structure. + +## Simplified Directory Structure + +### Current Structure: +``` +audio/ +├── background/ (Contains all background music/audio clips) +└── ambient/ (Empty for now, reserved for future ambient sounds) +``` + +### Previous Complex Structure (REMOVED): +- ❌ `audio/effects/` +- ❌ `audio/tasks/teasing/` +- ❌ `audio/tasks/intense/` +- ❌ `audio/tasks/instructions/` +- ❌ `audio/punishments/denial/` +- ❌ `audio/punishments/mocking/` +- ❌ `audio/rewards/completion/` + +## How It Works + +### Single Background Audio Category +- **Before**: Multiple hardcoded categories (tasks, punishments, rewards, teasing, intense, etc.) +- **After**: One dynamic "background" category that uses user-managed audio files + +### Dynamic Audio Discovery +- Audio files are loaded from the existing `customAudio` storage system +- Combines all user audio (background, ambient, effects) into one pool +- No more hardcoded file paths that can break +- Automatically refreshes when users add new audio files + +### User Experience +1. **Add Audio**: Use "Manage Audio" menu to import audio files +2. **Auto-Play**: Audio automatically plays during tasks, rewards, and consequences +3. **Single Control**: All audio settings now control the same background audio +4. **No Errors**: No more "file not found" errors from missing hardcoded files + +## Technical Changes + +### AudioManager Simplification +- `playTaskAudio()` → `playBackgroundAudio()` +- `playPunishmentAudio()` → `playBackgroundAudio()` +- `playRewardAudio()` → `playBackgroundAudio()` +- Single audio category instead of multiple complex categories + +### Game Integration +- All game events (task start, completion, skip) play from the same audio pool +- Audio automatically refreshes when users add files via "Manage Audio" +- Settings UI still shows separate controls but they all control the same audio + +### Benefits +- ✅ No more audio file path errors +- ✅ User has full control over audio content +- ✅ Simple, reliable system +- ✅ Integrates with existing UI +- ✅ No hardcoded dependencies + +## For Users + +### To Add Background Audio: +1. Place your audio files in the `audio/background/` directory +2. Open the main menu and click "Manage Audio" +3. Click "🔍 Scan Directories" to discover the files +4. Audio will automatically play during the game + +### Audio Controls: +- All volume sliders now control the same background audio +- Enable/disable toggles all control the same background audio +- Preview buttons all preview your background audio + +## Migration Notes +- Complex directory structure has been simplified to just two folders +- Existing user audio files in "Manage Audio" will automatically work +- All audio files should be placed in `audio/background/` for now +- `audio/ambient/` is reserved for future ambient sounds (leave empty) +- System is now completely user-controlled and dynamic \ No newline at end of file diff --git a/DIRECTORY_SCANNING.md b/DIRECTORY_SCANNING.md new file mode 100644 index 0000000..a296777 --- /dev/null +++ b/DIRECTORY_SCANNING.md @@ -0,0 +1,113 @@ +# Audio Directory Scanning Feature + +## Overview +The directory scanning feature automatically discovers audio files that are already present in your app's audio directory structure and adds them to your audio library. + +## How It Works + +### Automatic Scanning +- **On Startup**: The app automatically scans for audio files when it launches (desktop mode only) +- **Manual Scanning**: Use the "🔍 Scan Directories" button in the "Manage Audio" menu + +### Scanned Directories +The scanner looks for audio files in these directories: +``` +audio/ +├── background/ +└── ambient/ +``` + +### Supported Audio Formats +- **MP3** (most common) +- **WAV** (high quality) +- **OGG** (open source) +- **M4A** (Apple format) +- **AAC** (compressed) +- **FLAC** (lossless) + +## Using Directory Scanning + +### Desktop Mode (Recommended) +1. **Place Files**: Copy your audio files into the appropriate audio subdirectories +2. **Scan**: Click "🔍 Scan Directories" in the "Manage Audio" menu +3. **Auto-Use**: Scanned files are automatically added to your library and enabled + +### File Organization +- **Background Music** → `audio/background/` +- **Ambient Sounds** → `audio/ambient/` + +## Category Mapping +Due to the simplified audio system, all scanned files are categorized as follows: +- Files from `audio/ambient/` → **Ambient** category +- Files from `audio/background/` → **Background** category + +## Benefits + +### Easy Bulk Import +- Add many files at once by copying them to directories +- No need to import files one-by-one through the UI +- Perfect for organizing large audio collections + +### Automatic Discovery +- New files are found automatically on app restart +- Manual scan button for immediate discovery +- No configuration required + +### File Management +- Files stay in organized directory structure +- Easy to add/remove files outside the app +- Clear organization by purpose/category + +## Troubleshooting + +### No Files Found +- **Check Directories**: Ensure audio files are in the correct subdirectories +- **File Formats**: Verify files are in supported formats (MP3, WAV, OGG, M4A, AAC, FLAC) +- **Permissions**: Make sure the app has read access to the audio directories +- **File Names**: Avoid special characters in file names + +### Duplicate Files +- The scanner checks for existing files before adding +- Files already in your library won't be duplicated +- If you see duplicates, use the "🧹 Cleanup" button + +### Web Mode Limitations +- Directory scanning only works in desktop mode (Electron) +- Web browsers can't access file system directories +- Use the Import buttons for manual file upload in web mode + +## Tips + +### Organizing Your Audio +1. **Create Themed Folders**: Group similar audio files together +2. **Descriptive Names**: Use clear, descriptive file names +3. **Test Files**: Place a few test files first, then scan to verify + +### Performance +- Scanning is fast for hundreds of files +- Large files (>100MB) may take longer to process +- The app shows progress messages during scanning + +### Backup Strategy +- Keep original files in the audio directories +- The app creates references, not copies +- Easy to backup/restore entire audio collection + +## Integration + +### With Dynamic Audio System +- Scanned files integrate seamlessly with the dynamic audio system +- All audio management features work with scanned files +- Enable/disable scanned files individually + +### With Existing Audio +- Scanned files are added to existing audio library +- No conflicts with manually imported files +- Use both methods together for maximum flexibility + +## Next Steps + +1. **Organize Files**: Place your audio files in the appropriate directories +2. **Scan**: Use the "🔍 Scan Directories" button +3. **Test**: Try playing audio during a game session +4. **Manage**: Use the audio management UI to enable/disable specific files \ No newline at end of file diff --git a/ROADMAP.md b/ROADMAP.md index 68f22aa..11d0c78 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,11 +8,20 @@ - ✅ Scenario system with state management - ✅ Loading overlay and initialization protection - ✅ Desktop file management integration +- ✅ Continuous audio playlist system +- ✅ XP-based progression system (replaced scoring) ## 🚧 Active Development - Enhanced user experience improvements - Bug fixes and stability enhancements - Performance optimizations +- **NEW XP System Implementation:** + - Time-based XP: 1 XP per 2 minutes of gameplay + - Focus session bonuses: 5 XP per minute + - Webcam mirror bonuses: 5 XP per minute + - Photo rewards: 1 XP per picture taken + - Main game XP conversion from old point system + - No XP awarded for abandoned/quit sessions ## 📋 Feature Backlog @@ -40,6 +49,13 @@ - [ ] Media organization and tagging features - [ ] Import/export functionality for user content - [ ] Content validation and quality checks +- [ ] **Custom Audio Playlist Creation** - Allow users to create and save custom audio playlists with: + - Drag-and-drop playlist editor + - Named playlists (e.g., "Intense Session", "Relaxing Background") + - Shuffle/repeat options per playlist + - Playlist sharing and import/export + - Time-based playlist scheduling (different playlists for different game phases) + - Crossfade and transition effects between tracks ### 🔧 Technical Improvements - [ ] Code refactoring and optimization diff --git a/audio-compatibility-checker.js b/audio-compatibility-checker.js new file mode 100644 index 0000000..aa5773d --- /dev/null +++ b/audio-compatibility-checker.js @@ -0,0 +1,197 @@ +/** + * Audio Compatibility Checker and Browser Mode Handler + * This script helps detect and handle audio limitations in browser vs Electron mode + */ + +class AudioCompatibilityChecker { + constructor() { + this.isElectron = window.electronAPI !== undefined; + this.isFileProtocol = window.location.protocol === 'file:'; + this.browserAudioSupported = this.checkBrowserAudioSupport(); + } + + checkBrowserAudioSupport() { + // Test if we can create audio elements + try { + const testAudio = new Audio(); + return testAudio !== null; + } catch (error) { + console.error('Browser does not support Audio API:', error); + return false; + } + } + + async testSingleAudioFile(path) { + return new Promise((resolve) => { + const audio = new Audio(); + let resolved = false; + + const cleanup = () => { + if (!resolved) { + resolved = true; + audio.pause(); + audio.src = ''; + audio.remove(); + } + }; + + audio.addEventListener('canplay', () => { + if (!resolved) { + cleanup(); + resolve({ success: true, path, error: null }); + } + }); + + audio.addEventListener('error', (e) => { + if (!resolved) { + const errorInfo = { + code: e.target.error?.code, + message: e.target.error?.message, + networkState: e.target.networkState, + readyState: e.target.readyState, + src: e.target.src + }; + cleanup(); + resolve({ success: false, path, error: errorInfo }); + } + }); + + // Timeout after 3 seconds + setTimeout(() => { + if (!resolved) { + cleanup(); + resolve({ success: false, path, error: 'timeout' }); + } + }, 3000); + + // Try to load the audio + try { + audio.src = path; + audio.load(); + } catch (error) { + if (!resolved) { + cleanup(); + resolve({ success: false, path, error: error.message }); + } + } + }); + } + + async quickAudioTest() { + console.log('🎵 Audio Compatibility Test Starting...'); + console.log(`🎵 Environment: ${this.isElectron ? 'Electron' : 'Browser'}`); + console.log(`🎵 Protocol: ${window.location.protocol}`); + console.log(`🎵 Audio API Support: ${this.browserAudioSupported}`); + + // Test a few known audio files + const testFiles = [ + 'audio/tasks/teasing/u.mp3', + 'audio/rewards/completion/u.mp3' + ]; + + const results = []; + for (const file of testFiles) { + console.log(`🎵 Testing: ${file}`); + const result = await this.testSingleAudioFile(file); + results.push(result); + + if (result.success) { + console.log(`✅ ${file} - Working`); + } else { + console.log(`❌ ${file} - Failed:`, result.error); + } + + // Small delay between tests + await new Promise(resolve => setTimeout(resolve, 100)); + } + + return results; + } + + getRecommendations() { + const recommendations = []; + + if (!this.isElectron && this.isFileProtocol) { + recommendations.push({ + type: 'warning', + message: 'Running in browser with file:// protocol', + suggestion: 'Use "npm start" to run the Electron desktop version for full audio support' + }); + } + + if (!this.browserAudioSupported) { + recommendations.push({ + type: 'error', + message: 'Browser does not support HTML5 Audio API', + suggestion: 'Try a different browser or update your current browser' + }); + } + + if (this.isElectron) { + recommendations.push({ + type: 'success', + message: 'Running in Electron desktop mode', + suggestion: 'Audio should work without restrictions' + }); + } + + return recommendations; + } + + async diagnoseAudioIssues() { + console.log('🎵 Audio Diagnostic Report'); + console.log('=' .repeat(50)); + + const recommendations = this.getRecommendations(); + recommendations.forEach(rec => { + const icon = rec.type === 'error' ? '❌' : rec.type === 'warning' ? '⚠️' : '✅'; + console.log(`${icon} ${rec.message}`); + console.log(` 💡 ${rec.suggestion}`); + }); + + console.log('\n🎵 Testing Audio Files...'); + const testResults = await this.quickAudioTest(); + + const workingFiles = testResults.filter(r => r.success).length; + const totalFiles = testResults.length; + + console.log('\n🎵 Summary:'); + console.log(`✅ Working: ${workingFiles}/${totalFiles}`); + console.log(`❌ Failed: ${totalFiles - workingFiles}/${totalFiles}`); + + if (workingFiles === 0) { + console.log('\n🎵 No audio files are working. This suggests:'); + console.log(' - Browser CORS restrictions (use Electron app)'); + console.log(' - Audio files are corrupted or missing'); + console.log(' - Browser audio support issues'); + } else if (workingFiles < totalFiles) { + console.log('\n🎵 Some audio files are working. Issues may be:'); + console.log(' - Specific file corruption'); + console.log(' - Filename/path issues'); + console.log(' - Audio format compatibility'); + } else { + console.log('\n🎵 All tested files are working! 🎉'); + } + + return { + environment: { + isElectron: this.isElectron, + isFileProtocol: this.isFileProtocol, + audioSupported: this.browserAudioSupported + }, + testResults, + recommendations + }; + } +} + +// Auto-run diagnostic if audio issues are detected +window.audioCompatibilityChecker = new AudioCompatibilityChecker(); + +// Quick check for common issues +if (!window.audioCompatibilityChecker.isElectron && window.audioCompatibilityChecker.isFileProtocol) { + console.log('🎵 Audio issues detected! Run window.audioCompatibilityChecker.diagnoseAudioIssues() for full report'); +} + +console.log('🎵 Audio Compatibility Checker loaded'); +console.log('🎵 Run: window.audioCompatibilityChecker.diagnoseAudioIssues()'); \ No newline at end of file diff --git a/audio-validator.js b/audio-validator.js new file mode 100644 index 0000000..f00d283 --- /dev/null +++ b/audio-validator.js @@ -0,0 +1,143 @@ +/** + * Audio File Validator + * This script tests which audio files can actually be loaded by the browser + */ + +async function validateAudioFiles() { + console.log('🎵 Starting audio file validation...'); + + const audioStructure = { + tasks: { + teasing: [ + 'enjoying-a-giant-cock.mp3', + 'horny-japanese-babe-japanese-sex.mp3', + 'long-and-hard-moan.mp3', + 'playing-her-pussy-with-a-dildo-japanese-sex.mp3', + 'u.mp3' + ], + intense: [ + 'bree-olson-screaming-orgasm-sound.mp3', + 'carmela-bing-screaming-orgasm-sound.mp3', + 'moaning-ringtone.mp3', + 'multiple-orgasms-with-creamy-pussy.mp3' + ], + instructions: [ + 'addict-to-my-tits-854x480p.mp3', + 'deeper.mp3', + 'you-love-to-goon.mp3' + ] + }, + punishments: { + denial: [ + 'addicted-to-my-tits-tit-worship-mesmerize-joi-mov.mp3', + 'dumb-gooner-bitch-4-big-tits.mp3', + 'you-will-be-left-thoughtless.mp3' + ], + mocking: [ + 'precise-denial.mp3', + 'punishment-episode-cockring-causes-cumshots-cumshots-gameplay-only.mp3', + 'quick-jerk-to-tits-in-pink-bra-1080p-ellie-idol.mp3', + 'stroke-your-goon-bud.mp3' + ] + }, + rewards: { + completion: ['u.mp3'] + } + }; + + const results = { + working: [], + failed: [], + total: 0 + }; + + for (const [category, subcategories] of Object.entries(audioStructure)) { + for (const [subcategory, files] of Object.entries(subcategories)) { + for (const file of files) { + const audioPath = `audio/${category}/${subcategory}/${file}`; + results.total++; + + try { + const canLoad = await testAudioFile(audioPath); + if (canLoad) { + results.working.push(audioPath); + console.log(`✅ ${audioPath} - OK`); + } else { + results.failed.push(audioPath); + console.log(`❌ ${audioPath} - FAILED`); + } + } catch (error) { + results.failed.push(audioPath); + console.log(`❌ ${audioPath} - ERROR: ${error.message}`); + } + + // Small delay to prevent browser overload + await new Promise(resolve => setTimeout(resolve, 100)); + } + } + } + + console.log('\n🎵 Audio Validation Results:'); + console.log(`✅ Working files: ${results.working.length}/${results.total}`); + console.log(`❌ Failed files: ${results.failed.length}/${results.total}`); + + if (results.failed.length > 0) { + console.log('\n❌ Failed files:'); + results.failed.forEach(file => console.log(` - ${file}`)); + } + + if (results.working.length > 0) { + console.log('\n✅ Working files:'); + results.working.forEach(file => console.log(` - ${file}`)); + } + + return results; +} + +async function testAudioFile(audioPath) { + return new Promise((resolve) => { + const audio = new Audio(audioPath); + let resolved = false; + + const cleanup = () => { + if (!resolved) { + resolved = true; + audio.pause(); + audio.src = ''; + } + }; + + audio.addEventListener('canplay', () => { + if (!resolved) { + cleanup(); + resolve(true); + } + }); + + audio.addEventListener('error', () => { + if (!resolved) { + cleanup(); + resolve(false); + } + }); + + // Timeout after 5 seconds + setTimeout(() => { + if (!resolved) { + cleanup(); + resolve(false); + } + }, 5000); + + // Start loading + audio.load(); + }); +} + +// Make functions available globally +window.audioValidator = { + validateAudioFiles, + testAudioFile +}; + +console.log('🎵 Audio validator loaded. Run: window.audioValidator.validateAudioFiles()'); \ No newline at end of file diff --git a/audio/TESTING.md b/audio/TESTING.md index 2342220..88ec5f3 100644 --- a/audio/TESTING.md +++ b/audio/TESTING.md @@ -5,10 +5,8 @@ This is a placeholder for test audio. ## To test the audio system: 1. **Add real audio files** to the appropriate directories: - - `/audio/tasks/teasing/` - Add MP3 files like `tease1.mp3`, `whisper1.mp3` - - `/audio/punishments/denial/` - Add MP3 files like `denied.mp3`, `bad_boy.mp3` - - `/audio/punishments/mocking/` - Add MP3 files like `pathetic.mp3`, `weak.mp3` - - `/audio/rewards/completion/` - Add MP3 files like `good_boy.mp3`, `well_done.mp3` + - `/audio/background/` - Add MP3 files for background music during tasks + - `/audio/ambient/` - Add MP3 files for ambient sounds (optional, leave empty for now) 2. **Test the controls**: - Open the game and go to Options ⚙️ @@ -17,10 +15,10 @@ This is a placeholder for test audio. - Use preview buttons to test audio 3. **Test in gameplay**: - - Start a task → Should play teasing/intense audio - - Complete a task → Should play reward audio - - Skip a task → Should play mocking audio - - Get a consequence task → Should play denial audio + - Start a task → Should play background audio + - Complete a task → Should play background audio + - Skip a task → Should play background audio + - All audio now comes from the background category ## Current Features Working: diff --git a/clear-audio-debug.js b/clear-audio-debug.js new file mode 100644 index 0000000..250d2e4 --- /dev/null +++ b/clear-audio-debug.js @@ -0,0 +1,55 @@ +// Audio Debug Script - Clear corrupted audio data and trigger fresh scan + +console.log('🧹 Starting comprehensive audio cleanup...'); + +// Clear existing customAudio data completely and restart fresh +if (window.game && window.game.dataManager) { + console.log('🗑️ Clearing all existing audio data to start fresh...'); + + // Completely reset audio storage + window.game.dataManager.set('customAudio', { background: [], ambient: [] }); + console.log('✅ Cleared all customAudio storage'); + + // Clear any cached audio library + if (window.game.audioManager) { + window.game.audioManager.audioLibrary = { + background: { general: [] } + }; + console.log('✅ Cleared audio library cache'); + } + + // Now trigger a fresh directory scan if available + if (window.game.audioManager && window.game.audioManager.scanAudioDirectories) { + console.log('🔍 Triggering fresh directory scan...'); + window.game.audioManager.scanAudioDirectories().then((scannedFiles) => { + console.log(`✅ Fresh scan completed - found ${scannedFiles.length} files`); + + // Refresh the audio manager + return window.game.audioManager.refreshAudioLibrary(); + }).then(() => { + console.log('✅ Audio library refreshed with clean data'); + + // Refresh the audio gallery + if (window.game.loadAudioGallery) { + window.game.loadAudioGallery(); + console.log('✅ Audio gallery refreshed'); + } + }).catch(error => { + console.error('❌ Error during fresh scan:', error); + }); + } else { + console.log('⚠️ Directory scanning not available - try the "Scan Directories" button in Manage Audio'); + + // Just refresh what we have + if (window.game.audioManager) { + window.game.audioManager.refreshAudioLibrary().then(() => { + console.log('✅ Audio library refreshed'); + }); + } + } + +} else { + console.error('❌ Game or dataManager not available'); +} + +console.log('🎯 Cleanup script completed. Check the console for results and try playing audio.'); \ No newline at end of file diff --git a/clear-audio-storage.js b/clear-audio-storage.js new file mode 100644 index 0000000..117c158 --- /dev/null +++ b/clear-audio-storage.js @@ -0,0 +1,33 @@ +// Clear Audio Storage Script - Reset all audio data to start fresh + +console.log('🧹 Clearing all audio storage data...'); + +// Clear all audio-related storage +if (window.game && window.game.dataManager) { + console.log('🗑️ Clearing customAudio storage...'); + window.game.dataManager.set('customAudio', { background: [], ambient: [] }); + + console.log('🗑️ Clearing audio library cache...'); + if (window.game.audioManager) { + window.game.audioManager.audioLibrary = { + background: { general: [] } + }; + } + + console.log('🔄 Refreshing audio library...'); + if (window.game.audioManager) { + window.game.audioManager.refreshAudioLibrary().then(() => { + console.log('✅ Audio library refreshed'); + + // Refresh the UI + if (window.game.loadAudioGallery) { + window.game.loadAudioGallery(); + console.log('✅ Audio gallery refreshed'); + } + }); + } + + console.log('✅ All audio storage cleared successfully'); +} else { + console.error('❌ Game or dataManager not available'); +} \ No newline at end of file diff --git a/debug-audio-test.js b/debug-audio-test.js new file mode 100644 index 0000000..40fb96f --- /dev/null +++ b/debug-audio-test.js @@ -0,0 +1,147 @@ +/** + * Audio Overlap Debug Test Script + * + * This script helps test that background sounds stop properly when progressing through tasks. + * + * To use: + * 1. Start the game and begin playing + * 2. Open the browser console (F12) + * 3. Copy and paste this script into the console + * 4. Press Enter to run the test + * + * The test will simulate rapid task progression and monitor for audio overlaps. + */ + +console.log('🎵 Starting Audio Overlap Test...'); + +// Function to test audio stopping +function testAudioStopping() { + if (!window.game || !window.game.audioManager) { + console.error('❌ Game or AudioManager not available'); + return; + } + + const audioManager = window.game.audioManager; + + console.log('🎵 Testing audio category stopping...'); + + // Test rapid audio switching + let testCount = 0; + const maxTests = 5; + + const testInterval = setInterval(() => { + testCount++; + console.log(`🎵 Test ${testCount}/${maxTests}: Playing task audio...`); + + // Stop all audio first + audioManager.stopAllImmediate(); + + // Wait a bit, then play new audio + setTimeout(() => { + audioManager.playTaskAudio('teasing', { fadeIn: 500, loop: true }); + + // Check how many audio elements are playing after a short delay + setTimeout(() => { + const currentlyPlaying = audioManager.getCurrentlyPlaying(); + const playingCount = Object.keys(currentlyPlaying).length; + + console.log(`🎵 Test ${testCount}: ${playingCount} audio tracks currently playing`); + console.log('🎵 Playing audio details:', currentlyPlaying); + + if (playingCount > 1) { + console.warn(`⚠️ WARNING: ${playingCount} tracks playing simultaneously!`); + } else { + console.log('✅ Audio overlap test passed'); + } + }, 100); + }, 50); + + if (testCount >= maxTests) { + clearInterval(testInterval); + console.log('🎵 Audio overlap test completed'); + + // Clean up + setTimeout(() => { + audioManager.stopAllImmediate(); + console.log('🎵 Test cleanup completed'); + }, 2000); + } + }, 1000); +} + +// Function to monitor audio during actual gameplay +function monitorGameplayAudio() { + if (!window.game || !window.game.audioManager) { + console.error('❌ Game or AudioManager not available'); + return; + } + + console.log('🎵 Starting gameplay audio monitoring...'); + console.log('🎵 Quickly complete or skip several tasks to test audio overlap prevention'); + + // Monitor audio every 500ms + const monitorInterval = setInterval(() => { + const currentlyPlaying = window.game.audioManager.getCurrentlyPlaying(); + const playingCount = Object.keys(currentlyPlaying).length; + + if (playingCount > 1) { + console.warn(`⚠️ AUDIO OVERLAP DETECTED: ${playingCount} tracks playing!`); + console.log('🎵 Overlapping audio details:', currentlyPlaying); + } else if (playingCount === 1) { + console.log(`✅ Single audio track playing (normal)`); + } + }, 500); + + // Stop monitoring after 30 seconds + setTimeout(() => { + clearInterval(monitorInterval); + console.log('🎵 Audio monitoring stopped'); + }, 30000); + + return monitorInterval; +} + +// Function to test rapid task progression simulation +function simulateRapidProgression() { + if (!window.game || !window.game.gameState || !window.game.gameState.isRunning) { + console.error('❌ Game not running - start a game first'); + return; + } + + console.log('🎵 Simulating rapid task progression...'); + + let progressCount = 0; + const maxProgress = 3; + + const progressInterval = setInterval(() => { + progressCount++; + console.log(`🎵 Rapid progression test ${progressCount}/${maxProgress}`); + + // Simulate completing a task (this should stop audio and start new audio) + if (window.game.gameState.isRunning) { + window.game.completeTask(); + } + + if (progressCount >= maxProgress) { + clearInterval(progressInterval); + console.log('🎵 Rapid progression test completed'); + } + }, 200); // Very fast progression to test overlap +} + +// Run the tests +console.log('🎵 Audio Debug Test Menu:'); +console.log('🎵 1. Run testAudioStopping() - Tests basic audio stopping'); +console.log('🎵 2. Run monitorGameplayAudio() - Monitors for overlaps during gameplay'); +console.log('🎵 3. Run simulateRapidProgression() - Simulates rapid task progression'); +console.log('🎵 Example: testAudioStopping()'); + +// Make functions available globally for manual testing +window.audioDebugTest = { + testAudioStopping, + monitorGameplayAudio, + simulateRapidProgression +}; + +console.log('🎵 Functions available as window.audioDebugTest.*'); +console.log('🎵 Quick test: window.audioDebugTest.testAudioStopping()'); \ No newline at end of file diff --git a/electron-audio-debug.js b/electron-audio-debug.js new file mode 100644 index 0000000..4ad16fd --- /dev/null +++ b/electron-audio-debug.js @@ -0,0 +1,105 @@ +/** + * Electron Audio Path Debug Script + * Run this in the console to debug audio path issues in Electron + */ + +function debugElectronAudioPaths() { + console.log('🔧 Electron Audio Path Debug'); + console.log('=' .repeat(50)); + + console.log('Environment Info:'); + console.log('- Is Electron:', window.electronAPI !== undefined); + console.log('- Current URL:', window.location.href); + console.log('- Current Protocol:', window.location.protocol); + console.log('- Current Directory:', window.location.href.replace('/index.html', '')); + + // Test basic audio creation + console.log('\n🎵 Testing Basic Audio Creation:'); + try { + const testAudio = new Audio(); + console.log('✅ Audio element created successfully'); + console.log('- Initial src:', testAudio.src); + + // Test setting a simple relative path + testAudio.src = 'audio/tasks/teasing/u.mp3'; + console.log('- After setting relative path:', testAudio.src); + + // Test setting an absolute file path + const absolutePath = window.location.href.replace('/index.html', '') + '/audio/tasks/teasing/u.mp3'; + testAudio.src = absolutePath; + console.log('- After setting absolute path:', testAudio.src); + + testAudio.src = ''; + } catch (error) { + console.error('❌ Error creating audio element:', error); + } + + // Test actual file access + console.log('\n📁 Testing File Access:'); + + const testPaths = [ + 'audio/tasks/teasing/u.mp3', + './audio/tasks/teasing/u.mp3', + window.location.href.replace('/index.html', '') + '/audio/tasks/teasing/u.mp3' + ]; + + testPaths.forEach((path, index) => { + console.log(`\nTest ${index + 1}: ${path}`); + + const audio = new Audio(); + + audio.addEventListener('loadstart', () => { + console.log(` ✅ Load started for: ${path}`); + }); + + audio.addEventListener('canplay', () => { + console.log(` ✅ Can play: ${path}`); + audio.src = ''; // Clean up + }); + + audio.addEventListener('error', (e) => { + console.log(` ❌ Error loading: ${path}`); + console.log(` Error details:`, { + error: e.target.error, + src: e.target.src, + networkState: e.target.networkState, + readyState: e.target.readyState + }); + }); + + try { + audio.src = path; + setTimeout(() => { + if (audio.readyState === 0 && audio.networkState !== 2) { + console.log(` ⏰ Timeout for: ${path}`); + } + }, 2000); + } catch (error) { + console.log(` ❌ Exception setting src: ${error.message}`); + } + }); + + // Test if electronAPI is available and working + if (window.electronAPI) { + console.log('\n⚡ Testing Electron API:'); + + window.electronAPI.fileExists('audio/tasks/teasing/u.mp3').then(exists => { + console.log('- File exists (relative):', exists); + }).catch(err => { + console.log('- Error checking file existence:', err); + }); + + window.electronAPI.getAppPath().then(appPath => { + console.log('- App path:', appPath); + }).catch(err => { + console.log('- Error getting app path:', err); + }); + } +} + +// Auto-run the debug +console.log('🔧 Electron Audio Debug loaded. Running automatic test...'); +debugElectronAudioPaths(); + +// Make function available globally +window.debugElectronAudioPaths = debugElectronAudioPaths; \ No newline at end of file diff --git a/index.html b/index.html index 5487686..202b9e4 100644 --- a/index.html +++ b/index.html @@ -130,22 +130,22 @@
- -