Home

Awesome

ffaudio

ffaudio is a fast cross-platform interface for Audio Input/Output for C and C++.

It provides advanced features for complex apps like phiola audio player/recorder, or it can be used by tiny programs like wav player example.

Contents:

Features

Supports:

Note: JACK playback is not implemented.

How to use

Write your cross-platform code using ffaudio_interface interface.

List all available playback devices

	#include <ffaudio/audio.h>

	// get API
	const ffaudio_interface *audio = ffaudio_default_interface();

	// initialize audio subsystem
	ffaudio_init_conf initconf = {};
	int r = audio->init(&initconf);
	if (r < 0)
		exit(1);

	// enumerate devices one by one
	ffaudio_dev *d = audio->dev_alloc(FFAUDIO_DEV_PLAYBACK);
	for (;;) {
		int r = audio->dev_next(d);
		if (r > 0) {
			break;
		} else if (r < 0) {
			printf("error: %s\n", audio->dev_error(d));
			break;
		}

		printf("device: name: '%s'\n", audio->dev_info(d, FFAUDIO_DEV_NAME));
	}
	audio->dev_free(d);

	audio->uninit();

Record data from audio device

	#include <ffaudio/audio.h>

	// get API
	const ffaudio_interface *audio = ffaudio_default_interface();

	// initialize audio subsystem
	ffaudio_init_conf initconf = {};
	int r = audio->init(&initconf);
	if (r < 0)
		exit(1);

	// create audio buffer
	ffaudio_buf *buf = audio->alloc();

	// open audio buffer for recording
	ffaudio_conf bufconf = {};
	bufconf.format = FFAUDIO_F_INT16;
	bufconf.sample_rate = 44100;
	bufconf.channels = 2;
	r = audio->open(buf, &bufconf, FFAUDIO_CAPTURE);
	if (r == FFAUDIO_EFORMAT)
		r = audio->open(buf, &bufconf, FFAUDIO_CAPTURE); // open with the supported format
	if (r < 0)
		exit(1);

	// read data from audio buffer and write it to stderr
	for (;;) {
		const void *data;
		r = audio->read(buf, &data);
		if (r < 0)
			exit(1);

		write(2, data.ptr, data.len);
	}

	audio->free(buf);
	audio->uninit();

In order for ffaudio_default_interface() function to work you should define FFAUDIO_INTERFACE_DEFAULT_PTR with the API you want to use, either in code:

#define FFAUDIO_INTERFACE_DEFAULT_PTR  &ffalsa
#include <ffaudio/audio.h>

or in Makefile:

CFLAGS += -DFFAUDIO_INTERFACE_DEFAULT_PTR="&ffalsa"

But instead of calling ffaudio_default_interface() you can just use an API directly, e.g. ffalsa.

How to build

Include the necessary ffaudio C files into your project's build script, e.g.:

	./ffaudio-alsa.o: $(FFAUDIO_DIR)/ffaudio/alsa.c $(FFAUDIO_DIR)/ffaudio/audio.h
		gcc -c $(CFLAGS) $< -o $@

Use the neceessary linker flags for the audio API, described below.

Build information for each audio API

Configure your building script to compile particular C file and use appropriate link flags.

APIPackage DependencyCompileLinker Flags
AAudio-ffaudio/aaudio.c-laaudio
ALSAlibalsa-develffaudio/alsa.c-lasound
PulseAudiolibpulse-develffaudio/pulse.c-lpulse
JACKjack-audio-connection-kit-develffaudio/jack.c-ljack
WASAPI-ffaudio/wasapi.c-lole32
DirectSound-ffaudio/dsound.c-ldsound -ldxguid
CoreAudio-ffaudio/coreaudio.c-framework CoreFoundation -framework CoreAudio
OSS-ffaudio/oss.c-lm

How to test

git clone https://github.com/stsaz/ffbase
git clone https://github.com/stsaz/ffaudio
cd ffaudio/test
make -B FFAUDIO_API=alsa
./ffaudio-alsa list
./ffaudio-alsa record 2>file.raw
./ffaudio-alsa play <file.raw

make -B FFAUDIO_API=pulse
./ffaudio-pulse list
./ffaudio-pulse record 2>file.raw
./ffaudio-pulse play <file.raw

make -B FFAUDIO_API=jack
./ffaudio-jack list
./ffaudio-jack record 2>file.raw
# [not implemented] ./ffaudio-jack play <file.raw

Install Android SDK & NDK; then cross-build for Android:

make FFAUDIO_API=aaudio \
	SYS=android \
	ROOT_DIR=../.. \
	SDK_DIR=/home/USER/Android/Sdk \
	NDK_VER=YOUR_NDK_VERSION

Run the executable on Android:

./ffaudio-aaudio record 2>file.raw
./ffaudio-aaudio play <file.raw
make -B FFAUDIO_API=wasapi
.\ffaudio-wasapi.exe list
.\ffaudio-wasapi.exe record 2>file.raw
.\ffaudio-wasapi.exe play <file.raw

make -B FFAUDIO_API=dsound
.\ffaudio-dsound.exe list
.\ffaudio-dsound.exe record 2>file.raw
.\ffaudio-dsound.exe play <file.raw
make FFAUDIO_API=coreaudio
./ffaudio-coreaudio list
./ffaudio-coreaudio record 2>file.raw
./ffaudio-coreaudio play <file.raw
make FFAUDIO_API=oss
./ffaudio-oss list
./ffaudio-oss record 2>file.raw
./ffaudio-oss play <file.raw

There are more additional arguments that you can pass to these executable files.

License

ffaudio is in the public-domain.