Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ Release
/stub/res/x86-win32/fmod*.dll
/stub/lib/ios/libfmod*.a
/stub/lib/js-web/libfmod*.a
/.editor_settings
40 changes: 37 additions & 3 deletions CONTRIBUTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Alternatively, if you don't want to install Python on your system, you can run
it through Docker:

```
docker-compose -f bridge/docker-compose.generate_bindings.yml up
docker compose -f bridge/docker-compose.generate_bindings.yml up
```

The bridge library comes with compilation scripts for each platform:
Expand Down Expand Up @@ -57,7 +57,7 @@ You can build all of these in one go with Docker:

```bash
cd bridge
docker-compose up
docker compose up
```

Or use the respective Makefiles to build manually. Make sure to match
Expand All @@ -82,4 +82,38 @@ common prefix of the files you downloaded as the first argument:
```bash
# For example, if you downloaded FMOD 2.01.07:
./update_fmod.sh ~/Downloads/fmodstudioapi20107
```
```

## Testing HTML5/WASM pthread builds locally

WASM pthread builds require specific CORS headers to enable `SharedArrayBuffer`.
Regular `python3 -m http.server` will **not** work so please send required headers.

**Required headers:**
- `Cross-Origin-Opener-Policy: same-origin`
- `Cross-Origin-Embedder-Policy: require-corp`

So for python serving, you can add the request CORS handler like
```python3
class CORSRequestHandler(SimpleHTTPRequestHandler):
(...)
def end_headers(self):
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
```


**Build with both architectures** (loader needs both for fallback):

```bash
java -jar bob.jar build bundle --platform js-web \
--architectures wasm-web,wasm_pthread-web \
--bundle-format html5
(...)
```

Validate in the console

```javascript
console.log("Pthread:", Module.isWASMPthreadSupported); // Should be: true
```
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
![fmod](./docs/fmod_logo.png)
![](https://img.shields.io/badge/Defold-1.11.2+-green)
![](https://img.shields.io/badge/FMOD-2.03.09-green)
![](https://img.shields.io/badge/Emscripten-4.0.6+3.1.67-green)

# FMOD extension for Defold
![](./docs/defmod_banner.png)

# Defold FMOD Extension
> [FMOD] sound engine bindings for Defold

**Commercial usage of FMOD products may require a separate license directly with
Expand All @@ -15,9 +18,22 @@ least the words "FMOD" (OR "FMOD STUDIO" IF APPLICABLE) AND "FIRELIGHT TECHNOLOG

## Installation

Go to the [Releases page](https://github.com/dapetcu21/defold-fmod/releases),
Go to the [Releases page](https://github.com/defold/extension-fmod/releases),
copy a dependency URL, then add it to your dependencies in `game.project`.

### Running in the editor

The game will bundle fine, but in order for FMOD to be available when running
from the editor, an extra step is required.

Copy the `fmod/res` directory from this repo to a directory in your project
and add the path to that directory to your `game.project`:

```
[fmod]
lib_path = path/to/fmod/res
```

### Set the speaker mode

This step is [only required if you use Studio banks][set_software_format].
Expand Down Expand Up @@ -53,19 +69,6 @@ depends from game to game, but for this example to run, it needs a 512MB heap.
heap_size = 512
```

### Running in the editor

The game will bundle fine, but in order for FMOD to be available when running
from the editor, an extra step is required.

Copy the `fmod/res` directory from this repo to a directory in your project
and add the path to that directory to your `game.project`:

```
[fmod]
lib_path = path/to/fmod/res
```

## Usage

Structs and classes are exposed on the `fmod` and `fmod.studio` namespaces. All
Expand Down
14 changes: 8 additions & 6 deletions bridge/Makefile.android
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ HEADERS = \
JAVA_FILES = \
src/me/petcu/fmodbridge/BridgeHelper.java

ANDROID_NDK ?= $(HOME)/Tools/android-ndk-r17c
HOST_TAG ?= `uname | tr A-Z a-z`-x86_64

CC_ARM := $(ANDROID_NDK)/toolchains/llvm/prebuilt/$(HOST_TAG)/bin/clang -target armv7a-linux-androideabi14 --sysroot=$(ANDROID_NDK)/sysroot -I$(ANDROID_NDK)/sysroot/usr/include/arm-linux-androideabi
CC_ARM64 := $(ANDROID_NDK)/toolchains/llvm/prebuilt/$(HOST_TAG)/bin/clang -target aarch64-linux-androideabi21 --sysroot=$(ANDROID_NDK)/sysroot -I$(ANDROID_NDK)/sysroot/usr/include/aarch64-linux-android
AR := $(ANDROID_NDK)/toolchains/llvm/prebuilt/$(HOST_TAG)/bin/llvm-ar
ANDROID_NDK ?= /opt/android-ndk-r25b
HOST_TAG ?= linux-x86_64

# prebuilt compiler from the NDK toolchain
TOOLCHAIN_PREFIX := $(ANDROID_NDK)/toolchains/llvm/prebuilt/$(HOST_TAG)
CC_ARM := $(TOOLCHAIN_PREFIX)/bin/armv7a-linux-androideabi19-clang
CC_ARM64 := $(TOOLCHAIN_PREFIX)/bin/aarch64-linux-android21-clang
AR := $(TOOLCHAIN_PREFIX)/bin/llvm-ar

