30 #include <portaudio.h>
37 static void *pa_handle;
38 #define MAKE_FUNC(x) static typeof(x) * p##x
39 MAKE_FUNC(Pa_Initialize);
40 MAKE_FUNC(Pa_Terminate);
41 MAKE_FUNC(Pa_GetErrorText);
42 MAKE_FUNC(Pa_StartStream);
43 MAKE_FUNC(Pa_StopStream);
44 MAKE_FUNC(Pa_OpenStream);
45 MAKE_FUNC(Pa_CloseStream);
46 MAKE_FUNC(Pa_GetDefaultOutputDevice);
47 MAKE_FUNC(Pa_GetStreamInfo);
50 #define Pa_Initialize pPa_Initialize
51 #define Pa_Terminate pPa_Terminate
52 #define Pa_GetErrorText pPa_GetErrorText
53 #define Pa_StartStream pPa_StartStream
54 #define Pa_StopStream pPa_StopStream
55 #define Pa_OpenStream pPa_OpenStream
56 #define Pa_CloseStream pPa_CloseStream
57 #define Pa_GetDefaultOutputDevice pPa_GetDefaultOutputDevice
58 #define Pa_GetStreamInfo pPa_GetStreamInfo
69 # define PALIB "portaudio.dll"
70 #elif defined(__APPLE__) && defined(__MACH__)
71 # define PALIB "libportaudio.2.dylib"
72 #elif defined(__OpenBSD__)
73 # define PALIB "libportaudio.so"
75 # define PALIB "libportaudio.so.2"
78 pa_handle = LoadLib(PALIB);
82 #define LOAD_FUNC(f) do { \
83 p##f = GetSymbol(pa_handle, #f); \
86 CloseLib(pa_handle); \
102 if((err=Pa_Initialize()) != paNoError)
104 ERR(
"Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
111 if((err=Pa_Initialize()) != paNoError)
113 ERR(
"Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
123 PaStreamParameters
params;
130 static int pa_callback(
const void *inputBuffer,
void *outputBuffer,
131 unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
132 const PaStreamCallbackFlags statusFlags,
void *userData)
140 aluMixData(device, outputBuffer, framesPerBuffer);
145 unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
146 const PaStreamCallbackFlags statusFlags,
void *userData)
167 else if(strcmp(deviceName,
pa_device) != 0)
170 data = (pa_data*)
calloc(1,
sizeof(pa_data));
173 data->params.device = -1;
175 data->params.device < 0)
176 data->params.device = Pa_GetDefaultOutputDevice();
179 data->params.hostApiSpecificStreamInfo =
NULL;
186 data->params.sampleFormat = paInt8;
189 data->params.sampleFormat = paUInt8;
194 data->params.sampleFormat = paInt16;
199 data->params.sampleFormat = paInt32;
202 data->params.sampleFormat = paFloat32;
207 err = Pa_OpenStream(&data->stream,
NULL, &data->params, device->
Frequency,
211 if(data->params.sampleFormat == paFloat32)
213 data->params.sampleFormat = paInt16;
216 ERR(
"Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
232 err = Pa_CloseStream(data->stream);
234 ERR(
"Error closing stream: %s\n", Pa_GetErrorText(err));
243 const PaStreamInfo *streamInfo;
245 streamInfo = Pa_GetStreamInfo(data->stream);
246 device->
Frequency = streamInfo->sampleRate;
249 if(data->params.sampleFormat == paInt8)
251 else if(data->params.sampleFormat == paUInt8)
253 else if(data->params.sampleFormat == paInt16)
255 else if(data->params.sampleFormat == paInt32)
257 else if(data->params.sampleFormat == paFloat32)
261 ERR(
"Unexpected sample format: 0x%lx\n", data->params.sampleFormat);
265 if(data->params.channelCount == 2)
267 else if(data->params.channelCount == 1)
271 ERR(
"Unexpected channel count: %u\n", data->params.channelCount);
284 err = Pa_StartStream(data->stream);
287 ERR(
"Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err));
299 err = Pa_StopStream(data->stream);
301 ERR(
"Error stopping stream: %s\n", Pa_GetErrorText(err));
313 else if(strcmp(deviceName,
pa_device) != 0)
316 data = (pa_data*)
calloc(1,
sizeof(pa_data));
322 if(data->ring ==
NULL)
325 data->params.device = -1;
327 data->params.device < 0)
328 data->params.device = Pa_GetDefaultOutputDevice();
329 data->params.suggestedLatency = 0.0f;
330 data->params.hostApiSpecificStreamInfo =
NULL;
335 data->params.sampleFormat = paInt8;
338 data->params.sampleFormat = paUInt8;
341 data->params.sampleFormat = paInt16;
344 data->params.sampleFormat = paInt32;
347 data->params.sampleFormat = paFloat32;
356 err = Pa_OpenStream(&data->stream, &data->params,
NULL, device->
Frequency,
357 paFramesPerBufferUnspecified, paNoFlag,
pa_capture_cb, device);
360 ERR(
"Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
380 err = Pa_CloseStream(data->stream);
382 ERR(
"Error closing stream: %s\n", Pa_GetErrorText(err));
393 err = Pa_StartStream(data->stream);
395 ERR(
"Error starting stream: %s\n", Pa_GetErrorText(err));
403 err = Pa_StopStream(data->stream);
405 ERR(
"Error stopping stream: %s\n", Pa_GetErrorText(err));
static void pa_start_capture(ALCdevice *device)
static const ALCchar pa_device[]
static void pa_stop_capture(ALCdevice *device)
static int pa_capture_cb(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags, void *userData)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
char * strdup(const char *inStr)
int ConfigValueInt(const char *blockName, const char *keyName, int *ret)
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
static const BackendFuncs pa_funcs
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
ALsizei RingBufferSize(RingBuffer *ring)
void SetDefaultChannelOrder(ALCdevice *device)
void AppendCaptureDeviceList(const ALCchar *name)
static void pa_close_capture(ALCdevice *device)
static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
static void pa_stop_playback(ALCdevice *device)
struct RingBuffer RingBuffer
EGLContext EGLenum EGLClientBuffer buffer
ALCboolean alc_pa_init(BackendFuncs *func_list)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
static ALCenum pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
static ALCboolean pa_reset_playback(ALCdevice *device)
enum DevFmtChannels FmtChans
static ALCuint pa_available_samples(ALCdevice *device)
static void pa_close_playback(ALCdevice *device)
static ALCboolean pa_load(void)
void alc_pa_probe(enum DevProbe type)
void ALCdevice_LockDefault(ALCdevice *device)
static ALCboolean pa_start_playback(ALCdevice *device)
static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
#define ALC_INVALID_VALUE
#define ALC_OUT_OF_MEMORY
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
const ALCchar * DevFmtTypeString(enum DevFmtType type)
void DestroyRingBuffer(RingBuffer *ring)
void ALCdevice_UnlockDefault(ALCdevice *device)
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
void AppendAllDevicesList(const ALCchar *name)
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
static int pa_callback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags, void *userData)