Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea
.DS_Store
FMOD\ Programmers\ API/
.fmod203/
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

## [Unreleased] - 2024-09-25

### Added
- Support for FMOD 2.03.09
- `play_sound` example with progress tracking
- `run_fmod.sh` convenience script

### Changed
- `System::getVersion()` returns `(version, buildnumber)` tuple
- Field filtering for removed/renamed structure fields

### Breaking Changes
- `System::getVersion()` signature changed
- `FMOD_ADVANCEDSETTINGS.commandQueueSize` removed
- Requires FMOD 2.03.09 SDK
125 changes: 125 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

libfmod is a Rust bindings library for FMOD Engine audio middleware. The project consists of two main components:
- **libfmod-gen**: A code generator that parses FMOD C headers and generates Rust FFI bindings
- **libfmod**: The main library providing safe Rust wrappers around FMOD's C API

**Current Focus**: Migrating from FMOD 2.02.22 to 2.03.09 (see docs/ folder for detailed plans)

## Build Commands

### Building the main library
```bash
cd libfmod
cargo build
cargo build --features logging # Build with FMOD logging libraries
```

### Running the generator
```bash
cd libfmod-gen
cargo run -- [fmod_sdk_path] [output_dir]
# Default: cargo run -- ./fmod/20222 ../libfmod
```

### Testing
```bash
# Run library tests (requires FMOD libraries installed)
cd libfmod
export LD_LIBRARY_PATH=$FMOD_SDK_PATH/api/core/lib/x86_64:$LD_LIBRARY_PATH
cargo test -- --test-threads=1

# Run specific test
cargo test test_name -- --nocapture

# Run manual tests
cargo test --test manual -- --ignored
```

### Code formatting and linting
```bash
cargo fmt
cargo clippy
```

## Architecture

### Code Generation Pipeline
1. **Parser** (libfmod-gen/src/parsers/): Uses pest grammar to parse FMOD C headers
- Extracts structures, functions, enums, callbacks, constants
- Parses documentation from HTML files for parameter modifiers

2. **Patching** (libfmod-gen/src/patching/): Applies manual corrections to parsed data
- Fixes FFI type mappings
- Handles special cases and FMOD-specific patterns

3. **Generator** (libfmod-gen/src/generators/): Creates Rust code from parsed API
- `ffi.rs`: Raw FFI bindings
- `lib.rs`: Safe Rust wrappers
- `flags.rs`: Bitflags for FMOD flags
- `errors.rs`: Error type definitions

### Key Components

**libfmod-gen/src/main.rs**: Entry point that orchestrates the generation process
- Reads FMOD headers from SDK
- Invokes parsers for each header file
- Patches the combined API model
- Generates Rust files

**libfmod/build.rs**: Build script that links appropriate FMOD libraries based on platform and features

## Important Implementation Details

