Cleanup dynamic loading in the PortAudio backend
This commit is contained in:
parent
ccf62fc525
commit
6b8209fdc9
157
Alc/portaudio.c
157
Alc/portaudio.c
@ -26,13 +26,15 @@
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <portaudio.h>
|
||||
|
||||
|
||||
static const ALCchar pa_device[] = "PortAudio Default";
|
||||
|
||||
|
||||
static void *pa_handle;
|
||||
#ifdef HAVE_DYNLOAD
|
||||
#define MAKE_FUNC(x) static typeof(x) * p##x
|
||||
MAKE_FUNC(Pa_Initialize);
|
||||
MAKE_FUNC(Pa_Terminate);
|
||||
@ -45,9 +47,15 @@ MAKE_FUNC(Pa_GetDefaultOutputDevice);
|
||||
MAKE_FUNC(Pa_GetStreamInfo);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
|
||||
static const ALCchar pa_device[] = "PortAudio Default";
|
||||
|
||||
#define Pa_Initialize pPa_Initialize
|
||||
#define Pa_Terminate pPa_Terminate
|
||||
#define Pa_GetErrorText pPa_GetErrorText
|
||||
#define Pa_StartStream pPa_StartStream
|
||||
#define Pa_StopStream pPa_StopStream
|
||||
#define Pa_OpenStream pPa_OpenStream
|
||||
#define Pa_CloseStream pPa_CloseStream
|
||||
#define Pa_GetDefaultOutputDevice pPa_GetDefaultOutputDevice
|
||||
#define Pa_GetStreamInfo pPa_GetStreamInfo
|
||||
|
||||
void *pa_load(void)
|
||||
{
|
||||
@ -56,73 +64,62 @@ void *pa_load(void)
|
||||
PaError err;
|
||||
|
||||
#ifdef _WIN32
|
||||
pa_handle = LoadLibrary("portaudio.dll");
|
||||
#define LOAD_FUNC(x) do { \
|
||||
p##x = (typeof(p##x))GetProcAddress(pa_handle, #x); \
|
||||
if(!(p##x)) { \
|
||||
AL_PRINT("Could not load %s from portaudio.dll\n", #x); \
|
||||
FreeLibrary(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
|
||||
const char *str;
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# define PALIB "portaudio.dll"
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
# define PALIB "libportaudio.2.dylib"
|
||||
#else
|
||||
# define PALIB "libportaudio.so.2"
|
||||
#endif
|
||||
pa_handle = dlopen(PALIB, RTLD_NOW);
|
||||
dlerror();
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = (typeof(f)*)dlsym(pa_handle, #f); \
|
||||
if((str=dlerror()) != NULL) \
|
||||
{ \
|
||||
dlclose(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
AL_PRINT("Could not load %s from "PALIB": %s\n", #f, str); \
|
||||
return NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
pa_handle = (void*)0xDEADBEEF;
|
||||
#define LOAD_FUNC(f) p##f = f
|
||||
#endif
|
||||
|
||||
pa_handle = LoadLib(PALIB);
|
||||
if(!pa_handle)
|
||||
return NULL;
|
||||
|
||||
LOAD_FUNC(Pa_Initialize);
|
||||
LOAD_FUNC(Pa_Terminate);
|
||||
LOAD_FUNC(Pa_GetErrorText);
|
||||
LOAD_FUNC(Pa_StartStream);
|
||||
LOAD_FUNC(Pa_StopStream);
|
||||
LOAD_FUNC(Pa_OpenStream);
|
||||
LOAD_FUNC(Pa_CloseStream);
|
||||
LOAD_FUNC(Pa_GetDefaultOutputDevice);
|
||||
LOAD_FUNC(Pa_GetStreamInfo);
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = GetSymbol(pa_handle, #f); \
|
||||
if(p##f == NULL) \
|
||||
{ \
|
||||
CloseLib(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
return NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
LOAD_FUNC(Pa_Initialize);
|
||||
LOAD_FUNC(Pa_Terminate);
|
||||
LOAD_FUNC(Pa_GetErrorText);
|
||||
LOAD_FUNC(Pa_StartStream);
|
||||
LOAD_FUNC(Pa_StopStream);
|
||||
LOAD_FUNC(Pa_OpenStream);
|
||||
LOAD_FUNC(Pa_CloseStream);
|
||||
LOAD_FUNC(Pa_GetDefaultOutputDevice);
|
||||
LOAD_FUNC(Pa_GetStreamInfo);
|
||||
#undef LOAD_FUNC
|
||||
|
||||
if((err=pPa_Initialize()) != paNoError)
|
||||
if((err=Pa_Initialize()) != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_Initialize() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(pa_handle);
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
dlclose(pa_handle);
|
||||
#endif
|
||||
AL_PRINT("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
CloseLib(pa_handle);
|
||||
pa_handle = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return pa_handle;
|
||||
}
|
||||
#else
|
||||
void *pa_load(void)
|
||||
{
|
||||
if(!pa_handle)
|
||||
{
|
||||
pa_handle = (void*)0xDEADBEEF;
|
||||
if((err=Pa_Initialize()) != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
pa_handle = NULL;
|
||||
}
|
||||
}
|
||||
return pa_handle;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -185,7 +182,7 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
|
||||
outParams.device = GetConfigValueInt("port", "device", -1);
|
||||
if(outParams.device < 0)
|
||||
outParams.device = pPa_GetDefaultOutputDevice();
|
||||
outParams.device = Pa_GetDefaultOutputDevice();
|
||||
outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
|
||||
(float)device->Frequency;
|
||||
outParams.hostApiSpecificStreamInfo = NULL;
|
||||
@ -212,16 +209,16 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
|
||||
SetDefaultChannelOrder(device);
|
||||
|
||||
err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
|
||||
err = Pa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
|
||||
device->UpdateSize, paNoFlag, pa_callback, device);
|
||||
if(err != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
device->ExtraData = NULL;
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
streamInfo = pPa_GetStreamInfo(data->stream);
|
||||
streamInfo = Pa_GetStreamInfo(data->stream);
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->Frequency = streamInfo->sampleRate;
|
||||
@ -234,9 +231,9 @@ static void pa_close_playback(ALCdevice *device)
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_CloseStream(data->stream);
|
||||
err = Pa_CloseStream(data->stream);
|
||||
if(err != paNoError)
|
||||
AL_PRINT("Error closing stream: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Error closing stream: %s\n", Pa_GetErrorText(err));
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
@ -248,7 +245,7 @@ static ALCboolean pa_reset_playback(ALCdevice *device)
|
||||
const PaStreamInfo *streamInfo;
|
||||
PaError err;
|
||||
|
||||
streamInfo = pPa_GetStreamInfo(data->stream);
|
||||
streamInfo = Pa_GetStreamInfo(data->stream);
|
||||
if(device->Frequency != streamInfo->sampleRate)
|
||||
{
|
||||
if((device->Flags&DEVICE_FREQUENCY_REQUEST))
|
||||
@ -258,10 +255,10 @@ static ALCboolean pa_reset_playback(ALCdevice *device)
|
||||
}
|
||||
device->UpdateSize = data->update_size;
|
||||
|
||||
err = pPa_StartStream(data->stream);
|
||||
err = Pa_StartStream(data->stream);
|
||||
if(err != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_StartStream() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@ -273,9 +270,9 @@ static void pa_stop_playback(ALCdevice *device)
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_StopStream(data->stream);
|
||||
err = Pa_StopStream(data->stream);
|
||||
if(err != paNoError)
|
||||
AL_PRINT("Error stopping stream: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Error stopping stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
|
||||
@ -311,7 +308,7 @@ static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
|
||||
inParams.device = GetConfigValueInt("port", "capture", -1);
|
||||
if(inParams.device < 0)
|
||||
inParams.device = pPa_GetDefaultOutputDevice();
|
||||
inParams.device = Pa_GetDefaultOutputDevice();
|
||||
inParams.suggestedLatency = 0.0f;
|
||||
inParams.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
@ -335,11 +332,11 @@ static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
}
|
||||
inParams.channelCount = ChannelsFromDevFmt(device->FmtChans);
|
||||
|
||||
err = pPa_OpenStream(&data->stream, &inParams, NULL, device->Frequency,
|
||||
err = Pa_OpenStream(&data->stream, &inParams, NULL, device->Frequency,
|
||||
paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device);
|
||||
if(err != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -359,9 +356,9 @@ static void pa_close_capture(ALCdevice *device)
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_CloseStream(data->stream);
|
||||
err = Pa_CloseStream(data->stream);
|
||||
if(err != paNoError)
|
||||
AL_PRINT("Error closing stream: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Error closing stream: %s\n", Pa_GetErrorText(err));
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
@ -372,9 +369,9 @@ static void pa_start_capture(ALCdevice *device)
|
||||
pa_data *data = device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_StartStream(data->stream);
|
||||
err = Pa_StartStream(data->stream);
|
||||
if(err != paNoError)
|
||||
AL_PRINT("Error starting stream: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Error starting stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
static void pa_stop_capture(ALCdevice *device)
|
||||
@ -382,9 +379,9 @@ static void pa_stop_capture(ALCdevice *device)
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_StopStream(data->stream);
|
||||
err = Pa_StopStream(data->stream);
|
||||
if(err != paNoError)
|
||||
AL_PRINT("Error stopping stream: %s\n", pPa_GetErrorText(err));
|
||||
AL_PRINT("Error stopping stream: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
static void pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
|
||||
@ -425,11 +422,9 @@ void alc_pa_deinit(void)
|
||||
{
|
||||
if(pa_handle)
|
||||
{
|
||||
pPa_Terminate();
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(pa_handle);
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
dlclose(pa_handle);
|
||||
Pa_Terminate();
|
||||
#ifdef HAVE_DYNLOAD
|
||||
CloseLib(pa_handle);
|
||||
#endif
|
||||
pa_handle = NULL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user