CFLAGS := -std=c11 -O3 -fvisibility=hidden -I./include -fpic -fomit-frame-pointer \
-fno-strict-aliasing -funwind-tables -ffunction-sections -fstack-protector \
Expand Down
22 changes: 17 additions & 5 deletions bridge/Makefile.emscripten
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
LIBPATH := ../fmod/lib/web/libfmodbridge.a
LIBPATH_PTHREAD := ../fmod/lib/wasm_pthread-web/libfmodbridge.a

SOURCES = \
src/fmod_init.c \
Expand All @@ -9,19 +10,30 @@ HEADERS = src/fmod_bridge.h
CC := emcc
AR := emar

CFLAGS := -O3 -fvisibility=hidden -I./include
CFLAGS := -O3 -fvisibility=hidden -I./include -s ALLOW_MEMORY_GROWTH=1 -s LEGACY_RUNTIME=1
CFLAGS_PTHREAD := -O3 -visibility=hidden -I./include -s ALLOW_MEMORY_GROWTH=1 -pthread

all: $(LIBPATH)
all: $(LIBPATH) $(LIBPATH_PTHREAD)

OBJECTS = $(patsubst src/%.c,build/js-%.bc,$(SOURCES))
# Regular build
OBJECTS = $(patsubst src/%.c,build/js-%.o,$(SOURCES))

build/js-%.bc: src/%.c $(HEADERS)
build/js-%.o: src/%.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@

$(LIBPATH): $(OBJECTS)
$(AR) rcs $@ $^

# Pthread build
OBJECTS_PTHREAD = $(patsubst src/%.c,build/js-pthread-%.o,$(SOURCES))

build/js-pthread-%.o: src/%.c $(HEADERS)
$(CC) $(CFLAGS_PTHREAD) -c $< -o $@

$(LIBPATH_PTHREAD): $(OBJECTS_PTHREAD)
$(AR) rcs $@ $^

clean:
rm -f $(LIBPATH) build/js-*.bc
rm -f $(LIBPATH) $(LIBPATH_PTHREAD) build/js-*.o build/js-pthread-*.o

.PHONY: all clean
2 changes: 1 addition & 1 deletion bridge/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ services:
build_android:
build: docker/build_android
volumes:
- "..:/repo"
- "..:/repo"
24 changes: 21 additions & 3 deletions bridge/docker/build_android/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
FROM lakoo/android-ndk:28-28.0.2-r17c
FROM ubuntu:22.04

RUN apt-get update && apt-get install make -y
ENV DEBIAN_FRONTEND=noninteractive

# basic tools
RUN apt-get update && apt-get install -y \
wget \
unzip \
openjdk-11-jdk \
make \
build-essential \
&& rm -rf /var/lib/apt/lists/*

# Android NDK r25b (same version as Defold's build server)
ENV ANDROID_NDK_HOME=/opt/android-ndk-r25b
RUN cd /opt && \
wget -q https://dl.google.com/android/repository/android-ndk-r25b-linux.zip && \
unzip -q android-ndk-r25b-linux.zip && \
rm android-ndk-r25b-linux.zip

ENV PATH="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${PATH}"

VOLUME [ "/repo" ]
WORKDIR /repo/bridge

ENTRYPOINT [ "make", "-f", "Makefile.android" ]
ENTRYPOINT [ "make", "-f", "Makefile.android" ]
4 changes: 2 additions & 2 deletions bridge/docker/build_linux/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM debian:8
FROM debian:11

RUN apt-get update && apt-get install build-essential -y

VOLUME [ "/repo" ]
WORKDIR /repo/bridge

ENTRYPOINT [ "make", "-f", "Makefile.linux" ]
ENTRYPOINT [ "make", "-f", "Makefile.linux" ]
4 changes: 2 additions & 2 deletions bridge/docker/build_web/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM emscripten/emsdk:1.39.17-upstream
FROM emscripten/emsdk:4.0.16

VOLUME [ "/repo" ]
WORKDIR /repo/bridge

ENTRYPOINT [ "make", "-f", "Makefile.emscripten" ]
ENTRYPOINT [ "make", "-f", "Makefile.emscripten" ]
8 changes: 5 additions & 3 deletions bridge/include/fmod.h
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* ======================================================================================== */
/* FMOD Core API - C header file. */
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2025. */
/* */
/* Use this header in conjunction with fmod_common.h (which contains all the constants / */
/* callbacks) to develop using the C interface */
/* */
/* For more detail visit: */
/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */
/* https://fmod.com/docs/2.03/api/core-api.html */
/* ======================================================================================== */