- The library uses dynamic linking only (FMOD doesn't support static linking)
- String ownership is managed by moving String fields to C when passing structures
- The generator automatically runs `cargo fmt` after generating code
- Test files require FMOD development libraries to be installed as per README

## FMOD 2.03.09 Migration (Current Focus)

### Critical Breaking Changes
- **No ABI compatibility** between FMOD 2.02 and 2.03
- `System::getVersion` signature changed (adds buildnumber parameter)
- `FMOD_ADVANCEDSETTINGS.commandQueueSize` field removed
- `FMOD_STUDIO_ADVANCEDSETTINGS.encryptionkey` field added
- `FMOD_OUTPUT_DESCRIPTION.polling` renamed to `method`

### Migration Phases (see docs/fmod-update-plan.md)
1. **Setup**: Download and verify FMOD 2.03.09 SDK
2. **Generator Updates**: Fix breaking changes in libfmod-gen
3. **Core libfmod**: Update system, studio, and event APIs
4. **Test Harness**: Interactive testing tool
5. **bevy_fmod**: Minimal Bevy plugin implementation
6. **Validation**: Complete test suite

### Test-Driven Approach
Each migration step has specific tests to verify correctness before proceeding. Run tests after any changes:
```bash
# After libfmod-gen changes
cd libfmod-gen && cargo test

# After libfmod changes
cd libfmod && cargo test -- --test-threads=1

# Interactive testing
cargo run --example test_harness
```

## Quick Reference

### Common Issues
- **Dangling pointer warnings**: Temporary Vec issues in FFI code (needs fixing)
- **Missing FMOD libraries**: Follow README installation instructions
- **Test failures**: Ensure FMOD libraries are in LD_LIBRARY_PATH

### File Locations
- Generated FFI: `libfmod/src/ffi.rs`
- Safe wrappers: `libfmod/src/lib.rs`
- Parser grammar: `libfmod-gen/src/parsers/*.rs`
- Patching rules: `libfmod-gen/src/patching/`
- Migration docs: `docs/fmod-*.md`
120 changes: 120 additions & 0 deletions RUN_FMOD_2.03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# How to Run FMOD 2.03.09 Examples

## Quick Start (Copy & Paste)

From the `libfmod` directory, run:

```bash
# Set library path and run
export LD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib/x86_64:../libfmod-gen/fmod/20309/api/studio/lib/x86_64:$LD_LIBRARY_PATH"
./target/debug/examples/play_sound /usr/share/sounds/freedesktop/stereo/bell.oga
```

## The Problem

The error `libfmod.so.14: cannot open shared object file` happens because Linux can't find the FMOD 2.03.09 libraries. They're in `libfmod-gen/fmod/20309/` but the system doesn't know that.

## Solution 1: Set LD_LIBRARY_PATH (Temporary)

Every time you open a new terminal, run:

```bash
cd ~/devenv/gamedev/dg/src/libfmod/libfmod
export LD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib/x86_64:../libfmod-gen/fmod/20309/api/studio/lib/x86_64:$LD_LIBRARY_PATH"
```

Then you can run examples:
```bash
./target/debug/examples/play_sound /usr/share/sounds/freedesktop/stereo/bell.oga
./target/debug/examples/verify_203
```

## Solution 2: Use the Run Script (Easier!)

Use the provided script that sets everything up:

```bash
cd ~/devenv/gamedev/dg/src/libfmod/libfmod
./run_fmod.sh play_sound /usr/share/sounds/freedesktop/stereo/bell.oga
./run_fmod.sh verify_203
```

## Solution 3: Install Libraries (Permanent)

To avoid setting paths every time:

```bash
# Copy to user library directory (no sudo needed)
mkdir -p ~/lib
cp ../libfmod-gen/fmod/20309/api/core/lib/x86_64/*.so* ~/lib/
cp ../libfmod-gen/fmod/20309/api/studio/lib/x86_64/*.so* ~/lib/

# Add to .bashrc or .zshrc
echo 'export LD_LIBRARY_PATH="$HOME/lib:$LD_LIBRARY_PATH"' >> ~/.bashrc
source ~/.bashrc
```

## Building Examples

When building, you need to tell Rust where the libraries are:

```bash
cd ~/devenv/gamedev/dg/src/libfmod/libfmod
RUSTFLAGS="-L $(pwd)/../libfmod-gen/fmod/20309/api/core/lib/x86_64 -L $(pwd)/../libfmod-gen/fmod/20309/api/studio/lib/x86_64" cargo build --example play_sound
```

## Available Examples

1. **play_sound** - Play any audio file
```bash
./run_fmod.sh play_sound ~/Music/song.mp3
```

2. **verify_203** - Quick version check
```bash
./run_fmod.sh verify_203
```

3. **quick_test** - Comprehensive test
```bash
./run_fmod.sh quick_test
```

## Common Audio Files to Test

```bash
# System sounds (usually available)
/usr/share/sounds/freedesktop/stereo/bell.oga
/usr/share/sounds/freedesktop/stereo/complete.oga
/usr/share/sounds/freedesktop/stereo/message.oga

# Your own files
~/Music/*.mp3
~/Music/*.wav
~/Downloads/*.ogg
```

## Troubleshooting

If you still get library errors:

1. **Check libraries exist:**
```bash
ls ../libfmod-gen/fmod/20309/api/core/lib/x86_64/
```
Should show: libfmod.so, libfmod.so.14, libfmod.so.14.9

2. **Check current LD_LIBRARY_PATH:**
```bash
echo $LD_LIBRARY_PATH
```

3. **Check what libraries the program needs:**
```bash
ldd ./target/debug/examples/play_sound
```

4. **Full path approach:**
```bash
LD_LIBRARY_PATH=/full/path/to/fmod/libs:$LD_LIBRARY_PATH ./target/debug/examples/play_sound
```
107 changes: 107 additions & 0 deletions docs/FMOD_SETUP_MANUAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# FMOD Setup Manual for libfmod

Quick guide for setting up FMOD libraries to test libfmod on Linux and macOS.

## Step 1: Download FMOD SDK

1. Go to https://www.fmod.com/download
2. Create an account and sign in
3. Download FMOD Engine 2.03.09 for your platform:
- Linux: `fmodstudioapi20309linux.tar.gz`
- macOS: `fmodstudioapi20309mac-installer.dmg`

## Step 2: Extract/Install FMOD

### Linux

```bash
cd libfmod/libfmod-gen
mkdir -p fmod/20309
tar -xzf ~/Downloads/fmodstudioapi20309linux.tar.gz -C fmod/20309 --strip-components=1
```

### macOS

```bash
# Mount the DMG and extract the SDK
hdiutil attach ~/Downloads/fmodstudioapi20309mac-installer.dmg
cd libfmod/libfmod-gen
mkdir -p fmod/20309

# Copy the SDK files (adjust path if needed)
cp -r /Volumes/FMOD\ Programmers\ API/FMOD\ Programmers\ API/* fmod/20309/

# Unmount
hdiutil detach /Volumes/FMOD\ Programmers\ API/
```

## Step 3: Run Examples

### Linux

```bash
cd libfmod/libfmod

# Test FMOD version
./run_fmod.sh verify_203

# Play a sound
./run_fmod.sh play_sound /usr/share/sounds/freedesktop/stereo/bell.oga

# Test Studio features
./run_fmod.sh studio_banks_test
```

### macOS

```bash
cd libfmod/libfmod

# Build with library paths
RUSTFLAGS="-L ../libfmod-gen/fmod/20309/api/core/lib -L ../libfmod-gen/fmod/20309/api/studio/lib" \
cargo build --example verify_203

# Run with library path
DYLD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib:../libfmod-gen/fmod/20309/api/studio/lib" \
./target/debug/examples/verify_203

# Play a sound (use macOS system sound)
DYLD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib:../libfmod-gen/fmod/20309/api/studio/lib" \
./target/debug/examples/play_sound /System/Library/Sounds/Glass.aiff
```

## Directory Structure After Setup

```
libfmod-gen/fmod/20309/
├── api/
│ ├── core/
│ │ ├── inc/ # Headers
│ │ └── lib/ # Libraries
│ │ ├── x86_64/ # Linux
│ │ └── *.dylib # macOS
│ └── studio/
│ └── examples/
│ └── media/ # Sample banks
└── doc/
```

## Troubleshooting

### Linux: "libraries not found"
```bash
export LD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib/x86_64:../libfmod-gen/fmod/20309/api/studio/lib/x86_64:$LD_LIBRARY_PATH"
```

### macOS: "dylib not found"
```bash
export DYLD_LIBRARY_PATH="../libfmod-gen/fmod/20309/api/core/lib:../libfmod-gen/fmod/20309/api/studio/lib:$DYLD_LIBRARY_PATH"
```

### macOS: Security warnings
If macOS blocks the libraries:
```bash
# Remove quarantine attribute
xattr -d com.apple.quarantine libfmod-gen/fmod/20309/api/core/lib/*.dylib
xattr -d com.apple.quarantine libfmod-gen/fmod/20309/api/studio/lib/*.dylib
```
Loading