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
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [Mac OS](#mac-os)
- [Building](#building)
- [Bugs](#bugs)
- [Example](#example)
- [License Information](#license-information)

----------
Expand Down Expand Up @@ -83,6 +84,62 @@ and install it using:
Report bugs to the [pcaudiolib issues](https://github.com/espeak-ng/pcaudiolib/issues)
page on GitHub.

## Example
```C
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <pcaudiolib/audio.h>

#define AUDIO_RATE 22050
#define PI 3.14159265358979323846

void main() {
//pcaudiolib uses return values to report errors
int error = 0; // 0 means no error
//create the audio device
struct audio_object* my_audio
= create_audio_device_object(NULL, "example program", "plays a sound");
error = audio_object_open(my_audio, AUDIO_OBJECT_FORMAT_S16LE, AUDIO_RATE, 1);
if (error != 0) {
printf("failed to open device because %s",\
audio_object_strerror(my_audio, error));
}

//synthasize a sound
uint16_t sample_sound[AUDIO_RATE];
for (size_t i = 0; i < AUDIO_RATE; i++) {
//time in seconds
double time = ((double) i) / (double) AUDIO_RATE;
//sin(t) is 1 hz sine wave
double t = time * (2*PI);
//we play a 440hz A and the octave above
double amplitude = sin(t * 440) + sin(t * 880);
sample_sound[i] = (int16_t) (((double) INT16_MAX) / 2.0 * amplitude);
}

error = audio_object_write(my_audio, sample_sound, sizeof(sample_sound));
if (error != 0) {
printf("failed to write to device because %s",
audio_object_strerror(my_audio, error));
}

//wait until the sound is done playing
error = audio_object_drain(my_audio);
if (error != 0) {
printf("failed to drain to device because %s",
audio_object_strerror(my_audio, error));
}

//now we clean up

audio_object_close(my_audio);
// my_audio could now be openned to a different bitrate and format if we wanted

audio_object_destroy(my_audio); //frees my_audio
}
```

## License Information

The Portable C Audio Library is released under the [GPL version 3](COPYING) or
Expand Down
100 changes: 100 additions & 0 deletions src/include/pcaudiolib/audio.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* Audio API.
*
* Copyright (C) 2016 Reece H. Dunn
*
* Documentation comments by Ribbon-otter in 2025
*
* This file is part of pcaudiolib.
*
Expand All @@ -18,6 +20,8 @@
* along with pcaudiolib. If not, see <http://www.gnu.org/licenses/>.
*/



#ifndef PCAUDIOLIB_AUDIO_H
#define PCAUDIOLIB_AUDIO_H

Expand All @@ -29,6 +33,12 @@ extern "C"
{
#endif

/** represent different binary formats for audio.

Not all formats are supported on all platforms.
AUDIO_OBJECT_FORMAT_S16LE appears widely supported though

*/
enum audio_object_format
{
AUDIO_OBJECT_FORMAT_S8,
Expand Down Expand Up @@ -80,35 +90,125 @@ enum audio_object_format
AUDIO_OBJECT_FORMAT_AC3,
};

/** an opaque type that represents one audio device */
struct audio_object;

/**
Configure and ready an audio device for playback

@param object A opaque pointer return by an earlier
create_audio_device_object call
@param format An value from the audio_object_format enum
As of 2025-09-13, espeak-ng uses
AUDIO_OBJECT_FORMAT_S16LE for everything.
@param rate the audio sample rate in samples per sec
As of 2025-09-13, espeak-ng uses 22050
by default.
@param channels the number of audio channels.
As of 2025-09-13, espeak-ng use 1 for
everything

@return returns non-zero on error
*/
int
audio_object_open(struct audio_object *object,
enum audio_object_format format,
uint32_t rate,
uint8_t channels);

/**
Inverse of audio_object_open; called before audio_object_destroy

@param object A opaque pointer return by an earlier
create_audio_device_object call
*/
void
audio_object_close(struct audio_object *object);

/**
Free resources associated with the audio object.
Inverse of create_audio_device_object

@param object A opaque pointer return by an earlier
create_audio_device_object call
*/
void
audio_object_destroy(struct audio_object *object);

/**
Send audio data to played on audio device

@param object A opaque pointer return by an earlier
create_audio_device_object call
audio_object_open should be called before
attempting to write
@param data Pointer to the start of the binary data
formatted as specified in audio_object_open
@param bytes The length of the data to be passed in bytes

Once this function returns, it is safe to free data
or write other data to it.

@return returns non-zero on error
*/
int
audio_object_write(struct audio_object *object,
const void *data,
size_t bytes);

/**
Block thread until the audio queued for the device has played.

Used, for example, to prevent exiting the program
before audio playback is complete.

@param object A opaque pointer return by an earlier
create_audio_device_object call

@return returns non-zero on error
*/
int
audio_object_drain(struct audio_object *object);

/**
Discard audio currently in queue to be played.

@param object A opaque pointer return by an earlier
create_audio_device_object call

@return returns non-zero on error
*/
int
audio_object_flush(struct audio_object *object);

/**
Fetches textual descriptions of error codes

@param object A opaque pointer return by an earlier
create_audio_device_object call
@param[in] error the error code to be described

@return pointer to a c-string containing a human-readable
error code.

*/
const char *
audio_object_strerror(struct audio_object *object,
int error);

/**
Get an interface to the available audio system for playback

@param[in] device the name of the audio device to use or
NULL to use the default device
@param[in] application_name human-readable name of your program to
pass to the audio system
@param[in] description human-readable description of your program
to pass to the audio system

@return an opaque pointer which represents the audio device.
You pass the pointer to the other audio library functions
*/
struct audio_object *
create_audio_device_object(const char *device,
const char *application_name,
Expand Down