Packages

Erlang audio bindings to portaudio

Current section

Files

Jump to
erlaudio c_src erlaudio_drv.h
Raw

c_src/erlaudio_drv.h

#include "inttypes.h"
#include "stdint.h"
struct int_to_str {
PaSampleFormat num;
const char *str;
};
struct sflags_to_str {
PaStreamFlags num;
const char *str;
};
struct api_to_str {
PaHostApiTypeId num;
const char *str;
};
struct err_to_str {
PaError num;
const char *str;
};
struct erlaudio_ringbuf
{
unsigned char *data;
size_t length;
size_t head;
size_t tail;
};
struct erlaudio_stream_handle
{
struct erlaudio_thread_mgr* mgr;
int started;
int should_stop;
ErlNifTid thread;
// Stream related
PaStream* pa;
PaStreamParameters* input;
PaStreamParameters* output;
int flags;
double sample_rate;
unsigned long frames_per_buffer;
// Erlang-land related
ErlNifPid* owner_pid;
ErlNifPid* reader_pid;
// Buffers and pre-calc values
unsigned short input_frame_size;
unsigned short input_sample_size;
struct erlaudio_ringbuf *output_buf;
uint8_t total_samples;
unsigned short output_frame_size;
unsigned short output_sample_size;
};
static ERL_NIF_TERM erlaudio_get_pa_version (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_default_hostapi_index (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_device_index_from_hostapi (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_hostapi_count (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_hostapi_info (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_hostapi_index_from_type (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_default_input_device_index (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_default_output_device_index (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_device (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_get_device_count (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_format_supported (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_open (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_start (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_owner (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_reader (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_stop (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_close (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_abort (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_write (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_info (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_is_stopped (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_is_active (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_write_available (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM erlaudio_stream_writebuffer_size (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
#define MIN(a,b) ((a) < (b) ? (a) : (b))
static ErlNifResourceType* ERLAUDIO_STREAM_RESOURCE = NULL;
static ErlNifFunc nif_funcs[] =
{
{"get_pa_version", 0, erlaudio_get_pa_version},
// Native Host API stuff
{"get_default_hostapi_index", 0, erlaudio_get_default_hostapi_index},
{"get_device_index_from_hostapi", 2, erlaudio_get_device_index_from_hostapi},
{"get_hostapi_count", 0, erlaudio_get_hostapi_count},
{"get_hostapi_info", 1, erlaudio_get_hostapi_info},
{"get_hostapi_index_from_type", 1, erlaudio_get_hostapi_index_from_type},
// Devices
{"get_default_input_device_index", 0, erlaudio_get_default_input_device_index},
{"get_default_output_device_index", 0, erlaudio_get_default_output_device_index},
{"get_device", 1, erlaudio_get_device},
{"get_device_count", 0, erlaudio_get_device_count},
// Stream creation
{"stream_format_supported", 3, erlaudio_stream_format_supported},
{"stream_open", 5, erlaudio_stream_open},
// Stream management
// TODO: CHECK OWNERSHIP FOR THE FOLLOWING FUNCTIONS:
{"stream_start", 1, erlaudio_stream_start},
{"stream_owner", 1, erlaudio_stream_owner},
{"stream_owner", 2, erlaudio_stream_owner},
{"stream_reader", 1, erlaudio_stream_reader},
{"stream_reader", 2, erlaudio_stream_reader},
{"stream_close", 1, erlaudio_stream_close},
{"stream_stop", 1, erlaudio_stream_stop},
{"stream_abort", 1, erlaudio_stream_abort},
{"stream_write", 2, erlaudio_stream_write},
// READ ONLY BITS, NO OWNERSHIP CHECK NEEDED
{"stream_info", 1, erlaudio_stream_info},
{"stream_is_stopped", 1, erlaudio_stream_is_stopped},
{"stream_is_active", 1, erlaudio_stream_is_active},
{"stream_write_available", 1, erlaudio_stream_write_available},
{"stream_writebuffer_size", 1, erlaudio_stream_writebuffer_size}
};
static struct err_to_str pa_errors[] = {
{ paNotInitialized, "not_initialized" },
{ paNotInitialized, "not_initialized" },
{ paUnanticipatedHostError, "unanticipated_host_error" },
{ paInvalidChannelCount, "invalid_number_of_channels" },
{ paInvalidSampleRate, "invalid_sample_rate" },
{ paInvalidDevice, "invalid_device" },
{ paInvalidFlag, "invalid_flag" },
{ paSampleFormatNotSupported, "sample_format_unsupported" },
{ paBadIODeviceCombination, "bad_device_combo" },
{ paInsufficientMemory, "insufficient_memory" },
{ paBufferTooBig, "buffer_too_big" },
{ paBufferTooSmall, "buffer_too_small" },
{ paNullCallback, "nocallback" },
{ paBadStreamPtr, "badcallback" },
{ paTimedOut, "timeout" },
{ paInternalError, "internal_error" },
{ paDeviceUnavailable, "device_unavailable" },
{ paIncompatibleHostApiSpecificStreamInfo, "incompatible_host_stream_info" },
{ paStreamIsStopped, "stream_stopped" },
{ paStreamIsNotStopped, "stream_not_stopped" },
{ paInputOverflowed, "input_overflowed" },
{ paOutputUnderflowed, "output_underflowed" },
{ paHostApiNotFound, "no_hostapi" },
{ paInvalidHostApi, "invalid_hostapi" },
{ paCanNotReadFromACallbackStream, "noread_callback" },
{ paCanNotWriteToACallbackStream, "nowrite_callback" },
{ paCanNotReadFromAnOutputOnlyStream, "output_only" },
{ paCanNotWriteToAnInputOnlyStream, "input_only" },
{ paIncompatibleStreamHostApi, "incompatible_hostapi" },
{ paBadBufferPtr, "badbuffer" },
{ 0, 0 }
};
static struct api_to_str pa_drivers[] = {
{ paInDevelopment, "indevelopment" },
{ paDirectSound, "directsound" },
{ paMME, "mme" },
{ paASIO, "asio" },
{ paSoundManager, "soundmanager" },
{ paCoreAudio, "coreaudio" },
{ paOSS, "oss" },
{ paALSA, "alsa" },
{ paAL, "al" },
{ paBeOS, "beos" },
{ paWDMKS, "wdmks" },
{ paJACK, "jack" },
{ paWASAPI, "wasapi" },
{ paAudioScienceHPI, "audiosciencehpi" },
{ 0, 0 }
};
static struct int_to_str pa_types[] = {
{ paFloat32, "float32" },
{ paInt32, "int32" },
{ paInt24, "int24" },
{ paInt16, "int16" },
{ paInt8, "int8" },
{ paUInt8, "uint8" },
{ 0, 0 }
};
static struct sflags_to_str pa_flags[] = {
{ paClipOff, "noclip" },
{ paDitherOff, "nodither" },
{ paNeverDropInput, "nodropinput" },
{ paNoFlag, 0 }
};