Stop p5.js Audio Errors: Master soundFormats() in 10 Minutes

Fix browser audio compatibility issues in p5.js projects. Learn soundFormats() with working code examples that prevent loading errors.

Your p5.js sketch was working perfectly on your laptop. Then you share it with a friend, and suddenly: "Uncaught TypeError: Cannot read properties of undefined."

Sound familiar? I spent 2 hours debugging this exact error on my first interactive music project.

What you'll learn: How to make your p5.js audio work across all browsers
Time needed: 10 minutes
Difficulty: Beginner-friendly

Here's the fix that saved my project and will save yours: soundFormats() tells p5.js which audio files to try loading, preventing those mysterious audio errors.

Why I Had to Learn This

I built a generative music visualizer for a gallery installation. Everything worked perfectly on my MacBook Pro in Chrome. The day before the opening, I tested it on the gallery's Windows machine running Firefox.

Complete silence.

My setup:

  • p5.js 1.7.0 with p5.sound library
  • Audio files in MP3 format only
  • Modern web browsers (I thought)
  • Zero backup plan for audio compatibility

What broke:

  • Firefox didn't like my MP3 encoding
  • Safari was picky about file headers
  • Edge threw cryptic loading errors
  • No fallback audio formats

Time wasted: 4 hours of panic debugging at midnight

The Root Problem: Browser Audio Support

Different browsers support different audio formats. Your MP3 might work in Chrome but fail in Firefox. Your OGG file might load in Firefox but crash Safari.

My solution: Use soundFormats() to provide multiple file formats and let p5.js pick the best one.

Time this saves: Prevents hours of cross-browser debugging

Step 1: Set Up Multiple Audio Formats

Before writing any code, you need audio files in different formats for maximum compatibility.

// Place this BEFORE preload() function
function preload() {
  // Tell p5.js which formats to try, in order of preference
  soundFormats('mp3', 'ogg', 'wav');
  
  // Load your audio file (without extension)
  mySound = loadSound('assets/background-music');
}

What this does: p5.js tries to load 'background-music.mp3' first, then 'background-music.ogg', then 'background-music.wav' until one works.

Expected file structure:

your-project/
├── sketch.js
└── assets/
    ├── background-music.mp3
    ├── background-music.ogg
    └── background-music.wav

Personal tip: "Always put soundFormats() as the first line in preload(). I learned this the hard way when my loading order caused weird timing issues."

Step 2: Convert Your Audio Files

You'll need your audio in multiple formats. Here's my streamlined workflow:

Online conversion (easiest):

  1. Upload your original file to CloudConvert or similar
  2. Convert to MP3, OGG, and WAV
  3. Keep file names identical (just different extensions)

FFmpeg command line (fastest for multiple files):

# Convert to all three formats at once
ffmpeg -i original-audio.wav \
  -codec:a libmp3lame -b:a 192k background-music.mp3 \
  -codec:a libvorbis -q:a 5 background-music.ogg \
  -codec:a pcm_s16le background-music.wav

What this creates: Three versions of your audio optimized for different browsers

Personal tip: "I keep a 'convert-audio.sh' script in my project folder. Converting 5 files takes 30 seconds instead of 20 minutes of manual work."

Step 3: Test Your Browser Compatibility

Here's the complete working example I use to test audio loading:

let mySound;
let isLoaded = false;

function preload() {
  // Set supported formats in order of preference
  soundFormats('mp3', 'ogg', 'wav');
  
  // Load audio file (p5.js will try each format)
  mySound = loadSound(
    'assets/test-audio',
    // Success callback
    () => {
      console.log('Audio loaded successfully!');
      isLoaded = true;
    },
    // Error callback
    (error) => {
      console.log('Audio loading failed:', error);
    }
  );
}

function setup() {
  createCanvas(400, 400);
  
  // Create play button after everything loads
  if (isLoaded) {
    let playBtn = createButton('Play Sound');
    playBtn.mousePressed(playAudio);
  }
}

function playAudio() {
  if (mySound && isLoaded) {
    mySound.play();
  }
}

function draw() {
  background(220);
  
  // Show loading status
  textAlign(CENTER);
  if (isLoaded) {
    text('Audio ready! Click play button.', width/2, height/2);
  } else {
    text('Loading audio...', width/2, height/2);
  }
}

