mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-22 18:25:35 +00:00
docs
This commit is contained in:
parent
a37825d01a
commit
3d2ca2a610
177
README.md
177
README.md
|
@ -10,34 +10,148 @@ exposed.
|
|||
|
||||
**This library is a work-in-progress.**
|
||||
|
||||
## Alternatives
|
||||
## Features
|
||||
|
||||
* [PortAudio](http://www.portaudio.com/)
|
||||
- Does not support [PulseAudio](http://www.freedesktop.org/wiki/Software/PulseAudio/).
|
||||
- Logs messages to stdio and you can't turn that off.
|
||||
- Does not support channel layouts / channel maps.
|
||||
- Does not support emitting an event when available devices change.
|
||||
- Does not let you connect to multiple backends at once.
|
||||
- Not written by me.
|
||||
* [rtaudio](https://www.music.mcgill.ca/~gary/rtaudio/)
|
||||
- It is not a C library.
|
||||
- It uses [exceptions](http://stackoverflow.com/questions/1736146/why-is-exception-handling-bad).
|
||||
- It does not support channel layouts / channel maps.
|
||||
- Does not support emitting an event when available devices change.
|
||||
- Does not let you connect to multiple backends at once.
|
||||
- Not written by me.
|
||||
* [SDL](https://www.libsdl.org/)
|
||||
- Comes with baggage: display, windowing, input handling, and lots more.
|
||||
- Not designed with real-time low latency audio in mind.
|
||||
- Listing audio devices is [broken](https://github.com/andrewrk/node-groove/issues/13).
|
||||
- Does not support recording devices.
|
||||
- Does not support channel layouts / channel maps.
|
||||
- Does not support emitting an event when available devices change.
|
||||
- Does not let you connect to multiple backends at once.
|
||||
- Not written by me.
|
||||
* Supports:
|
||||
- [PulseAudio](http://www.freedesktop.org/wiki/Software/PulseAudio/)
|
||||
- [ALSA](http://www.alsa-project.org/)
|
||||
- Dummy Backend (silence)
|
||||
- (planned) [JACK](http://jackaudio.org/)
|
||||
- (planned) [CoreAudio](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/CoreAudioOverview/Introduction/Introduction.html)
|
||||
- (planned) [WASAPI](https://msdn.microsoft.com/en-us/library/windows/desktop/dd371455%28v=vs.85%29.aspx)
|
||||
- (planned) [ASIO](http://www.asio4all.com/)
|
||||
* C library. Depends only on the respective backend API libraries and libc.
|
||||
Does *not* depend on libstdc++, and does *not* have exceptions, run-time type
|
||||
information, or [setjmp](http://latentcontent.net/2007/12/05/libpng-worst-api-ever/).
|
||||
* Does not write anything to stdio. I'm looking at you,
|
||||
[PortAudio](http://www.portaudio.com/).
|
||||
* Supports channel layouts (also known as channel maps), important for
|
||||
surround sound applications.
|
||||
* Ability to monitor devices and get an event when available devices change.
|
||||
* Ability to connect to multiple backends at once. For example you could have
|
||||
an ALSA device open and a JACK device open at the same time.
|
||||
* Meticulously checks all return codes and memory allocations and uses
|
||||
meaningful error codes.
|
||||
|
||||
## How It Works
|
||||
## Synopsis
|
||||
|
||||
Complete program to emit a sine wave over the default device using the best
|
||||
backend:
|
||||
|
||||
```c
|
||||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of libsoundio, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include <soundio/soundio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
__attribute__ ((cold))
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__ ((format (printf, 1, 2)))
|
||||
static void panic(const char *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
abort();
|
||||
}
|
||||
|
||||
static const float PI = 3.1415926535f;
|
||||
static float seconds_offset = 0.0f;
|
||||
static void write_callback(struct SoundIoOutStream *outstream, int requested_frame_count) {
|
||||
float float_sample_rate = outstream->sample_rate;
|
||||
float seconds_per_frame = 1.0f / float_sample_rate;
|
||||
int err;
|
||||
|
||||
int frame_count = requested_frame_count;
|
||||
for (;;) {
|
||||
struct SoundIoChannelArea *areas;
|
||||
if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count)))
|
||||
panic("%s", soundio_strerror(err));
|
||||
|
||||
if (!frame_count)
|
||||
break;
|
||||
|
||||
const struct SoundIoChannelLayout *layout = &outstream->layout;
|
||||
|
||||
float pitch = 440.0f;
|
||||
float radians_per_second = pitch * 2.0f * PI;
|
||||
for (int frame = 0; frame < frame_count; frame += 1) {
|
||||
float sample = sinf((seconds_offset + frame * seconds_per_frame) * radians_per_second);
|
||||
for (int channel = 0; channel < layout->channel_count; channel += 1) {
|
||||
float *ptr = (float*)(areas[channel].ptr + areas[channel].step * frame);
|
||||
*ptr = sample;
|
||||
}
|
||||
}
|
||||
seconds_offset += seconds_per_frame * frame_count;
|
||||
|
||||
if ((err = soundio_outstream_write(outstream, frame_count)))
|
||||
panic("%s", soundio_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
static void error_callback(struct SoundIoOutStream *device, int err) {
|
||||
if (err == SoundIoErrorUnderflow) {
|
||||
static int count = 0;
|
||||
fprintf(stderr, "underrun %d\n", count++);
|
||||
} else {
|
||||
panic("%s", soundio_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct SoundIo *soundio = soundio_create();
|
||||
if (!soundio)
|
||||
panic("out of memory");
|
||||
|
||||
int err;
|
||||
if ((err = soundio_connect(soundio)))
|
||||
panic("error connecting: %s", soundio_strerror(err));
|
||||
|
||||
int default_out_device_index = soundio_get_default_output_device_index(soundio);
|
||||
if (default_out_device_index < 0)
|
||||
panic("no output device found");
|
||||
|
||||
struct SoundIoDevice *device = soundio_get_output_device(soundio, default_out_device_index);
|
||||
if (!device)
|
||||
panic("out of memory");
|
||||
|
||||
fprintf(stderr, "Output device: %s: %s\n", device->name, device->description);
|
||||
|
||||
struct SoundIoOutStream *outstream = soundio_outstream_create(device);
|
||||
outstream->format = SoundIoFormatFloat32NE;
|
||||
outstream->write_callback = write_callback;
|
||||
outstream->error_callback = error_callback;
|
||||
|
||||
if ((err = soundio_outstream_open(outstream)))
|
||||
panic("unable to open device: %s", soundio_strerror(err));
|
||||
|
||||
if ((err = soundio_outstream_start(outstream)))
|
||||
panic("unable to start device: %s", soundio_strerror(err));
|
||||
|
||||
for (;;)
|
||||
soundio_wait_events(soundio);
|
||||
|
||||
soundio_outstream_destroy(outstream);
|
||||
soundio_device_unref(device);
|
||||
soundio_destroy(soundio);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### "Best Backend"
|
||||
|
||||
When you use `soundio_connect', it tries these backends in order.
|
||||
libsoundio tries these backends in order. If unable to connect to that backend,
|
||||
due to the backend not being installed, or the server not running, or the
|
||||
platform is wrong, the next backend is tried.
|
||||
|
@ -47,10 +161,15 @@ platform is wrong, the next backend is tried.
|
|||
0. ALSA (Linux)
|
||||
0. CoreAudio (OSX)
|
||||
0. ASIO (Windows)
|
||||
0. DirectSound (Windows)
|
||||
0. OSS (BSD)
|
||||
0. WASAPI (Windows)
|
||||
0. Dummy
|
||||
|
||||
If you don't like this order, you can use `soundio_connect_backend` to
|
||||
explicitly choose a backend to connect to. You can use `soundio_backend_count`
|
||||
and `soundio_get_backend` to get the list of available backends.
|
||||
|
||||
For complete API documentation, see `src/soundio.h`.
|
||||
|
||||
## Contributing
|
||||
|
||||
libsoundio is programmed in a tiny subset of C++11:
|
||||
|
@ -62,7 +181,7 @@ libsoundio is programmed in a tiny subset of C++11:
|
|||
* No references.
|
||||
* No linking against libstdc++.
|
||||
|
||||
Don't get tricked - this is a *C library*, not a C++ library. We just take
|
||||
Do not be fooled - this is a *C library*, not a C++ library. We just take
|
||||
advantage of a select few C++11 compiler features such as templates, and then
|
||||
link against libc.
|
||||
|
||||
|
@ -128,7 +247,7 @@ view `coverage/index.html` in a browser.
|
|||
0. pipe record to playback example working with dummy linux, osx, windows
|
||||
0. pipe record to playback example working with pulseaudio linux
|
||||
0. implement CoreAudio (OSX) backend, get examples working
|
||||
0. implement DirectSound (Windows) backend, get examples working
|
||||
0. implement WASAPI (Windows) backend, get examples working
|
||||
0. implement JACK backend, get examples working
|
||||
0. Avoid calling `panic` in PulseAudio.
|
||||
0. implement ASIO (Windows) backend, get examples working
|
||||
|
|
|
@ -390,7 +390,7 @@ int soundio_backend_count(struct SoundIo *soundio);
|
|||
enum SoundIoBackend soundio_get_backend(struct SoundIo *soundio, int index);
|
||||
|
||||
// when you call this, the on_devices_change and on_events_signal callbacks
|
||||
// might be called. This is the only time those functions will be called.
|
||||
// might be called. This is the only time those callbacks will be called.
|
||||
void soundio_flush_events(struct SoundIo *soundio);
|
||||
|
||||
// flushes events as they occur, blocks until you call soundio_wakeup
|
||||
|
@ -462,10 +462,10 @@ int soundio_get_output_device_count(struct SoundIo *soundio);
|
|||
struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index);
|
||||
struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index);
|
||||
|
||||
// returns the index of the default input device, or -1 on error
|
||||
// returns the index of the default input device
|
||||
int soundio_get_default_input_device_index(struct SoundIo *soundio);
|
||||
|
||||
// returns the index of the default output device, or -1 on error
|
||||
// returns the index of the default output device
|
||||
int soundio_get_default_output_device_index(struct SoundIo *soundio);
|
||||
|
||||
void soundio_device_ref(struct SoundIoDevice *device);
|
||||
|
|
Loading…
Reference in a new issue