#ifndef _FMOD_H
Expand Down Expand Up @@ -98,7 +98,7 @@ FMOD_RESULT F_API FMOD_System_GetDefaultMixMatrix (FMOD_SYSTEM *system, FM
FMOD_RESULT F_API FMOD_System_GetSpeakerModeChannels (FMOD_SYSTEM *system, FMOD_SPEAKERMODE mode, int *channels);

/* System information functions. */
FMOD_RESULT F_API FMOD_System_GetVersion (FMOD_SYSTEM *system, unsigned int *version);
FMOD_RESULT F_API FMOD_System_GetVersion (FMOD_SYSTEM *system, unsigned int *version, unsigned int *buildnumber);
FMOD_RESULT F_API FMOD_System_GetOutputHandle (FMOD_SYSTEM *system, void **handle);
FMOD_RESULT F_API FMOD_System_GetChannelsPlaying (FMOD_SYSTEM *system, int *channels, int *realchannels);
FMOD_RESULT F_API FMOD_System_GetCPUUsage (FMOD_SYSTEM *system, FMOD_CPU_USAGE *usage);
Expand All @@ -109,6 +109,7 @@ FMOD_RESULT F_API FMOD_System_CreateSound (FMOD_SYSTEM *system, co
FMOD_RESULT F_API FMOD_System_CreateStream (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound);
FMOD_RESULT F_API FMOD_System_CreateDSP (FMOD_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description, FMOD_DSP **dsp);
FMOD_RESULT F_API FMOD_System_CreateDSPByType (FMOD_SYSTEM *system, FMOD_DSP_TYPE type, FMOD_DSP **dsp);
FMOD_RESULT F_API FMOD_System_CreateDSPConnection (FMOD_SYSTEM *system, FMOD_DSPCONNECTION_TYPE type, FMOD_DSPCONNECTION **connection);
FMOD_RESULT F_API FMOD_System_CreateChannelGroup (FMOD_SYSTEM *system, const char *name, FMOD_CHANNELGROUP **channelgroup);
FMOD_RESULT F_API FMOD_System_CreateSoundGroup (FMOD_SYSTEM *system, const char *name, FMOD_SOUNDGROUP **soundgroup);
FMOD_RESULT F_API FMOD_System_CreateReverb3D (FMOD_SYSTEM *system, FMOD_REVERB3D **reverb);
Expand Down Expand Up @@ -535,6 +536,7 @@ FMOD_RESULT F_API FMOD_DSP_SetChannelFormat (FMOD_DSP *dsp, FMOD_CHA
FMOD_RESULT F_API FMOD_DSP_GetChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode);
FMOD_RESULT F_API FMOD_DSP_GetOutputChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode);
FMOD_RESULT F_API FMOD_DSP_Reset (FMOD_DSP *dsp);
FMOD_RESULT F_API FMOD_DSP_SetCallback (FMOD_DSP *dsp, FMOD_DSP_CALLBACK callback);

/*
DSP parameter control.
Expand Down
8 changes: 5 additions & 3 deletions bridge/include/fmod.hpp
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* ======================================================================================== */
/* FMOD Core API - C++ header file. */
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2025. */
/* */
/* Use this header in conjunction with fmod_common.h (which contains all the constants / */
/* callbacks) to develop using the C++ language. */
/* */
/* For more detail visit: */
/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */
/* https://fmod.com/docs/2.03/api/core-api.html */
/* ======================================================================================== */
#ifndef _FMOD_HPP
#define _FMOD_HPP
Expand Down Expand Up @@ -120,7 +120,7 @@ namespace FMOD
FMOD_RESULT F_API getSpeakerModeChannels (FMOD_SPEAKERMODE mode, int *channels);

// System information functions.
FMOD_RESULT F_API getVersion (unsigned int *version);
FMOD_RESULT F_API getVersion (unsigned int *version, unsigned int *buildnumber = 0);
FMOD_RESULT F_API getOutputHandle (void **handle);
FMOD_RESULT F_API getChannelsPlaying (int *channels, int *realchannels = 0);
FMOD_RESULT F_API getCPUUsage (FMOD_CPU_USAGE *usage);
Expand All @@ -131,6 +131,7 @@ namespace FMOD
FMOD_RESULT F_API createStream (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound);
FMOD_RESULT F_API createDSP (const FMOD_DSP_DESCRIPTION *description, DSP **dsp);
FMOD_RESULT F_API createDSPByType (FMOD_DSP_TYPE type, DSP **dsp);
FMOD_RESULT F_API createDSPConnection (FMOD_DSPCONNECTION_TYPE type, DSPConnection **connection);
FMOD_RESULT F_API createChannelGroup (const char *name, ChannelGroup **channelgroup);
FMOD_RESULT F_API createSoundGroup (const char *name, SoundGroup **soundgroup);
FMOD_RESULT F_API createReverb3D (Reverb3D **reverb);
Expand Down Expand Up @@ -473,6 +474,7 @@ namespace FMOD
FMOD_RESULT F_API getChannelFormat (FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode);
FMOD_RESULT F_API getOutputChannelFormat (FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode);
FMOD_RESULT F_API reset ();
FMOD_RESULT F_API setCallback (FMOD_DSP_CALLBACK callback);

// DSP parameter control.
FMOD_RESULT F_API setParameterFloat (int index, float value);
Expand Down
Loading