Expected behavior: Console shows "Audio loaded successfully!" and you see a play button

Personal tip: "Always include error callbacks. The default p5.js error messages don't tell you which format failed or why."

Step 4: Handle Loading Errors Gracefully

Even with multiple formats, audio might fail to load. Here's my bulletproof error handling:

let sounds = {};
let audioReady = false;

function preload() {
  soundFormats('mp3', 'ogg', 'wav');
  
  // Load multiple audio files with error handling
  sounds.background = loadSound(
    'assets/background-music',
    () => console.log('Background music loaded'),
    (err) => {
      console.log('Background music failed:', err);
      sounds.background = null;
    }
  );
  
  sounds.click = loadSound(
    'assets/click-sound',
    () => console.log('Click sound loaded'),
    (err) => {
      console.log('Click sound failed:', err);
      sounds.click = null;
    }
  );
}

function setup() {
  createCanvas(400, 400);
  
  // Check what actually loaded
  audioReady = Object.values(sounds).some(sound => sound !== null);
  
  if (audioReady) {
    console.log('At least some audio loaded successfully');
  } else {
    console.log('No audio could be loaded - running in silent mode');
  }
}

function mousePressed() {
  // Safe audio playback
  if (sounds.click && sounds.click.isLoaded()) {
    sounds.click.play();
  } else {
    console.log('Click sound not available - visual feedback only');
    // Add visual feedback instead
    background(random(255), random(255), random(255));
  }
}

What this prevents: Crashes when audio files are missing or corrupted

Personal tip: "I always build a 'silent mode' into my projects. Some users have audio disabled, others have corporate firewalls that block audio files."

Common Mistakes I Made (So You Don't Have To)

Mistake 1: Wrong File Extensions

// ❌ Don't include extensions
mySound = loadSound('assets/music.mp3');

// ✅ Let p5.js choose the format
soundFormats('mp3', 'ogg', 'wav');
mySound = loadSound('assets/music');

Mistake 2: soundFormats() in Wrong Place

// ❌ Too late - loadSound already happened
function preload() {
  mySound = loadSound('assets/music');
  soundFormats('mp3', 'ogg');  // This won't work
}

// ✅ Set formats BEFORE loading
function preload() {
  soundFormats('mp3', 'ogg', 'wav');
  mySound = loadSound('assets/music');
}

Mistake 3: Not Testing File Sizes

Large audio files will timeout on slow connections. My 5MB background track caused loading failures.

My fix: Keep audio files under 1MB, use compressed formats for longer tracks.

Browser-Specific Tips That Saved My Projects

Chrome: Loves MP3, handles large files well

soundFormats('mp3', 'ogg');  // MP3 first for Chrome

Firefox: Prefers OGG, sometimes rejects MP3s with weird encoding

soundFormats('ogg', 'mp3', 'wav');  // OGG first for Firefox

Safari: Picky about MP3 headers, WAV is safest fallback

soundFormats('mp3', 'wav', 'ogg');  // WAV as safety net

Mobile browsers: Require user interaction before audio plays

function touchStarted() {
  // Enable audio context on first touch (mobile requirement)
  if (getAudioContext().state !== 'running') {
    getAudioContext().resume();
  }
}

What You Just Built

Your p5.js project now loads audio reliably across all major browsers. No more mysterious silent failures or "Cannot read properties" errors.

Key Takeaways (Save These)

  • Always use soundFormats() before loadSound(): Sets up fallback formats for browser compatibility
  • Include error callbacks: Default p5.js errors don't give enough debugging info
  • Test on multiple browsers: What works in Chrome might fail in Firefox or Safari
  • Build silent mode fallbacks: Some users can't or won't load audio files
  • Keep files under 1MB: Large audio causes timeout errors on slow connections

Your Next Steps

Pick one based on your experience level:

  • Beginner: Try loading multiple sound effects with different formats
  • Intermediate: Add audio analysis with FFT() for visual responses
  • Advanced: Build a complete audio-reactive animation system

Tools I Actually Use

  • Audacity: Free audio editing and format conversion
  • FFmpeg: Command-line batch conversion for multiple files
  • CloudConvert: Online converter when I need just one file
  • p5.js Sound Reference: Official documentation with all audio functions

Personal tip: "Bookmark this soundFormats() pattern. I reference it for every new project because browser audio support keeps changing."