mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-01 06:44:27 +08:00
Remove _THIS in src/audio/
This commit is contained in:
+9
-11
@@ -27,8 +27,6 @@
|
|||||||
#include "../thread/SDL_systhread.h"
|
#include "../thread/SDL_systhread.h"
|
||||||
#include "../SDL_utils_c.h"
|
#include "../SDL_utils_c.h"
|
||||||
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
static SDL_AudioDriver current_audio;
|
static SDL_AudioDriver current_audio;
|
||||||
static SDL_AudioDevice *open_devices[16];
|
static SDL_AudioDevice *open_devices[16];
|
||||||
|
|
||||||
@@ -137,37 +135,37 @@ static void SDL_AudioDetectDevices_Default(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioThreadInit_Default(_THIS)
|
static void SDL_AudioThreadInit_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioThreadDeinit_Default(_THIS)
|
static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioWaitDevice_Default(_THIS)
|
static void SDL_AudioWaitDevice_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioPlayDevice_Default(_THIS)
|
static void SDL_AudioPlayDevice_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS)
|
static Uint8 *SDL_AudioGetDeviceBuf_Default(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
|
static int SDL_AudioCaptureFromDevice_Default(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
return -1; /* just fail immediately. */
|
return -1; /* just fail immediately. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioFlushCapture_Default(_THIS)
|
static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioCloseDevice_Default(_THIS)
|
static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *_this)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +177,7 @@ static void SDL_AudioFreeDeviceHandle_Default(void *handle)
|
|||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SDL_AudioOpenDevice_Default(_THIS, const char *devname)
|
static int SDL_AudioOpenDevice_Default(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-13
@@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
/* The SDL audio driver */
|
/* The SDL audio driver */
|
||||||
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
/* Audio targets should call this as devices are added to the system (such as
|
/* Audio targets should call this as devices are added to the system (such as
|
||||||
a USB headset being plugged in), and should also be called for
|
a USB headset being plugged in), and should also be called for
|
||||||
@@ -63,17 +62,17 @@ extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
|
|||||||
typedef struct SDL_AudioDriverImpl
|
typedef struct SDL_AudioDriverImpl
|
||||||
{
|
{
|
||||||
void (*DetectDevices)(void);
|
void (*DetectDevices)(void);
|
||||||
int (*OpenDevice)(_THIS, const char *devname);
|
int (*OpenDevice)(SDL_AudioDevice *_this, const char *devname);
|
||||||
void (*ThreadInit)(_THIS); /* Called by audio thread at start */
|
void (*ThreadInit)(SDL_AudioDevice *_this); /* Called by audio thread at start */
|
||||||
void (*ThreadDeinit)(_THIS); /* Called by audio thread at end */
|
void (*ThreadDeinit)(SDL_AudioDevice *_this); /* Called by audio thread at end */
|
||||||
void (*WaitDevice)(_THIS);
|
void (*WaitDevice)(SDL_AudioDevice *_this);
|
||||||
void (*PlayDevice)(_THIS);
|
void (*PlayDevice)(SDL_AudioDevice *_this);
|
||||||
Uint8 *(*GetDeviceBuf)(_THIS);
|
Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *_this);
|
||||||
int (*CaptureFromDevice)(_THIS, void *buffer, int buflen);
|
int (*CaptureFromDevice)(SDL_AudioDevice *_this, void *buffer, int buflen);
|
||||||
void (*FlushCapture)(_THIS);
|
void (*FlushCapture)(SDL_AudioDevice *_this);
|
||||||
void (*CloseDevice)(_THIS);
|
void (*CloseDevice)(SDL_AudioDevice *_this);
|
||||||
void (*LockDevice)(_THIS);
|
void (*LockDevice)(SDL_AudioDevice *_this);
|
||||||
void (*UnlockDevice)(_THIS);
|
void (*UnlockDevice)(SDL_AudioDevice *_this);
|
||||||
void (*FreeDeviceHandle)(void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
|
void (*FreeDeviceHandle)(void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
|
||||||
void (*Deinitialize)(void);
|
void (*Deinitialize)(void);
|
||||||
int (*GetDefaultAudioInfo)(char **name, SDL_AudioSpec *spec, int iscapture);
|
int (*GetDefaultAudioInfo)(char **name, SDL_AudioSpec *spec, int iscapture);
|
||||||
@@ -165,7 +164,6 @@ struct SDL_AudioDevice
|
|||||||
|
|
||||||
void *handle;
|
void *handle;
|
||||||
};
|
};
|
||||||
#undef _THIS
|
|
||||||
|
|
||||||
typedef struct AudioBootStrap
|
typedef struct AudioBootStrap
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ void aaudio_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t
|
|||||||
|
|
||||||
#define LIB_AAUDIO_SO "libaaudio.so"
|
#define LIB_AAUDIO_SO "libaaudio.so"
|
||||||
|
|
||||||
static int aaudio_OpenDevice(_THIS, const char *devname)
|
static int aaudio_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *private;
|
struct SDL_PrivateAudioData *private;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
aaudio_result_t res;
|
aaudio_result_t res;
|
||||||
LOGI(__func__);
|
LOGI(__func__);
|
||||||
|
|
||||||
@@ -79,14 +79,14 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
private = this->hidden;
|
private = _this->hidden;
|
||||||
|
|
||||||
ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, this->spec.freq);
|
ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, _this->spec.freq);
|
||||||
ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, this->spec.channels);
|
ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, _this->spec.channels);
|
||||||
if(devname != NULL) {
|
if(devname != NULL) {
|
||||||
int aaudio_device_id = SDL_atoi(devname);
|
int aaudio_device_id = SDL_atoi(devname);
|
||||||
LOGI("Opening device id %d", aaudio_device_id);
|
LOGI("Opening device id %d", aaudio_device_id);
|
||||||
@@ -98,9 +98,9 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
aaudio_format_t format = AAUDIO_FORMAT_PCM_FLOAT;
|
aaudio_format_t format = AAUDIO_FORMAT_PCM_FLOAT;
|
||||||
if (this->spec.format == SDL_AUDIO_S16SYS) {
|
if (_this->spec.format == SDL_AUDIO_S16SYS) {
|
||||||
format = AAUDIO_FORMAT_PCM_I16;
|
format = AAUDIO_FORMAT_PCM_I16;
|
||||||
} else if (this->spec.format == SDL_AUDIO_S16SYS) {
|
} else if (_this->spec.format == SDL_AUDIO_S16SYS) {
|
||||||
format = AAUDIO_FORMAT_PCM_FLOAT;
|
format = AAUDIO_FORMAT_PCM_FLOAT;
|
||||||
}
|
}
|
||||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||||
@@ -109,8 +109,8 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||||||
ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private);
|
ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private);
|
||||||
|
|
||||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
_this->spec.freq, SDL_AUDIO_BITSIZE(_this->spec.format),
|
||||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
_this->spec.channels, (_this->spec.format & 0x1000) ? "BE" : "LE", _this->spec.samples);
|
||||||
|
|
||||||
res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream);
|
res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream);
|
||||||
if (res != AAUDIO_OK) {
|
if (res != AAUDIO_OK) {
|
||||||
@@ -118,34 +118,34 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->spec.freq = ctx.AAudioStream_getSampleRate(private->stream);
|
_this->spec.freq = ctx.AAudioStream_getSampleRate(private->stream);
|
||||||
this->spec.channels = ctx.AAudioStream_getChannelCount(private->stream);
|
_this->spec.channels = ctx.AAudioStream_getChannelCount(private->stream);
|
||||||
{
|
{
|
||||||
aaudio_format_t fmt = ctx.AAudioStream_getFormat(private->stream);
|
aaudio_format_t fmt = ctx.AAudioStream_getFormat(private->stream);
|
||||||
if (fmt == AAUDIO_FORMAT_PCM_I16) {
|
if (fmt == AAUDIO_FORMAT_PCM_I16) {
|
||||||
this->spec.format = SDL_AUDIO_S16SYS;
|
_this->spec.format = SDL_AUDIO_S16SYS;
|
||||||
} else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) {
|
} else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) {
|
||||||
this->spec.format = SDL_AUDIO_F32SYS;
|
_this->spec.format = SDL_AUDIO_F32SYS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
_this->spec.freq, SDL_AUDIO_BITSIZE(_this->spec.format),
|
||||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
_this->spec.channels, (_this->spec.format & 0x1000) ? "BE" : "LE", _this->spec.samples);
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
if (!iscapture) {
|
if (!iscapture) {
|
||||||
private->mixlen = this->spec.size;
|
private->mixlen = _this->spec.size;
|
||||||
private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen);
|
private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen);
|
||||||
if (private->mixbuf == NULL) {
|
if (private->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(private->mixbuf, this->spec.silence, this->spec.size);
|
SDL_memset(private->mixbuf, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private->frame_size = this->spec.channels * (SDL_AUDIO_BITSIZE(this->spec.format) / 8);
|
private->frame_size = _this->spec.channels * (SDL_AUDIO_BITSIZE(_this->spec.format) / 8);
|
||||||
|
|
||||||
res = ctx.AAudioStream_requestStart(private->stream);
|
res = ctx.AAudioStream_requestStart(private->stream);
|
||||||
if (res != AAUDIO_OK) {
|
if (res != AAUDIO_OK) {
|
||||||
@@ -157,9 +157,9 @@ static int aaudio_OpenDevice(_THIS, const char *devname)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aaudio_CloseDevice(_THIS)
|
static void aaudio_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *private = this->hidden;
|
struct SDL_PrivateAudioData *private = _this->hidden;
|
||||||
aaudio_result_t res;
|
aaudio_result_t res;
|
||||||
LOGI(__func__);
|
LOGI(__func__);
|
||||||
|
|
||||||
@@ -179,19 +179,19 @@ static void aaudio_CloseDevice(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *aaudio_GetDeviceBuf(_THIS)
|
static Uint8 *aaudio_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *private = this->hidden;
|
struct SDL_PrivateAudioData *private = _this->hidden;
|
||||||
return private->mixbuf;
|
return private->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aaudio_PlayDevice(_THIS)
|
static void aaudio_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *private = this->hidden;
|
struct SDL_PrivateAudioData *private = _this->hidden;
|
||||||
aaudio_result_t res;
|
aaudio_result_t res;
|
||||||
int64_t timeoutNanoseconds = 1 * 1000 * 1000; /* 8 ms */
|
int64_t timeoutNanoseconds = 1 * 1000 * 1000; /* 8 ms */
|
||||||
res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds);
|
res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds);
|
||||||
@@ -214,9 +214,9 @@ static void aaudio_PlayDevice(_THIS)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int aaudio_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *private = this->hidden;
|
struct SDL_PrivateAudioData *private = _this->hidden;
|
||||||
aaudio_result_t res;
|
aaudio_result_t res;
|
||||||
int64_t timeoutNanoseconds = 8 * 1000 * 1000; /* 8 ms */
|
int64_t timeoutNanoseconds = 8 * 1000 * 1000; /* 8 ms */
|
||||||
res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds);
|
res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds);
|
||||||
@@ -328,18 +328,18 @@ void aaudio_PauseDevices(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
||||||
SDL_AudioDevice *this = get_audio_dev(i);
|
SDL_AudioDevice *_this = get_audio_dev(i);
|
||||||
SDL_AudioDevice *audioDevice = NULL;
|
SDL_AudioDevice *audioDevice = NULL;
|
||||||
SDL_AudioDevice *captureDevice = NULL;
|
SDL_AudioDevice *captureDevice = NULL;
|
||||||
|
|
||||||
if (this == NULL) {
|
if (_this == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
captureDevice = this;
|
captureDevice = _this;
|
||||||
} else {
|
} else {
|
||||||
audioDevice = this;
|
audioDevice = _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||||
@@ -399,18 +399,18 @@ void aaudio_ResumeDevices(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
||||||
SDL_AudioDevice *this = get_audio_dev(i);
|
SDL_AudioDevice *_this = get_audio_dev(i);
|
||||||
SDL_AudioDevice *audioDevice = NULL;
|
SDL_AudioDevice *audioDevice = NULL;
|
||||||
SDL_AudioDevice *captureDevice = NULL;
|
SDL_AudioDevice *captureDevice = NULL;
|
||||||
|
|
||||||
if (this == NULL) {
|
if (_this == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
captureDevice = this;
|
captureDevice = _this;
|
||||||
} else {
|
} else {
|
||||||
audioDevice = this;
|
audioDevice = _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||||
@@ -466,18 +466,18 @@ SDL_bool aaudio_DetectBrokenPlayState(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
for (i = 0; i < get_max_num_audio_dev(); i++) {
|
||||||
SDL_AudioDevice *this = get_audio_dev(i);
|
SDL_AudioDevice *_this = get_audio_dev(i);
|
||||||
SDL_AudioDevice *audioDevice = NULL;
|
SDL_AudioDevice *audioDevice = NULL;
|
||||||
SDL_AudioDevice *captureDevice = NULL;
|
SDL_AudioDevice *captureDevice = NULL;
|
||||||
|
|
||||||
if (this == NULL) {
|
if (_this == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
captureDevice = this;
|
captureDevice = _this;
|
||||||
} else {
|
} else {
|
||||||
audioDevice = this;
|
audioDevice = _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <aaudio/AAudio.h>
|
#include <aaudio/AAudio.h>
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
AAudioStream *stream;
|
AAudioStream *stream;
|
||||||
|
|||||||
@@ -225,20 +225,20 @@ static const char *get_audio_device(void *handle, const int channels)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void ALSA_WaitDevice(_THIS)
|
static void ALSA_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
#if SDL_ALSA_NON_BLOCKING
|
#if SDL_ALSA_NON_BLOCKING
|
||||||
const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)this->spec.samples;
|
const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)_this->spec.samples;
|
||||||
while (SDL_AtomicGet(&this->enabled)) {
|
while (SDL_AtomicGet(&_this->enabled)) {
|
||||||
const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(this->hidden->pcm_handle);
|
const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(_this->hidden->pcm_handle);
|
||||||
if ((rc < 0) && (rc != -EAGAIN)) {
|
if ((rc < 0) && (rc != -EAGAIN)) {
|
||||||
/* Hmm, not much we can do - abort */
|
/* Hmm, not much we can do - abort */
|
||||||
fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n",
|
fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n",
|
||||||
ALSA_snd_strerror(rc));
|
ALSA_snd_strerror(rc));
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return;
|
return;
|
||||||
} else if (rc < needed) {
|
} else if (rc < needed) {
|
||||||
const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / this->spec.freq;
|
const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / _this->spec.freq;
|
||||||
SDL_Delay(SDL_max(delay, 10));
|
SDL_Delay(SDL_max(delay, 10));
|
||||||
} else {
|
} else {
|
||||||
break; /* ready to go! */
|
break; /* ready to go! */
|
||||||
@@ -311,15 +311,15 @@ CHANNEL_SWIZZLE(SWIZ8)
|
|||||||
#undef SWIZ8
|
#undef SWIZ8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called right before feeding this->hidden->mixbuf to the hardware. Swizzle
|
* Called right before feeding _this->hidden->mixbuf to the hardware. Swizzle
|
||||||
* channels from Windows/Mac order to the format alsalib will want.
|
* channels from Windows/Mac order to the format alsalib will want.
|
||||||
*/
|
*/
|
||||||
static void swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
static void swizzle_alsa_channels(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen)
|
||||||
{
|
{
|
||||||
switch (this->spec.channels) {
|
switch (_this->spec.channels) {
|
||||||
#define CHANSWIZ(chans) \
|
#define CHANSWIZ(chans) \
|
||||||
case chans: \
|
case chans: \
|
||||||
switch ((this->spec.format & (0xFF))) { \
|
switch ((_this->spec.format & (0xFF))) { \
|
||||||
case 8: \
|
case 8: \
|
||||||
swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \
|
swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \
|
||||||
break; \
|
break; \
|
||||||
@@ -348,22 +348,22 @@ static void swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
|||||||
|
|
||||||
#ifdef SND_CHMAP_API_VERSION
|
#ifdef SND_CHMAP_API_VERSION
|
||||||
/* Some devices have the right channel map, no swizzling necessary */
|
/* Some devices have the right channel map, no swizzling necessary */
|
||||||
static void no_swizzle(_THIS, void *buffer, Uint32 bufferlen)
|
static void no_swizzle(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif /* SND_CHMAP_API_VERSION */
|
#endif /* SND_CHMAP_API_VERSION */
|
||||||
|
|
||||||
static void ALSA_PlayDevice(_THIS)
|
static void ALSA_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
const Uint8 *sample_buf = (const Uint8 *)this->hidden->mixbuf;
|
const Uint8 *sample_buf = (const Uint8 *)_this->hidden->mixbuf;
|
||||||
const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
|
const int frame_size = ((SDL_AUDIO_BITSIZE(_this->spec.format)) / 8) *
|
||||||
this->spec.channels;
|
_this->spec.channels;
|
||||||
snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)this->spec.samples);
|
snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)_this->spec.samples);
|
||||||
|
|
||||||
this->hidden->swizzle_func(this, this->hidden->mixbuf, frames_left);
|
_this->hidden->swizzle_func(_this, _this->hidden->mixbuf, frames_left);
|
||||||
|
|
||||||
while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) {
|
while (frames_left > 0 && SDL_AtomicGet(&_this->enabled)) {
|
||||||
int status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
|
int status = ALSA_snd_pcm_writei(_this->hidden->pcm_handle,
|
||||||
sample_buf, frames_left);
|
sample_buf, frames_left);
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@@ -373,20 +373,20 @@ static void ALSA_PlayDevice(_THIS)
|
|||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0);
|
status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
/* Hmm, not much we can do - abort */
|
/* Hmm, not much we can do - abort */
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
||||||
"ALSA write failed (unrecoverable): %s\n",
|
"ALSA write failed (unrecoverable): %s\n",
|
||||||
ALSA_snd_strerror(status));
|
ALSA_snd_strerror(status));
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (status == 0) {
|
} else if (status == 0) {
|
||||||
/* No frames were written (no available space in pcm device).
|
/* No frames were written (no available space in pcm device).
|
||||||
Allow other threads to catch up. */
|
Allow other threads to catch up. */
|
||||||
Uint32 delay = (frames_left / 2 * 1000) / this->spec.freq;
|
Uint32 delay = (frames_left / 2 * 1000) / _this->spec.freq;
|
||||||
SDL_Delay(delay);
|
SDL_Delay(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,34 +395,34 @@ static void ALSA_PlayDevice(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *ALSA_GetDeviceBuf(_THIS)
|
static Uint8 *ALSA_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
Uint8 *sample_buf = (Uint8 *)buffer;
|
Uint8 *sample_buf = (Uint8 *)buffer;
|
||||||
const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
|
const int frame_size = ((SDL_AUDIO_BITSIZE(_this->spec.format)) / 8) *
|
||||||
this->spec.channels;
|
_this->spec.channels;
|
||||||
const int total_frames = buflen / frame_size;
|
const int total_frames = buflen / frame_size;
|
||||||
snd_pcm_uframes_t frames_left = total_frames;
|
snd_pcm_uframes_t frames_left = total_frames;
|
||||||
snd_pcm_uframes_t wait_time = frame_size / 2;
|
snd_pcm_uframes_t wait_time = frame_size / 2;
|
||||||
|
|
||||||
SDL_assert((buflen % frame_size) == 0);
|
SDL_assert((buflen % frame_size) == 0);
|
||||||
|
|
||||||
while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) {
|
while (frames_left > 0 && SDL_AtomicGet(&_this->enabled)) {
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = ALSA_snd_pcm_readi(this->hidden->pcm_handle,
|
status = ALSA_snd_pcm_readi(_this->hidden->pcm_handle,
|
||||||
sample_buf, frames_left);
|
sample_buf, frames_left);
|
||||||
|
|
||||||
if (status == -EAGAIN) {
|
if (status == -EAGAIN) {
|
||||||
ALSA_snd_pcm_wait(this->hidden->pcm_handle, wait_time);
|
ALSA_snd_pcm_wait(_this->hidden->pcm_handle, wait_time);
|
||||||
status = 0;
|
status = 0;
|
||||||
} else if (status < 0) {
|
} else if (status < 0) {
|
||||||
/*printf("ALSA: capture error %d\n", status);*/
|
/*printf("ALSA: capture error %d\n", status);*/
|
||||||
status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0);
|
status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
/* Hmm, not much we can do - abort */
|
/* Hmm, not much we can do - abort */
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
||||||
@@ -438,32 +438,32 @@ static int ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
frames_left -= status;
|
frames_left -= status;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->swizzle_func(this, buffer, total_frames - frames_left);
|
_this->hidden->swizzle_func(_this, buffer, total_frames - frames_left);
|
||||||
|
|
||||||
return (total_frames - frames_left) * frame_size;
|
return (total_frames - frames_left) * frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ALSA_FlushCapture(_THIS)
|
static void ALSA_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
ALSA_snd_pcm_reset(this->hidden->pcm_handle);
|
ALSA_snd_pcm_reset(_this->hidden->pcm_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ALSA_CloseDevice(_THIS)
|
static void ALSA_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->pcm_handle) {
|
if (_this->hidden->pcm_handle) {
|
||||||
/* Wait for the submitted audio to drain
|
/* Wait for the submitted audio to drain
|
||||||
ALSA_snd_pcm_drop() can hang, so don't use that.
|
ALSA_snd_pcm_drop() can hang, so don't use that.
|
||||||
*/
|
*/
|
||||||
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;
|
Uint32 delay = ((_this->spec.samples * 1000) / _this->spec.freq) * 2;
|
||||||
SDL_Delay(delay);
|
SDL_Delay(delay);
|
||||||
|
|
||||||
ALSA_snd_pcm_close(this->hidden->pcm_handle);
|
ALSA_snd_pcm_close(_this->hidden->pcm_handle);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *params)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
snd_pcm_hw_params_t *hwparams;
|
snd_pcm_hw_params_t *hwparams;
|
||||||
@@ -475,9 +475,9 @@ static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
|||||||
ALSA_snd_pcm_hw_params_copy(hwparams, params);
|
ALSA_snd_pcm_hw_params_copy(hwparams, params);
|
||||||
|
|
||||||
/* Attempt to match the period size to the requested buffer size */
|
/* Attempt to match the period size to the requested buffer size */
|
||||||
persize = this->spec.samples;
|
persize = _this->spec.samples;
|
||||||
status = ALSA_snd_pcm_hw_params_set_period_size_near(
|
status = ALSA_snd_pcm_hw_params_set_period_size_near(
|
||||||
this->hidden->pcm_handle, hwparams, &persize, NULL);
|
_this->hidden->pcm_handle, hwparams, &persize, NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -485,24 +485,24 @@ static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
|||||||
/* Need to at least double buffer */
|
/* Need to at least double buffer */
|
||||||
periods = 2;
|
periods = 2;
|
||||||
status = ALSA_snd_pcm_hw_params_set_periods_min(
|
status = ALSA_snd_pcm_hw_params_set_periods_min(
|
||||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
_this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ALSA_snd_pcm_hw_params_set_periods_first(
|
status = ALSA_snd_pcm_hw_params_set_periods_first(
|
||||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
_this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "set" the hardware with the desired parameters */
|
/* "set" the hardware with the desired parameters */
|
||||||
status = ALSA_snd_pcm_hw_params(this->hidden->pcm_handle, hwparams);
|
status = ALSA_snd_pcm_hw_params(_this->hidden->pcm_handle, hwparams);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->spec.samples = persize;
|
_this->spec.samples = persize;
|
||||||
|
|
||||||
/* This is useful for debugging */
|
/* This is useful for debugging */
|
||||||
if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) {
|
if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) {
|
||||||
@@ -518,10 +518,10 @@ static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ALSA_OpenDevice(_THIS, const char *devname)
|
static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
snd_pcm_t *pcm_handle = NULL;
|
snd_pcm_t *pcm_handle = NULL;
|
||||||
snd_pcm_hw_params_t *hwparams = NULL;
|
snd_pcm_hw_params_t *hwparams = NULL;
|
||||||
snd_pcm_sw_params_t *swparams = NULL;
|
snd_pcm_sw_params_t *swparams = NULL;
|
||||||
@@ -536,16 +536,16 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* Open the audio device */
|
/* Open the audio device */
|
||||||
/* Name of device should depend on # channels in spec */
|
/* Name of device should depend on # channels in spec */
|
||||||
status = ALSA_snd_pcm_open(&pcm_handle,
|
status = ALSA_snd_pcm_open(&pcm_handle,
|
||||||
get_audio_device(this->handle, this->spec.channels),
|
get_audio_device(_this->handle, _this->spec.channels),
|
||||||
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
|
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
|
||||||
SND_PCM_NONBLOCK);
|
SND_PCM_NONBLOCK);
|
||||||
|
|
||||||
@@ -553,7 +553,7 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status));
|
return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->pcm_handle = pcm_handle;
|
_this->hidden->pcm_handle = pcm_handle;
|
||||||
|
|
||||||
/* Figure out what the hardware is capable of */
|
/* Figure out what the hardware is capable of */
|
||||||
snd_pcm_hw_params_alloca(&hwparams);
|
snd_pcm_hw_params_alloca(&hwparams);
|
||||||
@@ -570,7 +570,7 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try for a closest match on audio format */
|
/* Try for a closest match on audio format */
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
case SDL_AUDIO_U8:
|
case SDL_AUDIO_U8:
|
||||||
@@ -607,19 +607,19 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
if (!test_format) {
|
if (!test_format) {
|
||||||
return SDL_SetError("%s: Unsupported audio format", "alsa");
|
return SDL_SetError("%s: Unsupported audio format", "alsa");
|
||||||
}
|
}
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
|
|
||||||
/* Validate number of channels and determine if swizzling is necessary
|
/* Validate number of channels and determine if swizzling is necessary
|
||||||
* Assume original swizzling, until proven otherwise.
|
* Assume original swizzling, until proven otherwise.
|
||||||
*/
|
*/
|
||||||
this->hidden->swizzle_func = swizzle_alsa_channels;
|
_this->hidden->swizzle_func = swizzle_alsa_channels;
|
||||||
#ifdef SND_CHMAP_API_VERSION
|
#ifdef SND_CHMAP_API_VERSION
|
||||||
chmap = ALSA_snd_pcm_get_chmap(pcm_handle);
|
chmap = ALSA_snd_pcm_get_chmap(pcm_handle);
|
||||||
if (chmap) {
|
if (chmap) {
|
||||||
if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) {
|
if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) {
|
||||||
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
|
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
|
||||||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
||||||
this->hidden->swizzle_func = no_swizzle;
|
_this->hidden->swizzle_func = no_swizzle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(chmap);
|
free(chmap);
|
||||||
@@ -628,27 +628,27 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
/* Set the number of channels */
|
/* Set the number of channels */
|
||||||
status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
|
status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
|
||||||
this->spec.channels);
|
_this->spec.channels);
|
||||||
channels = this->spec.channels;
|
channels = _this->spec.channels;
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
|
status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return SDL_SetError("ALSA: Couldn't set audio channels");
|
return SDL_SetError("ALSA: Couldn't set audio channels");
|
||||||
}
|
}
|
||||||
this->spec.channels = channels;
|
_this->spec.channels = channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the audio rate */
|
/* Set the audio rate */
|
||||||
rate = this->spec.freq;
|
rate = _this->spec.freq;
|
||||||
status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
|
status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
|
||||||
&rate, NULL);
|
&rate, NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status));
|
return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status));
|
||||||
}
|
}
|
||||||
this->spec.freq = rate;
|
_this->spec.freq = rate;
|
||||||
|
|
||||||
/* Set the buffer size, in samples */
|
/* Set the buffer size, in samples */
|
||||||
status = ALSA_set_buffer_size(this, hwparams);
|
status = ALSA_set_buffer_size(_this, hwparams);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status));
|
return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status));
|
||||||
}
|
}
|
||||||
@@ -659,7 +659,7 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status));
|
return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status));
|
||||||
}
|
}
|
||||||
status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples);
|
status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, _this->spec.samples);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status));
|
return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status));
|
||||||
}
|
}
|
||||||
@@ -674,16 +674,16 @@ static int ALSA_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the final parameters for this audio specification */
|
/* Calculate the final parameters for this audio specification */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
if (!iscapture) {
|
if (!iscapture) {
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen);
|
||||||
if (this->hidden->mixbuf == NULL) {
|
if (_this->hidden->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
|
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->hidden->mixlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !SDL_ALSA_NON_BLOCKING
|
#if !SDL_ALSA_NON_BLOCKING
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The audio device handle */
|
/* The audio device handle */
|
||||||
@@ -40,7 +37,7 @@ struct SDL_PrivateAudioData
|
|||||||
int mixlen;
|
int mixlen;
|
||||||
|
|
||||||
/* swizzle function */
|
/* swizzle function */
|
||||||
void (*swizzle_func)(_THIS, void *buffer, Uint32 bufferlen);
|
void (*swizzle_func)(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SDL_ALSA_audio_h_ */
|
#endif /* SDL_ALSA_audio_h_ */
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ static SDL_AudioDevice *audioDevice = NULL;
|
|||||||
static SDL_AudioDevice *captureDevice = NULL;
|
static SDL_AudioDevice *captureDevice = NULL;
|
||||||
|
|
||||||
|
|
||||||
static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
static int ANDROIDAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
|
|
||||||
if (iscapture) {
|
if (iscapture) {
|
||||||
if (captureDevice) {
|
if (captureDevice) {
|
||||||
@@ -54,22 +54,22 @@ static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iscapture) {
|
if (iscapture) {
|
||||||
captureDevice = this;
|
captureDevice = _this;
|
||||||
} else {
|
} else {
|
||||||
audioDevice = this;
|
audioDevice = _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
if ((test_format == SDL_AUDIO_U8) ||
|
if ((test_format == SDL_AUDIO_U8) ||
|
||||||
(test_format == SDL_AUDIO_S16) ||
|
(test_format == SDL_AUDIO_S16) ||
|
||||||
(test_format == SDL_AUDIO_F32)) {
|
(test_format == SDL_AUDIO_F32)) {
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,50 +84,50 @@ static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
if (devname != NULL) {
|
if (devname != NULL) {
|
||||||
audio_device_id = SDL_atoi(devname);
|
audio_device_id = SDL_atoi(devname);
|
||||||
}
|
}
|
||||||
if (Android_JNI_OpenAudioDevice(iscapture, audio_device_id, &this->spec) < 0) {
|
if (Android_JNI_OpenAudioDevice(iscapture, audio_device_id, &_this->spec) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ANDROIDAUDIO_PlayDevice(_THIS)
|
static void ANDROIDAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
Android_JNI_WriteAudioBuffer();
|
Android_JNI_WriteAudioBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *ANDROIDAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *ANDROIDAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return Android_JNI_GetAudioBuffer();
|
return Android_JNI_GetAudioBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int ANDROIDAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
return Android_JNI_CaptureAudioBuffer(buffer, buflen);
|
return Android_JNI_CaptureAudioBuffer(buffer, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ANDROIDAUDIO_FlushCapture(_THIS)
|
static void ANDROIDAUDIO_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
Android_JNI_FlushCapturedAudio();
|
Android_JNI_FlushCapturedAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ANDROIDAUDIO_CloseDevice(_THIS)
|
static void ANDROIDAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
|
/* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
|
||||||
so it's safe to terminate the Java side buffer and AudioTrack
|
so it's safe to terminate the Java side buffer and AudioTrack
|
||||||
*/
|
*/
|
||||||
Android_JNI_CloseAudioDevice(this->iscapture);
|
Android_JNI_CloseAudioDevice(_this->iscapture);
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
SDL_assert(captureDevice == this);
|
SDL_assert(captureDevice == _this);
|
||||||
captureDevice = NULL;
|
captureDevice = NULL;
|
||||||
} else {
|
} else {
|
||||||
SDL_assert(audioDevice == this);
|
SDL_assert(audioDevice == _this);
|
||||||
audioDevice = NULL;
|
audioDevice = NULL;
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl)
|
static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* Resume device if it was paused automatically */
|
/* Resume device if it was paused automatically */
|
||||||
|
|||||||
@@ -47,9 +47,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
SDL_Thread *thread;
|
SDL_Thread *thread;
|
||||||
|
|||||||
+162
-162
File diff suppressed because it is too large
Load Diff
@@ -198,7 +198,7 @@ static void DSOUND_DetectDevices(void)
|
|||||||
#endif /* HAVE_MMDEVICEAPI_H*/
|
#endif /* HAVE_MMDEVICEAPI_H*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_WaitDevice(_THIS)
|
static void DSOUND_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
DWORD status = 0;
|
DWORD status = 0;
|
||||||
DWORD cursor = 0;
|
DWORD cursor = 0;
|
||||||
@@ -208,11 +208,11 @@ static void DSOUND_WaitDevice(_THIS)
|
|||||||
/* Semi-busy wait, since we have no way of getting play notification
|
/* Semi-busy wait, since we have no way of getting play notification
|
||||||
on a primary mixing buffer located in hardware (DirectX 5.0)
|
on a primary mixing buffer located in hardware (DirectX 5.0)
|
||||||
*/
|
*/
|
||||||
result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
|
result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf,
|
||||||
&junk, &cursor);
|
&junk, &cursor);
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
if (result == DSERR_BUFFERLOST) {
|
if (result == DSERR_BUFFERLOST) {
|
||||||
IDirectSoundBuffer_Restore(this->hidden->mixbuf);
|
IDirectSoundBuffer_Restore(_this->hidden->mixbuf);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_SOUND
|
#ifdef DEBUG_SOUND
|
||||||
SetDSerror("DirectSound GetCurrentPosition", result);
|
SetDSerror("DirectSound GetCurrentPosition", result);
|
||||||
@@ -220,21 +220,21 @@ static void DSOUND_WaitDevice(_THIS)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((cursor / this->spec.size) == this->hidden->lastchunk) {
|
while ((cursor / _this->spec.size) == _this->hidden->lastchunk) {
|
||||||
/* FIXME: find out how much time is left and sleep that long */
|
/* FIXME: find out how much time is left and sleep that long */
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
|
|
||||||
/* Try to restore a lost sound buffer */
|
/* Try to restore a lost sound buffer */
|
||||||
IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status);
|
IDirectSoundBuffer_GetStatus(_this->hidden->mixbuf, &status);
|
||||||
if (status & DSBSTATUS_BUFFERLOST) {
|
if (status & DSBSTATUS_BUFFERLOST) {
|
||||||
IDirectSoundBuffer_Restore(this->hidden->mixbuf);
|
IDirectSoundBuffer_Restore(_this->hidden->mixbuf);
|
||||||
IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status);
|
IDirectSoundBuffer_GetStatus(_this->hidden->mixbuf, &status);
|
||||||
if (status & DSBSTATUS_BUFFERLOST) {
|
if (status & DSBSTATUS_BUFFERLOST) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(status & DSBSTATUS_PLAYING)) {
|
if (!(status & DSBSTATUS_PLAYING)) {
|
||||||
result = IDirectSoundBuffer_Play(this->hidden->mixbuf, 0, 0,
|
result = IDirectSoundBuffer_Play(_this->hidden->mixbuf, 0, 0,
|
||||||
DSBPLAY_LOOPING);
|
DSBPLAY_LOOPING);
|
||||||
if (result == DS_OK) {
|
if (result == DS_OK) {
|
||||||
continue;
|
continue;
|
||||||
@@ -246,7 +246,7 @@ static void DSOUND_WaitDevice(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find out where we are playing */
|
/* Find out where we are playing */
|
||||||
result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
|
result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf,
|
||||||
&junk, &cursor);
|
&junk, &cursor);
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
SetDSerror("DirectSound GetCurrentPosition", result);
|
SetDSerror("DirectSound GetCurrentPosition", result);
|
||||||
@@ -255,17 +255,17 @@ static void DSOUND_WaitDevice(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_PlayDevice(_THIS)
|
static void DSOUND_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Unlock the buffer, allowing it to play */
|
/* Unlock the buffer, allowing it to play */
|
||||||
if (this->hidden->locked_buf) {
|
if (_this->hidden->locked_buf) {
|
||||||
IDirectSoundBuffer_Unlock(this->hidden->mixbuf,
|
IDirectSoundBuffer_Unlock(_this->hidden->mixbuf,
|
||||||
this->hidden->locked_buf,
|
_this->hidden->locked_buf,
|
||||||
this->spec.size, NULL, 0);
|
_this->spec.size, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *DSOUND_GetDeviceBuf(_THIS)
|
static Uint8 *DSOUND_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
DWORD cursor = 0;
|
DWORD cursor = 0;
|
||||||
DWORD junk = 0;
|
DWORD junk = 0;
|
||||||
@@ -273,84 +273,84 @@ static Uint8 *DSOUND_GetDeviceBuf(_THIS)
|
|||||||
DWORD rawlen = 0;
|
DWORD rawlen = 0;
|
||||||
|
|
||||||
/* Figure out which blocks to fill next */
|
/* Figure out which blocks to fill next */
|
||||||
this->hidden->locked_buf = NULL;
|
_this->hidden->locked_buf = NULL;
|
||||||
result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
|
result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf,
|
||||||
&junk, &cursor);
|
&junk, &cursor);
|
||||||
if (result == DSERR_BUFFERLOST) {
|
if (result == DSERR_BUFFERLOST) {
|
||||||
IDirectSoundBuffer_Restore(this->hidden->mixbuf);
|
IDirectSoundBuffer_Restore(_this->hidden->mixbuf);
|
||||||
result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf,
|
result = IDirectSoundBuffer_GetCurrentPosition(_this->hidden->mixbuf,
|
||||||
&junk, &cursor);
|
&junk, &cursor);
|
||||||
}
|
}
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
SetDSerror("DirectSound GetCurrentPosition", result);
|
SetDSerror("DirectSound GetCurrentPosition", result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
cursor /= this->spec.size;
|
cursor /= _this->spec.size;
|
||||||
#ifdef DEBUG_SOUND
|
#ifdef DEBUG_SOUND
|
||||||
/* Detect audio dropouts */
|
/* Detect audio dropouts */
|
||||||
{
|
{
|
||||||
DWORD spot = cursor;
|
DWORD spot = cursor;
|
||||||
if (spot < this->hidden->lastchunk) {
|
if (spot < _this->hidden->lastchunk) {
|
||||||
spot += this->hidden->num_buffers;
|
spot += _this->hidden->num_buffers;
|
||||||
}
|
}
|
||||||
if (spot > this->hidden->lastchunk + 1) {
|
if (spot > _this->hidden->lastchunk + 1) {
|
||||||
fprintf(stderr, "Audio dropout, missed %d fragments\n",
|
fprintf(stderr, "Audio dropout, missed %d fragments\n",
|
||||||
(spot - (this->hidden->lastchunk + 1)));
|
(spot - (_this->hidden->lastchunk + 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
this->hidden->lastchunk = cursor;
|
_this->hidden->lastchunk = cursor;
|
||||||
cursor = (cursor + 1) % this->hidden->num_buffers;
|
cursor = (cursor + 1) % _this->hidden->num_buffers;
|
||||||
cursor *= this->spec.size;
|
cursor *= _this->spec.size;
|
||||||
|
|
||||||
/* Lock the audio buffer */
|
/* Lock the audio buffer */
|
||||||
result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
|
result = IDirectSoundBuffer_Lock(_this->hidden->mixbuf, cursor,
|
||||||
this->spec.size,
|
_this->spec.size,
|
||||||
(LPVOID *)&this->hidden->locked_buf,
|
(LPVOID *)&_this->hidden->locked_buf,
|
||||||
&rawlen, NULL, &junk, 0);
|
&rawlen, NULL, &junk, 0);
|
||||||
if (result == DSERR_BUFFERLOST) {
|
if (result == DSERR_BUFFERLOST) {
|
||||||
IDirectSoundBuffer_Restore(this->hidden->mixbuf);
|
IDirectSoundBuffer_Restore(_this->hidden->mixbuf);
|
||||||
result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
|
result = IDirectSoundBuffer_Lock(_this->hidden->mixbuf, cursor,
|
||||||
this->spec.size,
|
_this->spec.size,
|
||||||
(LPVOID *)&this->hidden->locked_buf, &rawlen, NULL,
|
(LPVOID *)&_this->hidden->locked_buf, &rawlen, NULL,
|
||||||
&junk, 0);
|
&junk, 0);
|
||||||
}
|
}
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
SetDSerror("DirectSound Lock", result);
|
SetDSerror("DirectSound Lock", result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return this->hidden->locked_buf;
|
return _this->hidden->locked_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int DSOUND_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
DWORD junk, cursor, ptr1len, ptr2len;
|
DWORD junk, cursor, ptr1len, ptr2len;
|
||||||
VOID *ptr1, *ptr2;
|
VOID *ptr1, *ptr2;
|
||||||
|
|
||||||
SDL_assert((Uint32)buflen == this->spec.size);
|
SDL_assert((Uint32)buflen == _this->spec.size);
|
||||||
|
|
||||||
while (SDL_TRUE) {
|
while (SDL_TRUE) {
|
||||||
if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */
|
if (SDL_AtomicGet(&_this->shutdown)) { /* in case the buffer froze... */
|
||||||
SDL_memset(buffer, this->spec.silence, buflen);
|
SDL_memset(buffer, _this->spec.silence, buflen);
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
|
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((cursor / this->spec.size) == h->lastchunk) {
|
if ((cursor / _this->spec.size) == h->lastchunk) {
|
||||||
SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */
|
SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) {
|
if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * _this->spec.size, _this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_assert(ptr1len == this->spec.size);
|
SDL_assert(ptr1len == _this->spec.size);
|
||||||
SDL_assert(ptr2 == NULL);
|
SDL_assert(ptr2 == NULL);
|
||||||
SDL_assert(ptr2len == 0);
|
SDL_assert(ptr2len == 0);
|
||||||
|
|
||||||
@@ -365,42 +365,42 @@ static int DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
return ptr1len;
|
return ptr1len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_FlushCapture(_THIS)
|
static void DSOUND_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
DWORD junk, cursor;
|
DWORD junk, cursor;
|
||||||
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) {
|
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) {
|
||||||
h->lastchunk = cursor / this->spec.size;
|
h->lastchunk = cursor / _this->spec.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_CloseDevice(_THIS)
|
static void DSOUND_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->mixbuf != NULL) {
|
if (_this->hidden->mixbuf != NULL) {
|
||||||
IDirectSoundBuffer_Stop(this->hidden->mixbuf);
|
IDirectSoundBuffer_Stop(_this->hidden->mixbuf);
|
||||||
IDirectSoundBuffer_Release(this->hidden->mixbuf);
|
IDirectSoundBuffer_Release(_this->hidden->mixbuf);
|
||||||
}
|
}
|
||||||
if (this->hidden->sound != NULL) {
|
if (_this->hidden->sound != NULL) {
|
||||||
IDirectSound_Release(this->hidden->sound);
|
IDirectSound_Release(_this->hidden->sound);
|
||||||
}
|
}
|
||||||
if (this->hidden->capturebuf != NULL) {
|
if (_this->hidden->capturebuf != NULL) {
|
||||||
IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf);
|
IDirectSoundCaptureBuffer_Stop(_this->hidden->capturebuf);
|
||||||
IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf);
|
IDirectSoundCaptureBuffer_Release(_this->hidden->capturebuf);
|
||||||
}
|
}
|
||||||
if (this->hidden->capture != NULL) {
|
if (_this->hidden->capture != NULL) {
|
||||||
IDirectSoundCapture_Release(this->hidden->capture);
|
IDirectSoundCapture_Release(_this->hidden->capture);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function tries to create a secondary audio buffer, and returns the
|
/* This function tries to create a secondary audio buffer, and returns the
|
||||||
number of audio chunks available in the created buffer. This is for
|
number of audio chunks available in the created buffer. This is for
|
||||||
playback devices, not capture.
|
playback devices, not capture.
|
||||||
*/
|
*/
|
||||||
static int CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
static int CreateSecondary(SDL_AudioDevice *_this, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||||
{
|
{
|
||||||
LPDIRECTSOUND sndObj = this->hidden->sound;
|
LPDIRECTSOUND sndObj = _this->hidden->sound;
|
||||||
LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
|
LPDIRECTSOUNDBUFFER *sndbuf = &_this->hidden->mixbuf;
|
||||||
HRESULT result = DS_OK;
|
HRESULT result = DS_OK;
|
||||||
DSBUFFERDESC format;
|
DSBUFFERDESC format;
|
||||||
LPVOID pvAudioPtr1, pvAudioPtr2;
|
LPVOID pvAudioPtr1, pvAudioPtr2;
|
||||||
@@ -425,7 +425,7 @@ static int CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
|||||||
(LPVOID *)&pvAudioPtr2, &dwAudioBytes2,
|
(LPVOID *)&pvAudioPtr2, &dwAudioBytes2,
|
||||||
DSBLOCK_ENTIREBUFFER);
|
DSBLOCK_ENTIREBUFFER);
|
||||||
if (result == DS_OK) {
|
if (result == DS_OK) {
|
||||||
SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1);
|
SDL_memset(pvAudioPtr1, _this->spec.silence, dwAudioBytes1);
|
||||||
IDirectSoundBuffer_Unlock(*sndbuf,
|
IDirectSoundBuffer_Unlock(*sndbuf,
|
||||||
(LPVOID)pvAudioPtr1, dwAudioBytes1,
|
(LPVOID)pvAudioPtr1, dwAudioBytes1,
|
||||||
(LPVOID)pvAudioPtr2, dwAudioBytes2);
|
(LPVOID)pvAudioPtr2, dwAudioBytes2);
|
||||||
@@ -439,10 +439,10 @@ static int CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
|||||||
number of audio chunks available in the created buffer. This is for
|
number of audio chunks available in the created buffer. This is for
|
||||||
capture devices, not playback.
|
capture devices, not playback.
|
||||||
*/
|
*/
|
||||||
static int CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
static int CreateCaptureBuffer(SDL_AudioDevice *_this, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||||
{
|
{
|
||||||
LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
|
LPDIRECTSOUNDCAPTURE capture = _this->hidden->capture;
|
||||||
LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
|
LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &_this->hidden->capturebuf;
|
||||||
DSCBUFFERDESC format;
|
DSCBUFFERDESC format;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
@@ -472,42 +472,42 @@ static int CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
|||||||
return SetDSerror("DirectSound GetCurrentPosition", result);
|
return SetDSerror("DirectSound GetCurrentPosition", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->lastchunk = cursor / this->spec.size;
|
_this->hidden->lastchunk = cursor / _this->spec.size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSOUND_OpenDevice(_THIS, const char *devname)
|
static int DSOUND_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
const DWORD numchunks = 8;
|
const DWORD numchunks = 8;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
SDL_bool tried_format = SDL_FALSE;
|
SDL_bool tried_format = SDL_FALSE;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
LPGUID guid = (LPGUID)this->handle;
|
LPGUID guid = (LPGUID)_this->handle;
|
||||||
DWORD bufsize;
|
DWORD bufsize;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* Open the audio device */
|
/* Open the audio device */
|
||||||
if (iscapture) {
|
if (iscapture) {
|
||||||
result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL);
|
result = pDirectSoundCaptureCreate8(guid, &_this->hidden->capture, NULL);
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
return SetDSerror("DirectSoundCaptureCreate8", result);
|
return SetDSerror("DirectSoundCaptureCreate8", result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
|
result = pDirectSoundCreate8(guid, &_this->hidden->sound, NULL);
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
return SetDSerror("DirectSoundCreate8", result);
|
return SetDSerror("DirectSoundCreate8", result);
|
||||||
}
|
}
|
||||||
result = IDirectSound_SetCooperativeLevel(this->hidden->sound,
|
result = IDirectSound_SetCooperativeLevel(_this->hidden->sound,
|
||||||
GetDesktopWindow(),
|
GetDesktopWindow(),
|
||||||
DSSCL_NORMAL);
|
DSSCL_NORMAL);
|
||||||
if (result != DS_OK) {
|
if (result != DS_OK) {
|
||||||
@@ -515,7 +515,7 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
case SDL_AUDIO_U8:
|
case SDL_AUDIO_U8:
|
||||||
@@ -524,12 +524,12 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||||||
case SDL_AUDIO_F32:
|
case SDL_AUDIO_F32:
|
||||||
tried_format = SDL_TRUE;
|
tried_format = SDL_TRUE;
|
||||||
|
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes */
|
/* Update the fragment size as size in bytes */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
bufsize = numchunks * this->spec.size;
|
bufsize = numchunks * _this->spec.size;
|
||||||
if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
|
if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
|
||||||
SDL_SetError("Sound buffer size must be between %d and %d",
|
SDL_SetError("Sound buffer size must be between %d and %d",
|
||||||
(int)((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
|
(int)((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
|
||||||
@@ -538,18 +538,18 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||||||
int rc;
|
int rc;
|
||||||
WAVEFORMATEXTENSIBLE wfmt;
|
WAVEFORMATEXTENSIBLE wfmt;
|
||||||
SDL_zero(wfmt);
|
SDL_zero(wfmt);
|
||||||
if (this->spec.channels > 2) {
|
if (_this->spec.channels > 2) {
|
||||||
wfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
wfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||||
wfmt.Format.cbSize = sizeof(wfmt) - sizeof(WAVEFORMATEX);
|
wfmt.Format.cbSize = sizeof(wfmt) - sizeof(WAVEFORMATEX);
|
||||||
|
|
||||||
if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
if (SDL_AUDIO_ISFLOAT(_this->spec.format)) {
|
||||||
SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID));
|
SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID));
|
||||||
} else {
|
} else {
|
||||||
SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
|
SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
|
||||||
}
|
}
|
||||||
wfmt.Samples.wValidBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
wfmt.Samples.wValidBitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
|
|
||||||
switch (this->spec.channels) {
|
switch (_this->spec.channels) {
|
||||||
case 3: /* 3.0 (or 2.1) */
|
case 3: /* 3.0 (or 2.1) */
|
||||||
wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER;
|
wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER;
|
||||||
break;
|
break;
|
||||||
@@ -572,21 +572,21 @@ static int DSOUND_OpenDevice(_THIS, const char *devname)
|
|||||||
SDL_assert(0 && "Unsupported channel count!");
|
SDL_assert(0 && "Unsupported channel count!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
} else if (SDL_AUDIO_ISFLOAT(_this->spec.format)) {
|
||||||
wfmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
wfmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||||
} else {
|
} else {
|
||||||
wfmt.Format.wFormatTag = WAVE_FORMAT_PCM;
|
wfmt.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
}
|
}
|
||||||
|
|
||||||
wfmt.Format.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
wfmt.Format.wBitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
wfmt.Format.nChannels = this->spec.channels;
|
wfmt.Format.nChannels = _this->spec.channels;
|
||||||
wfmt.Format.nSamplesPerSec = this->spec.freq;
|
wfmt.Format.nSamplesPerSec = _this->spec.freq;
|
||||||
wfmt.Format.nBlockAlign = wfmt.Format.nChannels * (wfmt.Format.wBitsPerSample / 8);
|
wfmt.Format.nBlockAlign = wfmt.Format.nChannels * (wfmt.Format.wBitsPerSample / 8);
|
||||||
wfmt.Format.nAvgBytesPerSec = wfmt.Format.nSamplesPerSec * wfmt.Format.nBlockAlign;
|
wfmt.Format.nAvgBytesPerSec = wfmt.Format.nSamplesPerSec * wfmt.Format.nBlockAlign;
|
||||||
|
|
||||||
rc = iscapture ? CreateCaptureBuffer(this, bufsize, (WAVEFORMATEX *)&wfmt) : CreateSecondary(this, bufsize, (WAVEFORMATEX *)&wfmt);
|
rc = iscapture ? CreateCaptureBuffer(_this, bufsize, (WAVEFORMATEX *)&wfmt) : CreateSecondary(_this, bufsize, (WAVEFORMATEX *)&wfmt);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
this->hidden->num_buffers = numchunks;
|
_this->hidden->num_buffers = numchunks;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
/* The DirectSound objects */
|
/* The DirectSound objects */
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,12 +40,12 @@
|
|||||||
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void DISKAUDIO_WaitDevice(_THIS)
|
static void DISKAUDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_Delay(_this->hidden->io_delay);
|
SDL_Delay(_this->hidden->io_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DISKAUDIO_PlayDevice(_THIS)
|
static void DISKAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
const Sint64 written = SDL_RWwrite(_this->hidden->io,
|
const Sint64 written = SDL_RWwrite(_this->hidden->io,
|
||||||
_this->hidden->mixbuf,
|
_this->hidden->mixbuf,
|
||||||
@@ -60,12 +60,12 @@ static void DISKAUDIO_PlayDevice(_THIS)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *DISKAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *DISKAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return _this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int DISKAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = _this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
const int origbuflen = buflen;
|
const int origbuflen = buflen;
|
||||||
@@ -88,12 +88,12 @@ static int DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
return origbuflen;
|
return origbuflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DISKAUDIO_FlushCapture(_THIS)
|
static void DISKAUDIO_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* no op...we don't advance the file pointer or anything. */
|
/* no op...we don't advance the file pointer or anything. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DISKAUDIO_CloseDevice(_THIS)
|
static void DISKAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (_this->hidden->io != NULL) {
|
if (_this->hidden->io != NULL) {
|
||||||
SDL_RWclose(_this->hidden->io);
|
SDL_RWclose(_this->hidden->io);
|
||||||
@@ -113,7 +113,7 @@ static const char *get_filename(const SDL_bool iscapture, const char *devname)
|
|||||||
return devname;
|
return devname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
static int DISKAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
void *handle = _this->handle;
|
void *handle = _this->handle;
|
||||||
/* handle != NULL means "user specified the placeholder name on the fake detected device list" */
|
/* handle != NULL means "user specified the placeholder name on the fake detected device list" */
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The file descriptor for the audio device */
|
/* The file descriptor for the audio device */
|
||||||
|
|||||||
@@ -45,18 +45,18 @@ static void DSP_DetectDevices(void)
|
|||||||
SDL_EnumUnixAudioDevices(0, NULL);
|
SDL_EnumUnixAudioDevices(0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSP_CloseDevice(_THIS)
|
static void DSP_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->audio_fd >= 0) {
|
if (_this->hidden->audio_fd >= 0) {
|
||||||
close(this->hidden->audio_fd);
|
close(_this->hidden->audio_fd);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSP_OpenDevice(_THIS, const char *devname)
|
static int DSP_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||||
int format = 0;
|
int format = 0;
|
||||||
int value;
|
int value;
|
||||||
@@ -75,45 +75,45 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
/* Make sure fragment size stays a power of 2, or OSS fails. */
|
/* Make sure fragment size stays a power of 2, or OSS fails. */
|
||||||
/* I don't know which of these are actually legal values, though... */
|
/* I don't know which of these are actually legal values, though... */
|
||||||
if (this->spec.channels > 8) {
|
if (_this->spec.channels > 8) {
|
||||||
this->spec.channels = 8;
|
_this->spec.channels = 8;
|
||||||
} else if (this->spec.channels > 4) {
|
} else if (_this->spec.channels > 4) {
|
||||||
this->spec.channels = 4;
|
_this->spec.channels = 4;
|
||||||
} else if (this->spec.channels > 2) {
|
} else if (_this->spec.channels > 2) {
|
||||||
this->spec.channels = 2;
|
_this->spec.channels = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* Open the audio device */
|
/* Open the audio device */
|
||||||
this->hidden->audio_fd = open(devname, flags | O_CLOEXEC, 0);
|
_this->hidden->audio_fd = open(devname, flags | O_CLOEXEC, 0);
|
||||||
if (this->hidden->audio_fd < 0) {
|
if (_this->hidden->audio_fd < 0) {
|
||||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the file descriptor use blocking i/o with fcntl() */
|
/* Make the file descriptor use blocking i/o with fcntl() */
|
||||||
{
|
{
|
||||||
long ctlflags;
|
long ctlflags;
|
||||||
ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
|
ctlflags = fcntl(_this->hidden->audio_fd, F_GETFL);
|
||||||
ctlflags &= ~O_NONBLOCK;
|
ctlflags &= ~O_NONBLOCK;
|
||||||
if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
|
if (fcntl(_this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
|
||||||
return SDL_SetError("Couldn't set audio blocking mode");
|
return SDL_SetError("Couldn't set audio blocking mode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a list of supported hardware formats */
|
/* Get a list of supported hardware formats */
|
||||||
if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
|
if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
|
||||||
perror("SNDCTL_DSP_GETFMTS");
|
perror("SNDCTL_DSP_GETFMTS");
|
||||||
return SDL_SetError("Couldn't get audio format list");
|
return SDL_SetError("Couldn't get audio format list");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try for a closest match on audio format */
|
/* Try for a closest match on audio format */
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||||
@@ -153,39 +153,39 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||||||
if (format == 0) {
|
if (format == 0) {
|
||||||
return SDL_SetError("Couldn't find any hardware audio formats");
|
return SDL_SetError("Couldn't find any hardware audio formats");
|
||||||
}
|
}
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
|
|
||||||
/* Set the audio format */
|
/* Set the audio format */
|
||||||
value = format;
|
value = format;
|
||||||
if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
|
if ((ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
|
||||||
(value != format)) {
|
(value != format)) {
|
||||||
perror("SNDCTL_DSP_SETFMT");
|
perror("SNDCTL_DSP_SETFMT");
|
||||||
return SDL_SetError("Couldn't set audio format");
|
return SDL_SetError("Couldn't set audio format");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the number of channels of output */
|
/* Set the number of channels of output */
|
||||||
value = this->spec.channels;
|
value = _this->spec.channels;
|
||||||
if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
|
if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
|
||||||
perror("SNDCTL_DSP_CHANNELS");
|
perror("SNDCTL_DSP_CHANNELS");
|
||||||
return SDL_SetError("Cannot set the number of channels");
|
return SDL_SetError("Cannot set the number of channels");
|
||||||
}
|
}
|
||||||
this->spec.channels = value;
|
_this->spec.channels = value;
|
||||||
|
|
||||||
/* Set the DSP frequency */
|
/* Set the DSP frequency */
|
||||||
value = this->spec.freq;
|
value = _this->spec.freq;
|
||||||
if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
|
if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
|
||||||
perror("SNDCTL_DSP_SPEED");
|
perror("SNDCTL_DSP_SPEED");
|
||||||
return SDL_SetError("Couldn't set audio frequency");
|
return SDL_SetError("Couldn't set audio frequency");
|
||||||
}
|
}
|
||||||
this->spec.freq = value;
|
_this->spec.freq = value;
|
||||||
|
|
||||||
/* Calculate the final parameters for this audio specification */
|
/* Calculate the final parameters for this audio specification */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Determine the power of two of the fragment size */
|
/* Determine the power of two of the fragment size */
|
||||||
for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec) {
|
for (frag_spec = 0; (0x01U << frag_spec) < _this->spec.size; ++frag_spec) {
|
||||||
}
|
}
|
||||||
if ((0x01U << frag_spec) != this->spec.size) {
|
if ((0x01U << frag_spec) != _this->spec.size) {
|
||||||
return SDL_SetError("Fragment size must be a power of two");
|
return SDL_SetError("Fragment size must be a power of two");
|
||||||
}
|
}
|
||||||
frag_spec |= 0x00020000; /* two fragments, for low latency */
|
frag_spec |= 0x00020000; /* two fragments, for low latency */
|
||||||
@@ -195,13 +195,13 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||||||
fprintf(stderr, "Requesting %d fragments of size %d\n",
|
fprintf(stderr, "Requesting %d fragments of size %d\n",
|
||||||
(frag_spec >> 16), 1 << (frag_spec & 0xFFFF));
|
(frag_spec >> 16), 1 << (frag_spec & 0xFFFF));
|
||||||
#endif
|
#endif
|
||||||
if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
|
if (ioctl(_this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
|
||||||
perror("SNDCTL_DSP_SETFRAGMENT");
|
perror("SNDCTL_DSP_SETFRAGMENT");
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
{
|
{
|
||||||
audio_buf_info info;
|
audio_buf_info info;
|
||||||
ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info);
|
ioctl(_this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info);
|
||||||
fprintf(stderr, "fragments = %d\n", info.fragments);
|
fprintf(stderr, "fragments = %d\n", info.fragments);
|
||||||
fprintf(stderr, "fragstotal = %d\n", info.fragstotal);
|
fprintf(stderr, "fragstotal = %d\n", info.fragstotal);
|
||||||
fprintf(stderr, "fragsize = %d\n", info.fragsize);
|
fprintf(stderr, "fragsize = %d\n", info.fragsize);
|
||||||
@@ -211,43 +211,43 @@ static int DSP_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
if (!iscapture) {
|
if (!iscapture) {
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen);
|
||||||
if (this->hidden->mixbuf == NULL) {
|
if (_this->hidden->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're ready to rock and roll. :-) */
|
/* We're ready to rock and roll. :-) */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSP_PlayDevice(_THIS)
|
static void DSP_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) {
|
if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) {
|
||||||
perror("Audio write");
|
perror("Audio write");
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen);
|
fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *DSP_GetDeviceBuf(_THIS)
|
static Uint8 *DSP_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSP_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int DSP_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
return (int)read(this->hidden->audio_fd, buffer, buflen);
|
return (int)read(_this->hidden->audio_fd, buffer, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSP_FlushCapture(_THIS)
|
static void DSP_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
audio_buf_info info;
|
audio_buf_info info;
|
||||||
if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) {
|
if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) {
|
||||||
while (info.bytes > 0) {
|
while (info.bytes > 0) {
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The file descriptor for the audio device */
|
/* The file descriptor for the audio device */
|
||||||
|
|||||||
@@ -25,14 +25,14 @@
|
|||||||
#include "../SDL_audio_c.h"
|
#include "../SDL_audio_c.h"
|
||||||
#include "SDL_dummyaudio.h"
|
#include "SDL_dummyaudio.h"
|
||||||
|
|
||||||
static int DUMMYAUDIO_OpenDevice(_THIS, const char *devname)
|
static int DUMMYAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
_this->hidden = (void *)0x1; /* just something non-NULL */
|
_this->hidden = (void *)0x1; /* just something non-NULL */
|
||||||
|
|
||||||
return 0; /* always succeeds. */
|
return 0; /* always succeeds. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int DUMMYAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
/* Delay to make this sort of simulate real audio input. */
|
/* Delay to make this sort of simulate real audio input. */
|
||||||
SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq);
|
SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq);
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The file descriptor for the audio device */
|
/* The file descriptor for the audio device */
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
!!! FIXME: true always once pthread support becomes widespread. Revisit this code
|
!!! FIXME: true always once pthread support becomes widespread. Revisit this code
|
||||||
!!! FIXME: at some point and see what needs to be done for that! */
|
!!! FIXME: at some point and see what needs to be done for that! */
|
||||||
|
|
||||||
static void FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
static void FeedAudioDevice(SDL_AudioDevice *_this, const void *buf, const int buflen)
|
||||||
{
|
{
|
||||||
const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
|
const int framelen = (SDL_AUDIO_BITSIZE(_this->spec.format) / 8) * _this->spec.channels;
|
||||||
/* *INDENT-OFF* */ /* clang-format off */
|
/* *INDENT-OFF* */ /* clang-format off */
|
||||||
MAIN_THREAD_EM_ASM({
|
MAIN_THREAD_EM_ASM({
|
||||||
var SDL3 = Module['SDL3'];
|
var SDL3 = Module['SDL3'];
|
||||||
@@ -53,54 +53,54 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
|||||||
/* *INDENT-ON* */ /* clang-format on */
|
/* *INDENT-ON* */ /* clang-format on */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleAudioProcess(_THIS)
|
static void HandleAudioProcess(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_AudioCallback callback = this->callbackspec.callback;
|
SDL_AudioCallback callback = _this->callbackspec.callback;
|
||||||
const int stream_len = this->callbackspec.size;
|
const int stream_len = _this->callbackspec.size;
|
||||||
|
|
||||||
/* Only do something if audio is enabled */
|
/* Only do something if audio is enabled */
|
||||||
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
|
if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) {
|
||||||
if (this->stream) {
|
if (_this->stream) {
|
||||||
SDL_ClearAudioStream(this->stream);
|
SDL_ClearAudioStream(_this->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset(this->work_buffer, this->spec.silence, this->spec.size);
|
SDL_memset(_this->work_buffer, _this->spec.silence, _this->spec.size);
|
||||||
FeedAudioDevice(this, this->work_buffer, this->spec.size);
|
FeedAudioDevice(_this, _this->work_buffer, _this->spec.size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->stream == NULL) { /* no conversion necessary. */
|
if (_this->stream == NULL) { /* no conversion necessary. */
|
||||||
SDL_assert(this->spec.size == stream_len);
|
SDL_assert(_this->spec.size == stream_len);
|
||||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
|
||||||
} else { /* streaming/converting */
|
} else { /* streaming/converting */
|
||||||
int got;
|
int got;
|
||||||
while (SDL_GetAudioStreamAvailable(this->stream) < ((int)this->spec.size)) {
|
while (SDL_GetAudioStreamAvailable(_this->stream) < ((int)_this->spec.size)) {
|
||||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
|
||||||
if (SDL_PutAudioStreamData(this->stream, this->work_buffer, stream_len) == -1) {
|
if (SDL_PutAudioStreamData(_this->stream, _this->work_buffer, stream_len) == -1) {
|
||||||
SDL_ClearAudioStream(this->stream);
|
SDL_ClearAudioStream(_this->stream);
|
||||||
SDL_AtomicSet(&this->enabled, 0);
|
SDL_AtomicSet(&_this->enabled, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
got = SDL_GetAudioStreamData(this->stream, this->work_buffer, this->spec.size);
|
got = SDL_GetAudioStreamData(_this->stream, _this->work_buffer, _this->spec.size);
|
||||||
SDL_assert((got < 0) || (got == this->spec.size));
|
SDL_assert((got < 0) || (got == _this->spec.size));
|
||||||
if (got != this->spec.size) {
|
if (got != _this->spec.size) {
|
||||||
SDL_memset(this->work_buffer, this->spec.silence, this->spec.size);
|
SDL_memset(_this->work_buffer, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedAudioDevice(this, this->work_buffer, this->spec.size);
|
FeedAudioDevice(_this, _this->work_buffer, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleCaptureProcess(_THIS)
|
static void HandleCaptureProcess(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_AudioCallback callback = this->callbackspec.callback;
|
SDL_AudioCallback callback = _this->callbackspec.callback;
|
||||||
const int stream_len = this->callbackspec.size;
|
const int stream_len = _this->callbackspec.size;
|
||||||
|
|
||||||
/* Only do something if audio is enabled */
|
/* Only do something if audio is enabled */
|
||||||
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
|
if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) {
|
||||||
SDL_ClearAudioStream(this->stream);
|
SDL_ClearAudioStream(_this->stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,31 +124,31 @@ static void HandleCaptureProcess(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, this->work_buffer, (this->spec.size / sizeof(float)) / this->spec.channels);
|
}, _this->work_buffer, (_this->spec.size / sizeof(float)) / _this->spec.channels);
|
||||||
/* *INDENT-ON* */ /* clang-format on */
|
/* *INDENT-ON* */ /* clang-format on */
|
||||||
|
|
||||||
/* okay, we've got an interleaved float32 array in C now. */
|
/* okay, we've got an interleaved float32 array in C now. */
|
||||||
|
|
||||||
if (this->stream == NULL) { /* no conversion necessary. */
|
if (_this->stream == NULL) { /* no conversion necessary. */
|
||||||
SDL_assert(this->spec.size == stream_len);
|
SDL_assert(_this->spec.size == stream_len);
|
||||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
|
||||||
} else { /* streaming/converting */
|
} else { /* streaming/converting */
|
||||||
if (SDL_PutAudioStreamData(this->stream, this->work_buffer, this->spec.size) == -1) {
|
if (SDL_PutAudioStreamData(_this->stream, _this->work_buffer, _this->spec.size) == -1) {
|
||||||
SDL_AtomicSet(&this->enabled, 0);
|
SDL_AtomicSet(&_this->enabled, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (SDL_GetAudioStreamAvailable(this->stream) >= stream_len) {
|
while (SDL_GetAudioStreamAvailable(_this->stream) >= stream_len) {
|
||||||
const int got = SDL_GetAudioStreamData(this->stream, this->work_buffer, stream_len);
|
const int got = SDL_GetAudioStreamData(_this->stream, _this->work_buffer, stream_len);
|
||||||
SDL_assert((got < 0) || (got == stream_len));
|
SDL_assert((got < 0) || (got == stream_len));
|
||||||
if (got != stream_len) {
|
if (got != stream_len) {
|
||||||
SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len);
|
SDL_memset(_this->work_buffer, _this->callbackspec.silence, stream_len);
|
||||||
}
|
}
|
||||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */
|
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); /* Send it to the app. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
static void EMSCRIPTENAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* *INDENT-OFF* */ /* clang-format off */
|
/* *INDENT-OFF* */ /* clang-format off */
|
||||||
MAIN_THREAD_EM_ASM({
|
MAIN_THREAD_EM_ASM({
|
||||||
@@ -188,19 +188,19 @@ static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
|||||||
SDL3.audioContext.close();
|
SDL3.audioContext.close();
|
||||||
SDL3.audioContext = undefined;
|
SDL3.audioContext = undefined;
|
||||||
}
|
}
|
||||||
}, this->iscapture);
|
}, _this->iscapture);
|
||||||
/* *INDENT-ON* */ /* clang-format on */
|
/* *INDENT-ON* */ /* clang-format on */
|
||||||
|
|
||||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* based on parts of library_sdl.js */
|
/* based on parts of library_sdl.js */
|
||||||
@@ -236,7 +236,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("Web Audio API is not available!");
|
return SDL_SetError("Web Audio API is not available!");
|
||||||
}
|
}
|
||||||
|
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
case SDL_AUDIO_F32: /* web audio only supports floats */
|
case SDL_AUDIO_F32: /* web audio only supports floats */
|
||||||
@@ -251,25 +251,25 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
/* Didn't find a compatible format :( */
|
/* Didn't find a compatible format :( */
|
||||||
return SDL_SetError("%s: Unsupported audio format", "emscripten");
|
return SDL_SetError("%s: Unsupported audio format", "emscripten");
|
||||||
}
|
}
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
#endif
|
#endif
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)0x1;
|
_this->hidden = (struct SDL_PrivateAudioData *)0x1;
|
||||||
|
|
||||||
/* limit to native freq */
|
/* limit to native freq */
|
||||||
this->spec.freq = EM_ASM_INT({
|
_this->spec.freq = EM_ASM_INT({
|
||||||
var SDL3 = Module['SDL3'];
|
var SDL3 = Module['SDL3'];
|
||||||
return SDL3.audioContext.sampleRate;
|
return SDL3.audioContext.sampleRate;
|
||||||
});
|
});
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* *INDENT-OFF* */ /* clang-format off */
|
/* *INDENT-OFF* */ /* clang-format off */
|
||||||
if (iscapture) {
|
if (iscapture) {
|
||||||
@@ -329,7 +329,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
} else if (navigator.webkitGetUserMedia !== undefined) {
|
} else if (navigator.webkitGetUserMedia !== undefined) {
|
||||||
navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone);
|
navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone);
|
||||||
}
|
}
|
||||||
}, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
|
}, _this->spec.channels, _this->spec.samples, HandleCaptureProcess, _this);
|
||||||
} else {
|
} else {
|
||||||
/* setup a ScriptProcessorNode */
|
/* setup a ScriptProcessorNode */
|
||||||
MAIN_THREAD_EM_ASM({
|
MAIN_THREAD_EM_ASM({
|
||||||
@@ -341,7 +341,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
dynCall('vi', $2, [$3]);
|
dynCall('vi', $2, [$3]);
|
||||||
};
|
};
|
||||||
SDL3.audio.scriptProcessorNode['connect'](SDL3.audioContext['destination']);
|
SDL3.audio.scriptProcessorNode['connect'](SDL3.audioContext['destination']);
|
||||||
}, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
|
}, _this->spec.channels, _this->spec.samples, HandleAudioProcess, _this);
|
||||||
}
|
}
|
||||||
/* *INDENT-ON* */ /* clang-format on */
|
/* *INDENT-ON* */ /* clang-format on */
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
int unused;
|
int unused;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ static void FillSound(void *device, void *stream, size_t len,
|
|||||||
SDL_UnlockMutex(audio->mixer_lock);
|
SDL_UnlockMutex(audio->mixer_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HAIKUAUDIO_CloseDevice(_THIS)
|
static void HAIKUAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (_this->hidden->audio_obj) {
|
if (_this->hidden->audio_obj) {
|
||||||
_this->hidden->audio_obj->Stop();
|
_this->hidden->audio_obj->Stop();
|
||||||
@@ -115,7 +115,7 @@ static inline void UnmaskSignals(sigset_t * omask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
|
static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
media_raw_audio_format format;
|
media_raw_audio_format format;
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
BSoundPlayer *audio_obj;
|
BSoundPlayer *audio_obj;
|
||||||
|
|||||||
@@ -135,9 +135,9 @@ static int load_jack_syms(void)
|
|||||||
|
|
||||||
static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */
|
static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */
|
||||||
{
|
{
|
||||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)arg;
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
SDL_PostSemaphore(this->hidden->iosem); /* unblock the SDL thread. */
|
SDL_PostSemaphore(_this->hidden->iosem); /* unblock the SDL thread. */
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! FIXME: implement and register these!
|
// !!! FIXME: implement and register these!
|
||||||
@@ -146,21 +146,21 @@ static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. *
|
|||||||
|
|
||||||
static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
||||||
{
|
{
|
||||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)arg;
|
||||||
jack_port_t **ports = this->hidden->sdlports;
|
jack_port_t **ports = _this->hidden->sdlports;
|
||||||
const int total_channels = this->spec.channels;
|
const int total_channels = _this->spec.channels;
|
||||||
const int total_frames = this->spec.samples;
|
const int total_frames = _this->spec.samples;
|
||||||
int channelsi;
|
int channelsi;
|
||||||
|
|
||||||
if (!SDL_AtomicGet(&this->enabled)) {
|
if (!SDL_AtomicGet(&_this->enabled)) {
|
||||||
/* silence the buffer to avoid repeats and corruption. */
|
/* silence the buffer to avoid repeats and corruption. */
|
||||||
SDL_memset(this->hidden->iobuffer, '\0', this->spec.size);
|
SDL_memset(_this->hidden->iobuffer, '\0', _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
||||||
float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||||
if (dst) {
|
if (dst) {
|
||||||
const float *src = this->hidden->iobuffer + channelsi;
|
const float *src = _this->hidden->iobuffer + channelsi;
|
||||||
int framesi;
|
int framesi;
|
||||||
for (framesi = 0; framesi < total_frames; framesi++) {
|
for (framesi = 0; framesi < total_frames; framesi++) {
|
||||||
*(dst++) = *src;
|
*(dst++) = *src;
|
||||||
@@ -169,38 +169,38 @@ static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_PostSemaphore(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */
|
SDL_PostSemaphore(_this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void JACK_WaitDevice(_THIS)
|
static void JACK_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (SDL_AtomicGet(&this->enabled)) {
|
if (SDL_AtomicGet(&_this->enabled)) {
|
||||||
if (SDL_WaitSemaphore(this->hidden->iosem) == -1) {
|
if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *JACK_GetDeviceBuf(_THIS)
|
static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return (Uint8 *)this->hidden->iobuffer;
|
return (Uint8 *)_this->hidden->iobuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
||||||
{
|
{
|
||||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)arg;
|
||||||
if (SDL_AtomicGet(&this->enabled)) {
|
if (SDL_AtomicGet(&_this->enabled)) {
|
||||||
jack_port_t **ports = this->hidden->sdlports;
|
jack_port_t **ports = _this->hidden->sdlports;
|
||||||
const int total_channels = this->spec.channels;
|
const int total_channels = _this->spec.channels;
|
||||||
const int total_frames = this->spec.samples;
|
const int total_frames = _this->spec.samples;
|
||||||
int channelsi;
|
int channelsi;
|
||||||
|
|
||||||
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
||||||
const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||||
if (src) {
|
if (src) {
|
||||||
float *dst = this->hidden->iobuffer + channelsi;
|
float *dst = _this->hidden->iobuffer + channelsi;
|
||||||
int framesi;
|
int framesi;
|
||||||
for (framesi = 0; framesi < total_frames; framesi++) {
|
for (framesi = 0; framesi < total_frames; framesi++) {
|
||||||
*dst = *(src++);
|
*dst = *(src++);
|
||||||
@@ -210,60 +210,60 @@ static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_PostSemaphore(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */
|
SDL_PostSemaphore(_this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int JACK_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */
|
SDL_assert(buflen == _this->spec.size); /* we always fill a full buffer. */
|
||||||
|
|
||||||
/* Wait for JACK to fill the iobuffer */
|
/* Wait for JACK to fill the iobuffer */
|
||||||
if (SDL_WaitSemaphore(this->hidden->iosem) == -1) {
|
if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memcpy(buffer, this->hidden->iobuffer, buflen);
|
SDL_memcpy(buffer, _this->hidden->iobuffer, buflen);
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JACK_FlushCapture(_THIS)
|
static void JACK_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_WaitSemaphore(this->hidden->iosem);
|
SDL_WaitSemaphore(_this->hidden->iosem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JACK_CloseDevice(_THIS)
|
static void JACK_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->client) {
|
if (_this->hidden->client) {
|
||||||
JACK_jack_deactivate(this->hidden->client);
|
JACK_jack_deactivate(_this->hidden->client);
|
||||||
|
|
||||||
if (this->hidden->sdlports) {
|
if (_this->hidden->sdlports) {
|
||||||
const int channels = this->spec.channels;
|
const int channels = _this->spec.channels;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < channels; i++) {
|
for (i = 0; i < channels; i++) {
|
||||||
JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[i]);
|
JACK_jack_port_unregister(_this->hidden->client, _this->hidden->sdlports[i]);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->sdlports);
|
SDL_free(_this->hidden->sdlports);
|
||||||
}
|
}
|
||||||
|
|
||||||
JACK_jack_client_close(this->hidden->client);
|
JACK_jack_client_close(_this->hidden->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->iosem) {
|
if (_this->hidden->iosem) {
|
||||||
SDL_DestroySemaphore(this->hidden->iosem);
|
SDL_DestroySemaphore(_this->hidden->iosem);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden->iobuffer);
|
SDL_free(_this->hidden->iobuffer);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int JACK_OpenDevice(_THIS, const char *devname)
|
static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
/* Note that JACK uses "output" for capture devices (they output audio
|
/* Note that JACK uses "output" for capture devices (they output audio
|
||||||
data to us) and "input" for playback (we input audio data to them).
|
data to us) and "input" for playback (we input audio data to them).
|
||||||
Likewise, SDL's playback port will be "output" (we write data out)
|
Likewise, SDL's playback port will be "output" (we write data out)
|
||||||
and capture will be "input" (we read data in). */
|
and capture will be "input" (we read data in). */
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
|
const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
|
||||||
const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
|
const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
|
||||||
const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
|
const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
|
||||||
@@ -277,14 +277,14 @@ static int JACK_OpenDevice(_THIS, const char *devname)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !!! FIXME: we _still_ need an API to specify an app name */
|
/* !!! FIXME: we _still_ need an API to specify an app name */
|
||||||
client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
|
client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
|
||||||
this->hidden->client = client;
|
_this->hidden->client = client;
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
return SDL_SetError("Can't open JACK client");
|
return SDL_SetError("Can't open JACK client");
|
||||||
}
|
}
|
||||||
@@ -317,28 +317,28 @@ static int JACK_OpenDevice(_THIS, const char *devname)
|
|||||||
/* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */
|
/* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */
|
||||||
|
|
||||||
/* Jack pretty much demands what it wants. */
|
/* Jack pretty much demands what it wants. */
|
||||||
this->spec.format = SDL_AUDIO_F32SYS;
|
_this->spec.format = SDL_AUDIO_F32SYS;
|
||||||
this->spec.freq = JACK_jack_get_sample_rate(client);
|
_this->spec.freq = JACK_jack_get_sample_rate(client);
|
||||||
this->spec.channels = channels;
|
_this->spec.channels = channels;
|
||||||
this->spec.samples = JACK_jack_get_buffer_size(client);
|
_this->spec.samples = JACK_jack_get_buffer_size(client);
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
this->hidden->iosem = SDL_CreateSemaphore(0);
|
_this->hidden->iosem = SDL_CreateSemaphore(0);
|
||||||
if (!this->hidden->iosem) {
|
if (!_this->hidden->iosem) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
return -1; /* error was set by SDL_CreateSemaphore */
|
return -1; /* error was set by SDL_CreateSemaphore */
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->iobuffer = (float *)SDL_calloc(1, this->spec.size);
|
_this->hidden->iobuffer = (float *)SDL_calloc(1, _this->spec.size);
|
||||||
if (!this->hidden->iobuffer) {
|
if (!_this->hidden->iobuffer) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build SDL's ports, which we will connect to the device ports. */
|
/* Build SDL's ports, which we will connect to the device ports. */
|
||||||
this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
|
_this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
|
||||||
if (this->hidden->sdlports == NULL) {
|
if (_this->hidden->sdlports == NULL) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
@@ -346,19 +346,19 @@ static int JACK_OpenDevice(_THIS, const char *devname)
|
|||||||
for (i = 0; i < channels; i++) {
|
for (i = 0; i < channels; i++) {
|
||||||
char portname[32];
|
char portname[32];
|
||||||
(void)SDL_snprintf(portname, sizeof(portname), "sdl_jack_%s_%d", sdlportstr, i);
|
(void)SDL_snprintf(portname, sizeof(portname), "sdl_jack_%s_%d", sdlportstr, i);
|
||||||
this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
|
_this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
|
||||||
if (this->hidden->sdlports[i] == NULL) {
|
if (_this->hidden->sdlports[i] == NULL) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
return SDL_SetError("jack_port_register failed");
|
return SDL_SetError("jack_port_register failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JACK_jack_set_process_callback(client, callback, this) != 0) {
|
if (JACK_jack_set_process_callback(client, callback, _this) != 0) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
return SDL_SetError("JACK: Couldn't set process callback");
|
return SDL_SetError("JACK: Couldn't set process callback");
|
||||||
}
|
}
|
||||||
|
|
||||||
JACK_jack_on_shutdown(client, jackShutdownCallback, this);
|
JACK_jack_on_shutdown(client, jackShutdownCallback, _this);
|
||||||
|
|
||||||
if (JACK_jack_activate(client) != 0) {
|
if (JACK_jack_activate(client) != 0) {
|
||||||
SDL_free(audio_ports);
|
SDL_free(audio_ports);
|
||||||
@@ -367,7 +367,7 @@ static int JACK_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
/* once activated, we can connect all the ports. */
|
/* once activated, we can connect all the ports. */
|
||||||
for (i = 0; i < channels; i++) {
|
for (i = 0; i < channels; i++) {
|
||||||
const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
|
const char *sdlport = JACK_jack_port_name(_this->hidden->sdlports[i]);
|
||||||
const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
|
const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
|
||||||
const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
|
const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
|
||||||
if (JACK_jack_connect(client, srcport, dstport) != 0) {
|
if (JACK_jack_connect(client, srcport, dstport) != 0) {
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
jack_client_t *client;
|
jack_client_t *client;
|
||||||
|
|||||||
@@ -32,27 +32,27 @@
|
|||||||
static dspHookCookie dsp_hook;
|
static dspHookCookie dsp_hook;
|
||||||
static SDL_AudioDevice *audio_device;
|
static SDL_AudioDevice *audio_device;
|
||||||
|
|
||||||
static void FreePrivateData(_THIS);
|
static void FreePrivateData(SDL_AudioDevice *_this);
|
||||||
static int FindAudioFormat(_THIS);
|
static int FindAudioFormat(SDL_AudioDevice *_this);
|
||||||
|
|
||||||
static SDL_INLINE void contextLock(_THIS)
|
static SDL_INLINE void contextLock(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
LightLock_Lock(&this->hidden->lock);
|
LightLock_Lock(&_this->hidden->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void contextUnlock(_THIS)
|
static SDL_INLINE void contextUnlock(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
LightLock_Unlock(&this->hidden->lock);
|
LightLock_Unlock(&_this->hidden->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUD_LockAudio(_THIS)
|
static void N3DSAUD_LockAudio(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
contextLock(this);
|
contextLock(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUD_UnlockAudio(_THIS)
|
static void N3DSAUD_UnlockAudio(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUD_DspHook(DSP_HookType hook)
|
static void N3DSAUD_DspHook(DSP_HookType hook)
|
||||||
@@ -70,32 +70,32 @@ static void AudioFrameFinished(void *device)
|
|||||||
{
|
{
|
||||||
bool shouldBroadcast = false;
|
bool shouldBroadcast = false;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
SDL_AudioDevice *this = (SDL_AudioDevice *)device;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)device;
|
||||||
|
|
||||||
contextLock(this);
|
contextLock(_this);
|
||||||
|
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
if (this->hidden->waveBuf[i].status == NDSP_WBUF_DONE) {
|
if (_this->hidden->waveBuf[i].status == NDSP_WBUF_DONE) {
|
||||||
this->hidden->waveBuf[i].status = NDSP_WBUF_FREE;
|
_this->hidden->waveBuf[i].status = NDSP_WBUF_FREE;
|
||||||
shouldBroadcast = SDL_TRUE;
|
shouldBroadcast = SDL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldBroadcast) {
|
if (shouldBroadcast) {
|
||||||
CondVar_Broadcast(&this->hidden->cv);
|
CondVar_Broadcast(&_this->hidden->cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
static int N3DSAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
Result ndsp_init_res;
|
Result ndsp_init_res;
|
||||||
Uint8 *data_vaddr;
|
Uint8 *data_vaddr;
|
||||||
float mix[12];
|
float mix[12];
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
|
||||||
|
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,145 +111,145 @@ static int N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise internal state */
|
/* Initialise internal state */
|
||||||
LightLock_Init(&this->hidden->lock);
|
LightLock_Init(&_this->hidden->lock);
|
||||||
CondVar_Init(&this->hidden->cv);
|
CondVar_Init(&_this->hidden->cv);
|
||||||
|
|
||||||
if (this->spec.channels > 2) {
|
if (_this->spec.channels > 2) {
|
||||||
this->spec.channels = 2;
|
_this->spec.channels = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should not happen but better be safe. */
|
/* Should not happen but better be safe. */
|
||||||
if (FindAudioFormat(this) < 0) {
|
if (FindAudioFormat(_this) < 0) {
|
||||||
return SDL_SetError("No supported audio format found.");
|
return SDL_SetError("No supported audio format found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes */
|
/* Update the fragment size as size in bytes */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
if (this->spec.size >= SDL_MAX_UINT32 / 2) {
|
if (_this->spec.size >= SDL_MAX_UINT32 / 2) {
|
||||||
return SDL_SetError("Mixing buffer is too large.");
|
return SDL_SetError("Mixing buffer is too large.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->spec.size);
|
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->spec.size);
|
||||||
if (this->hidden->mixbuf == NULL) {
|
if (_this->hidden->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size);
|
||||||
|
|
||||||
data_vaddr = (Uint8 *)linearAlloc(this->hidden->mixlen * NUM_BUFFERS);
|
data_vaddr = (Uint8 *)linearAlloc(_this->hidden->mixlen * NUM_BUFFERS);
|
||||||
if (data_vaddr == NULL) {
|
if (data_vaddr == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset(data_vaddr, 0, this->hidden->mixlen * NUM_BUFFERS);
|
SDL_memset(data_vaddr, 0, _this->hidden->mixlen * NUM_BUFFERS);
|
||||||
DSP_FlushDataCache(data_vaddr, this->hidden->mixlen * NUM_BUFFERS);
|
DSP_FlushDataCache(data_vaddr, _this->hidden->mixlen * NUM_BUFFERS);
|
||||||
|
|
||||||
this->hidden->nextbuf = 0;
|
_this->hidden->nextbuf = 0;
|
||||||
this->hidden->channels = this->spec.channels;
|
_this->hidden->channels = _this->spec.channels;
|
||||||
this->hidden->samplerate = this->spec.freq;
|
_this->hidden->samplerate = _this->spec.freq;
|
||||||
|
|
||||||
ndspChnReset(0);
|
ndspChnReset(0);
|
||||||
|
|
||||||
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
||||||
ndspChnSetRate(0, this->spec.freq);
|
ndspChnSetRate(0, _this->spec.freq);
|
||||||
ndspChnSetFormat(0, this->hidden->format);
|
ndspChnSetFormat(0, _this->hidden->format);
|
||||||
|
|
||||||
SDL_memset(mix, 0, sizeof(mix));
|
SDL_memset(mix, 0, sizeof(mix));
|
||||||
mix[0] = 1.0;
|
mix[0] = 1.0;
|
||||||
mix[1] = 1.0;
|
mix[1] = 1.0;
|
||||||
ndspChnSetMix(0, mix);
|
ndspChnSetMix(0, mix);
|
||||||
|
|
||||||
SDL_memset(this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS);
|
SDL_memset(_this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS);
|
||||||
|
|
||||||
for (unsigned i = 0; i < NUM_BUFFERS; i++) {
|
for (unsigned i = 0; i < NUM_BUFFERS; i++) {
|
||||||
this->hidden->waveBuf[i].data_vaddr = data_vaddr;
|
_this->hidden->waveBuf[i].data_vaddr = data_vaddr;
|
||||||
this->hidden->waveBuf[i].nsamples = this->hidden->mixlen / this->hidden->bytePerSample;
|
_this->hidden->waveBuf[i].nsamples = _this->hidden->mixlen / _this->hidden->bytePerSample;
|
||||||
data_vaddr += this->hidden->mixlen;
|
data_vaddr += _this->hidden->mixlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup callback */
|
/* Setup callback */
|
||||||
audio_device = this;
|
audio_device = _this;
|
||||||
ndspSetCallback(AudioFrameFinished, this);
|
ndspSetCallback(AudioFrameFinished, _this);
|
||||||
dspHook(&dsp_hook, N3DSAUD_DspHook);
|
dspHook(&dsp_hook, N3DSAUD_DspHook);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int N3DSAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int N3DSAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
/* Delay to make this sort of simulate real audio input. */
|
/* Delay to make this sort of simulate real audio input. */
|
||||||
SDL_Delay((this->spec.samples * 1000) / this->spec.freq);
|
SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq);
|
||||||
|
|
||||||
/* always return a full buffer of silence. */
|
/* always return a full buffer of silence. */
|
||||||
SDL_memset(buffer, this->spec.silence, buflen);
|
SDL_memset(buffer, _this->spec.silence, buflen);
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUDIO_PlayDevice(_THIS)
|
static void N3DSAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
size_t nextbuf;
|
size_t nextbuf;
|
||||||
size_t sampleLen;
|
size_t sampleLen;
|
||||||
contextLock(this);
|
contextLock(_this);
|
||||||
|
|
||||||
nextbuf = this->hidden->nextbuf;
|
nextbuf = _this->hidden->nextbuf;
|
||||||
sampleLen = this->hidden->mixlen;
|
sampleLen = _this->hidden->mixlen;
|
||||||
|
|
||||||
if (this->hidden->isCancelled ||
|
if (_this->hidden->isCancelled ||
|
||||||
this->hidden->waveBuf[nextbuf].status != NDSP_WBUF_FREE) {
|
_this->hidden->waveBuf[nextbuf].status != NDSP_WBUF_FREE) {
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->nextbuf = (nextbuf + 1) % NUM_BUFFERS;
|
_this->hidden->nextbuf = (nextbuf + 1) % NUM_BUFFERS;
|
||||||
|
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
|
|
||||||
memcpy((void *)this->hidden->waveBuf[nextbuf].data_vaddr,
|
memcpy((void *)_this->hidden->waveBuf[nextbuf].data_vaddr,
|
||||||
this->hidden->mixbuf, sampleLen);
|
_this->hidden->mixbuf, sampleLen);
|
||||||
DSP_FlushDataCache(this->hidden->waveBuf[nextbuf].data_vaddr, sampleLen);
|
DSP_FlushDataCache(_this->hidden->waveBuf[nextbuf].data_vaddr, sampleLen);
|
||||||
|
|
||||||
ndspChnWaveBufAdd(0, &this->hidden->waveBuf[nextbuf]);
|
ndspChnWaveBufAdd(0, &_this->hidden->waveBuf[nextbuf]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUDIO_WaitDevice(_THIS)
|
static void N3DSAUDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
contextLock(this);
|
contextLock(_this);
|
||||||
while (!this->hidden->isCancelled &&
|
while (!_this->hidden->isCancelled &&
|
||||||
this->hidden->waveBuf[this->hidden->nextbuf].status != NDSP_WBUF_FREE) {
|
_this->hidden->waveBuf[_this->hidden->nextbuf].status != NDSP_WBUF_FREE) {
|
||||||
CondVar_Wait(&this->hidden->cv, &this->hidden->lock);
|
CondVar_Wait(&_this->hidden->cv, &_this->hidden->lock);
|
||||||
}
|
}
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *N3DSAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *N3DSAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUDIO_CloseDevice(_THIS)
|
static void N3DSAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
contextLock(this);
|
contextLock(_this);
|
||||||
|
|
||||||
dspUnhook(&dsp_hook);
|
dspUnhook(&dsp_hook);
|
||||||
ndspSetCallback(NULL, NULL);
|
ndspSetCallback(NULL, NULL);
|
||||||
|
|
||||||
if (!this->hidden->isCancelled) {
|
if (!_this->hidden->isCancelled) {
|
||||||
ndspChnReset(0);
|
ndspChnReset(0);
|
||||||
memset(this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS);
|
memset(_this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS);
|
||||||
CondVar_Broadcast(&this->hidden->cv);
|
CondVar_Broadcast(&_this->hidden->cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
contextUnlock(this);
|
contextUnlock(_this);
|
||||||
|
|
||||||
ndspExit();
|
ndspExit();
|
||||||
|
|
||||||
FreePrivateData(this);
|
FreePrivateData(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUDIO_ThreadInit(_THIS)
|
static void N3DSAUDIO_ThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
s32 current_priority;
|
s32 current_priority;
|
||||||
svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE);
|
svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE);
|
||||||
@@ -289,43 +289,43 @@ AudioBootStrap N3DSAUDIO_bootstrap = {
|
|||||||
/**
|
/**
|
||||||
* Cleans up all allocated memory, safe to call with null pointers
|
* Cleans up all allocated memory, safe to call with null pointers
|
||||||
*/
|
*/
|
||||||
static void FreePrivateData(_THIS)
|
static void FreePrivateData(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (!this->hidden) {
|
if (!_this->hidden) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->waveBuf[0].data_vaddr) {
|
if (_this->hidden->waveBuf[0].data_vaddr) {
|
||||||
linearFree((void *)this->hidden->waveBuf[0].data_vaddr);
|
linearFree((void *)_this->hidden->waveBuf[0].data_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->mixbuf) {
|
if (_this->hidden->mixbuf) {
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
this->hidden->mixbuf = NULL;
|
_this->hidden->mixbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
this->hidden = NULL;
|
_this->hidden = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FindAudioFormat(_THIS)
|
static int FindAudioFormat(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
case SDL_AUDIO_S8:
|
case SDL_AUDIO_S8:
|
||||||
/* Signed 8-bit audio supported */
|
/* Signed 8-bit audio supported */
|
||||||
this->hidden->format = (this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM8 : NDSP_FORMAT_MONO_PCM8;
|
_this->hidden->format = (_this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM8 : NDSP_FORMAT_MONO_PCM8;
|
||||||
this->hidden->isSigned = 1;
|
_this->hidden->isSigned = 1;
|
||||||
this->hidden->bytePerSample = this->spec.channels;
|
_this->hidden->bytePerSample = _this->spec.channels;
|
||||||
return 0;
|
return 0;
|
||||||
case SDL_AUDIO_S16:
|
case SDL_AUDIO_S16:
|
||||||
/* Signed 16-bit audio supported */
|
/* Signed 16-bit audio supported */
|
||||||
this->hidden->format = (this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM16 : NDSP_FORMAT_MONO_PCM16;
|
_this->hidden->format = (_this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM16 : NDSP_FORMAT_MONO_PCM16;
|
||||||
this->hidden->isSigned = 1;
|
_this->hidden->isSigned = 1;
|
||||||
this->hidden->bytePerSample = this->spec.channels * 2;
|
_this->hidden->bytePerSample = _this->spec.channels * 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
|
|||||||
@@ -48,19 +48,19 @@ static void NETBSDAUDIO_DetectDevices(void)
|
|||||||
SDL_EnumUnixAudioDevices(0, NULL);
|
SDL_EnumUnixAudioDevices(0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NETBSDAUDIO_Status(_THIS)
|
static void NETBSDAUDIO_Status(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
/* *INDENT-OFF* */ /* clang-format off */
|
/* *INDENT-OFF* */ /* clang-format off */
|
||||||
audio_info_t info;
|
audio_info_t info;
|
||||||
const struct audio_prinfo *prinfo;
|
const struct audio_prinfo *prinfo;
|
||||||
|
|
||||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
||||||
fprintf(stderr, "AUDIO_GETINFO failed.\n");
|
fprintf(stderr, "AUDIO_GETINFO failed.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prinfo = this->iscapture ? &info.record : &info.play;
|
prinfo = _this->iscapture ? &info.record : &info.play;
|
||||||
|
|
||||||
fprintf(stderr, "\n"
|
fprintf(stderr, "\n"
|
||||||
"[%s info]\n"
|
"[%s info]\n"
|
||||||
@@ -77,7 +77,7 @@ static void NETBSDAUDIO_Status(_THIS)
|
|||||||
"waiting : %s\n"
|
"waiting : %s\n"
|
||||||
"active : %s\n"
|
"active : %s\n"
|
||||||
"",
|
"",
|
||||||
this->iscapture ? "record" : "play",
|
_this->iscapture ? "record" : "play",
|
||||||
prinfo->buffer_size,
|
prinfo->buffer_size,
|
||||||
prinfo->sample_rate,
|
prinfo->sample_rate,
|
||||||
prinfo->channels,
|
prinfo->channels,
|
||||||
@@ -111,23 +111,23 @@ static void NETBSDAUDIO_Status(_THIS)
|
|||||||
"format : 0x%x\n"
|
"format : 0x%x\n"
|
||||||
"size : %u\n"
|
"size : %u\n"
|
||||||
"",
|
"",
|
||||||
this->spec.format,
|
_this->spec.format,
|
||||||
this->spec.size);
|
_this->spec.size);
|
||||||
/* *INDENT-ON* */ /* clang-format on */
|
/* *INDENT-ON* */ /* clang-format on */
|
||||||
|
|
||||||
#endif /* DEBUG_AUDIO */
|
#endif /* DEBUG_AUDIO */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NETBSDAUDIO_PlayDevice(_THIS)
|
static void NETBSDAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
int written;
|
int written;
|
||||||
|
|
||||||
/* Write the audio data */
|
/* Write the audio data */
|
||||||
written = write(h->audio_fd, h->mixbuf, h->mixlen);
|
written = write(h->audio_fd, h->mixbuf, h->mixlen);
|
||||||
if (written == -1) {
|
if (written == -1) {
|
||||||
/* Non recoverable error has occurred. It should be reported!!! */
|
/* Non recoverable error has occurred. It should be reported!!! */
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
perror("audio");
|
perror("audio");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -137,17 +137,17 @@ static void NETBSDAUDIO_PlayDevice(_THIS)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *NETBSDAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *NETBSDAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
|
static int NETBSDAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *_buffer, int buflen)
|
||||||
{
|
{
|
||||||
Uint8 *buffer = (Uint8 *)_buffer;
|
Uint8 *buffer = (Uint8 *)_buffer;
|
||||||
int br;
|
int br;
|
||||||
|
|
||||||
br = read(this->hidden->audio_fd, buffer, buflen);
|
br = read(_this->hidden->audio_fd, buffer, buflen);
|
||||||
if (br == -1) {
|
if (br == -1) {
|
||||||
/* Non recoverable error has occurred. It should be reported!!! */
|
/* Non recoverable error has occurred. It should be reported!!! */
|
||||||
perror("audio");
|
perror("audio");
|
||||||
@@ -160,20 +160,20 @@ static int NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NETBSDAUDIO_FlushCapture(_THIS)
|
static void NETBSDAUDIO_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
audio_info_t info;
|
audio_info_t info;
|
||||||
size_t remain;
|
size_t remain;
|
||||||
Uint8 buf[512];
|
Uint8 buf[512];
|
||||||
|
|
||||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
||||||
return; /* oh well. */
|
return; /* oh well. */
|
||||||
}
|
}
|
||||||
|
|
||||||
remain = (size_t)(info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8));
|
remain = (size_t)(info.record.samples * (SDL_AUDIO_BITSIZE(_this->spec.format) / 8));
|
||||||
while (remain > 0) {
|
while (remain > 0) {
|
||||||
const size_t len = SDL_min(sizeof(buf), remain);
|
const size_t len = SDL_min(sizeof(buf), remain);
|
||||||
const int br = read(this->hidden->audio_fd, buf, len);
|
const int br = read(_this->hidden->audio_fd, buf, len);
|
||||||
if (br <= 0) {
|
if (br <= 0) {
|
||||||
return; /* oh well. */
|
return; /* oh well. */
|
||||||
}
|
}
|
||||||
@@ -181,18 +181,18 @@ static void NETBSDAUDIO_FlushCapture(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NETBSDAUDIO_CloseDevice(_THIS)
|
static void NETBSDAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->audio_fd >= 0) {
|
if (_this->hidden->audio_fd >= 0) {
|
||||||
close(this->hidden->audio_fd);
|
close(_this->hidden->audio_fd);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
static int NETBSDAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
int encoding = AUDIO_ENCODING_NONE;
|
int encoding = AUDIO_ENCODING_NONE;
|
||||||
@@ -209,34 +209,34 @@ static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* Open the audio device */
|
/* Open the audio device */
|
||||||
this->hidden->audio_fd = open(devname, (iscapture ? O_RDONLY : O_WRONLY) | O_CLOEXEC);
|
_this->hidden->audio_fd = open(devname, (iscapture ? O_RDONLY : O_WRONLY) | O_CLOEXEC);
|
||||||
if (this->hidden->audio_fd < 0) {
|
if (_this->hidden->audio_fd < 0) {
|
||||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
AUDIO_INITINFO(&info);
|
AUDIO_INITINFO(&info);
|
||||||
|
|
||||||
#ifdef AUDIO_GETFORMAT /* Introduced in NetBSD 9.0 */
|
#ifdef AUDIO_GETFORMAT /* Introduced in NetBSD 9.0 */
|
||||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) {
|
if (ioctl(_this->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) {
|
||||||
/*
|
/*
|
||||||
* Use the device's native sample rate so the kernel doesn't have to
|
* Use the device's native sample rate so the kernel doesn't have to
|
||||||
* resample.
|
* resample.
|
||||||
*/
|
*/
|
||||||
this->spec.freq = iscapture ? hwinfo.record.sample_rate : hwinfo.play.sample_rate;
|
_this->spec.freq = iscapture ? hwinfo.record.sample_rate : hwinfo.play.sample_rate;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prinfo->sample_rate = this->spec.freq;
|
prinfo->sample_rate = _this->spec.freq;
|
||||||
prinfo->channels = this->spec.channels;
|
prinfo->channels = _this->spec.channels;
|
||||||
|
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
case SDL_AUDIO_U8:
|
case SDL_AUDIO_U8:
|
||||||
@@ -271,32 +271,32 @@ static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
info.hiwat = 5;
|
info.hiwat = 5;
|
||||||
info.lowat = 3;
|
info.lowat = 3;
|
||||||
if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
|
if (ioctl(_this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
|
||||||
return SDL_SetError("AUDIO_SETINFO failed for %s: %s", devname, strerror(errno));
|
return SDL_SetError("AUDIO_SETINFO failed for %s: %s", devname, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
if (ioctl(_this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
||||||
return SDL_SetError("AUDIO_GETINFO failed for %s: %s", devname, strerror(errno));
|
return SDL_SetError("AUDIO_GETINFO failed for %s: %s", devname, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Final spec used for the device. */
|
/* Final spec used for the device. */
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
this->spec.freq = prinfo->sample_rate;
|
_this->spec.freq = prinfo->sample_rate;
|
||||||
this->spec.channels = prinfo->channels;
|
_this->spec.channels = prinfo->channels;
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
if (!iscapture) {
|
if (!iscapture) {
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen);
|
||||||
if (this->hidden->mixbuf == NULL) {
|
if (_this->hidden->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
NETBSDAUDIO_Status(this);
|
NETBSDAUDIO_Status(_this);
|
||||||
|
|
||||||
/* We're ready to rock and roll. :-) */
|
/* We're ready to rock and roll. :-) */
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The file descriptor for the audio device */
|
/* The file descriptor for the audio device */
|
||||||
|
|||||||
@@ -189,9 +189,9 @@ static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
|||||||
SDL_PostSemaphore(audiodata->playsem);
|
SDL_PostSemaphore(audiodata->playsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_DestroyPCMRecorder(_THIS)
|
static void openslES_DestroyPCMRecorder(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLresult result;
|
SLresult result;
|
||||||
|
|
||||||
/* stop recording */
|
/* stop recording */
|
||||||
@@ -220,9 +220,9 @@ static void openslES_DestroyPCMRecorder(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openslES_CreatePCMRecorder(_THIS)
|
static int openslES_CreatePCMRecorder(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLDataFormat_PCM format_pcm;
|
SLDataFormat_PCM format_pcm;
|
||||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
||||||
SLDataSink audioSnk;
|
SLDataSink audioSnk;
|
||||||
@@ -239,16 +239,16 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Just go with signed 16-bit audio as it's the most compatible */
|
/* Just go with signed 16-bit audio as it's the most compatible */
|
||||||
this->spec.format = SDL_AUDIO_S16SYS;
|
_this->spec.format = SDL_AUDIO_S16SYS;
|
||||||
this->spec.channels = 1;
|
_this->spec.channels = 1;
|
||||||
/*this->spec.freq = SL_SAMPLINGRATE_16 / 1000;*/
|
/*_this->spec.freq = SL_SAMPLINGRATE_16 / 1000;*/
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes */
|
/* Update the fragment size as size in bytes */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
|
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
|
||||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
_this->spec.freq, SDL_AUDIO_BITSIZE(_this->spec.format),
|
||||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
_this->spec.channels, (_this->spec.format & 0x1000) ? "BE" : "LE", _this->spec.samples);
|
||||||
|
|
||||||
/* configure audio source */
|
/* configure audio source */
|
||||||
loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
|
loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
|
||||||
@@ -263,10 +263,10 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||||||
loc_bufq.numBuffers = NUM_BUFFERS;
|
loc_bufq.numBuffers = NUM_BUFFERS;
|
||||||
|
|
||||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||||
format_pcm.numChannels = this->spec.channels;
|
format_pcm.numChannels = _this->spec.channels;
|
||||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
format_pcm.samplesPerSec = _this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||||
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format);
|
format_pcm.containerSize = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||||
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
|
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
|
||||||
|
|
||||||
@@ -303,8 +303,8 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register callback on the buffer queue */
|
/* register callback on the buffer queue */
|
||||||
/* context is '(SDL_PrivateAudioData *)this->hidden' */
|
/* context is '(SDL_PrivateAudioData *)_this->hidden' */
|
||||||
result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, this->hidden);
|
result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback, _this->hidden);
|
||||||
if (SL_RESULT_SUCCESS != result) {
|
if (SL_RESULT_SUCCESS != result) {
|
||||||
LOGE("RegisterCallback failed: %d", result);
|
LOGE("RegisterCallback failed: %d", result);
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -318,14 +318,14 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create the sound buffers */
|
/* Create the sound buffers */
|
||||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * _this->spec.size);
|
||||||
if (audiodata->mixbuff == NULL) {
|
if (audiodata->mixbuff == NULL) {
|
||||||
LOGE("mixbuffer allocate - out of memory");
|
LOGE("mixbuffer allocate - out of memory");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
audiodata->pmixbuff[i] = audiodata->mixbuff + i * this->spec.size;
|
audiodata->pmixbuff[i] = audiodata->mixbuff + i * _this->spec.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in case already recording, stop recording and clear buffer queue */
|
/* in case already recording, stop recording and clear buffer queue */
|
||||||
@@ -337,7 +337,7 @@ static int openslES_CreatePCMRecorder(_THIS)
|
|||||||
|
|
||||||
/* enqueue empty buffers to be filled by the recorder */
|
/* enqueue empty buffers to be filled by the recorder */
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[i], this->spec.size);
|
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[i], _this->spec.size);
|
||||||
if (SL_RESULT_SUCCESS != result) {
|
if (SL_RESULT_SUCCESS != result) {
|
||||||
LOGE("Record enqueue buffers failed: %d", result);
|
LOGE("Record enqueue buffers failed: %d", result);
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -366,9 +366,9 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
|||||||
SDL_PostSemaphore(audiodata->playsem);
|
SDL_PostSemaphore(audiodata->playsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_DestroyPCMPlayer(_THIS)
|
static void openslES_DestroyPCMPlayer(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLresult result;
|
SLresult result;
|
||||||
|
|
||||||
/* set the player's state to 'stopped' */
|
/* set the player's state to 'stopped' */
|
||||||
@@ -398,9 +398,9 @@ static void openslES_DestroyPCMPlayer(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openslES_CreatePCMPlayer(_THIS)
|
static int openslES_CreatePCMPlayer(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
||||||
SLDataFormat_PCM format_pcm;
|
SLDataFormat_PCM format_pcm;
|
||||||
SLAndroidDataFormat_PCM_EX format_pcm_ex;
|
SLAndroidDataFormat_PCM_EX format_pcm_ex;
|
||||||
@@ -417,7 +417,7 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
|
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
|
||||||
*/
|
*/
|
||||||
if (SDL_GetAndroidSDKVersion() >= 21) {
|
if (SDL_GetAndroidSDKVersion() >= 21) {
|
||||||
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
if (SDL_AUDIO_ISSIGNED(test_format)) {
|
if (SDL_AUDIO_ISSIGNED(test_format)) {
|
||||||
@@ -430,36 +430,36 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
LOGI("No compatible audio format, using signed 16-bit audio");
|
LOGI("No compatible audio format, using signed 16-bit audio");
|
||||||
test_format = SDL_AUDIO_S16SYS;
|
test_format = SDL_AUDIO_S16SYS;
|
||||||
}
|
}
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
} else {
|
} else {
|
||||||
/* Just go with signed 16-bit audio as it's the most compatible */
|
/* Just go with signed 16-bit audio as it's the most compatible */
|
||||||
this->spec.format = SDL_AUDIO_S16SYS;
|
_this->spec.format = SDL_AUDIO_S16SYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes */
|
/* Update the fragment size as size in bytes */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
|
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
|
||||||
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
|
_this->spec.freq, SDL_AUDIO_ISFLOAT(_this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(_this->spec.format),
|
||||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
_this->spec.channels, (_this->spec.format & 0x1000) ? "BE" : "LE", _this->spec.samples);
|
||||||
|
|
||||||
/* configure audio source */
|
/* configure audio source */
|
||||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||||
loc_bufq.numBuffers = NUM_BUFFERS;
|
loc_bufq.numBuffers = NUM_BUFFERS;
|
||||||
|
|
||||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||||
format_pcm.numChannels = this->spec.channels;
|
format_pcm.numChannels = _this->spec.channels;
|
||||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
format_pcm.samplesPerSec = _this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||||
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format);
|
format_pcm.containerSize = SDL_AUDIO_BITSIZE(_this->spec.format);
|
||||||
|
|
||||||
if (SDL_AUDIO_ISBIGENDIAN(this->spec.format)) {
|
if (SDL_AUDIO_ISBIGENDIAN(_this->spec.format)) {
|
||||||
format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
|
format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
|
||||||
} else {
|
} else {
|
||||||
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this->spec.channels) {
|
switch (_this->spec.channels) {
|
||||||
case 1:
|
case 1:
|
||||||
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
|
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
|
||||||
break;
|
break;
|
||||||
@@ -486,12 +486,12 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unknown number of channels, fall back to stereo */
|
/* Unknown number of channels, fall back to stereo */
|
||||||
this->spec.channels = 2;
|
_this->spec.channels = 2;
|
||||||
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
|
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
if (SDL_AUDIO_ISFLOAT(_this->spec.format)) {
|
||||||
/* Copy all setup into PCM EX structure */
|
/* Copy all setup into PCM EX structure */
|
||||||
format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
|
format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
|
||||||
format_pcm_ex.endianness = format_pcm.endianness;
|
format_pcm_ex.endianness = format_pcm.endianness;
|
||||||
@@ -504,7 +504,7 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
audioSrc.pLocator = &loc_bufq;
|
audioSrc.pLocator = &loc_bufq;
|
||||||
audioSrc.pFormat = SDL_AUDIO_ISFLOAT(this->spec.format) ? (void *)&format_pcm_ex : (void *)&format_pcm;
|
audioSrc.pFormat = SDL_AUDIO_ISFLOAT(_this->spec.format) ? (void *)&format_pcm_ex : (void *)&format_pcm;
|
||||||
|
|
||||||
/* configure audio sink */
|
/* configure audio sink */
|
||||||
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||||
@@ -541,8 +541,8 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register callback on the buffer queue */
|
/* register callback on the buffer queue */
|
||||||
/* context is '(SDL_PrivateAudioData *)this->hidden' */
|
/* context is '(SDL_PrivateAudioData *)_this->hidden' */
|
||||||
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this->hidden);
|
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, _this->hidden);
|
||||||
if (SL_RESULT_SUCCESS != result) {
|
if (SL_RESULT_SUCCESS != result) {
|
||||||
LOGE("RegisterCallback failed: %d", result);
|
LOGE("RegisterCallback failed: %d", result);
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -565,14 +565,14 @@ static int openslES_CreatePCMPlayer(_THIS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create the sound buffers */
|
/* Create the sound buffers */
|
||||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * _this->spec.size);
|
||||||
if (audiodata->mixbuff == NULL) {
|
if (audiodata->mixbuff == NULL) {
|
||||||
LOGE("mixbuffer allocate - out of memory");
|
LOGE("mixbuffer allocate - out of memory");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
audiodata->pmixbuff[i] = audiodata->mixbuff + i * this->spec.size;
|
audiodata->pmixbuff[i] = audiodata->mixbuff + i * _this->spec.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the player's state to playing */
|
/* set the player's state to playing */
|
||||||
@@ -588,26 +588,26 @@ failed:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openslES_OpenDevice(_THIS, const char *devname)
|
static int openslES_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
LOGI("openslES_OpenDevice() %s for capture", devname);
|
LOGI("openslES_OpenDevice() %s for capture", devname);
|
||||||
return openslES_CreatePCMRecorder(this);
|
return openslES_CreatePCMRecorder(_this);
|
||||||
} else {
|
} else {
|
||||||
int ret;
|
int ret;
|
||||||
LOGI("openslES_OpenDevice() %s for playing", devname);
|
LOGI("openslES_OpenDevice() %s for playing", devname);
|
||||||
ret = openslES_CreatePCMPlayer(this);
|
ret = openslES_CreatePCMPlayer(_this);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* Another attempt to open the device with a lower frequency */
|
/* Another attempt to open the device with a lower frequency */
|
||||||
if (this->spec.freq > 48000) {
|
if (_this->spec.freq > 48000) {
|
||||||
openslES_DestroyPCMPlayer(this);
|
openslES_DestroyPCMPlayer(_this);
|
||||||
this->spec.freq = 48000;
|
_this->spec.freq = 48000;
|
||||||
ret = openslES_CreatePCMPlayer(this);
|
ret = openslES_CreatePCMPlayer(_this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,9 +619,9 @@ static int openslES_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_WaitDevice(_THIS)
|
static void openslES_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
|
|
||||||
LOGV("openslES_WaitDevice()");
|
LOGV("openslES_WaitDevice()");
|
||||||
|
|
||||||
@@ -629,15 +629,15 @@ static void openslES_WaitDevice(_THIS)
|
|||||||
SDL_WaitSemaphore(audiodata->playsem);
|
SDL_WaitSemaphore(audiodata->playsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_PlayDevice(_THIS)
|
static void openslES_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLresult result;
|
SLresult result;
|
||||||
|
|
||||||
LOGV("======openslES_PlayDevice()======");
|
LOGV("======openslES_PlayDevice()======");
|
||||||
|
|
||||||
/* Queue it up */
|
/* Queue it up */
|
||||||
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], this->spec.size);
|
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size);
|
||||||
|
|
||||||
audiodata->next_buffer++;
|
audiodata->next_buffer++;
|
||||||
if (audiodata->next_buffer >= NUM_BUFFERS) {
|
if (audiodata->next_buffer >= NUM_BUFFERS) {
|
||||||
@@ -663,28 +663,28 @@ static void openslES_PlayDevice(_THIS)
|
|||||||
/* */
|
/* */
|
||||||
/* okay.. */
|
/* okay.. */
|
||||||
|
|
||||||
static Uint8 *openslES_GetDeviceBuf(_THIS)
|
static Uint8 *openslES_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
|
|
||||||
LOGV("openslES_GetDeviceBuf()");
|
LOGV("openslES_GetDeviceBuf()");
|
||||||
return audiodata->pmixbuff[audiodata->next_buffer];
|
return audiodata->pmixbuff[audiodata->next_buffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openslES_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int openslES_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
struct SDL_PrivateAudioData *audiodata = _this->hidden;
|
||||||
SLresult result;
|
SLresult result;
|
||||||
|
|
||||||
/* Wait for new recorded data */
|
/* Wait for new recorded data */
|
||||||
SDL_WaitSemaphore(audiodata->playsem);
|
SDL_WaitSemaphore(audiodata->playsem);
|
||||||
|
|
||||||
/* Copy it to the output buffer */
|
/* Copy it to the output buffer */
|
||||||
SDL_assert(buflen == this->spec.size);
|
SDL_assert(buflen == _this->spec.size);
|
||||||
SDL_memcpy(buffer, audiodata->pmixbuff[audiodata->next_buffer], this->spec.size);
|
SDL_memcpy(buffer, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size);
|
||||||
|
|
||||||
/* Re-enqueue the buffer */
|
/* Re-enqueue the buffer */
|
||||||
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], this->spec.size);
|
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, audiodata->pmixbuff[audiodata->next_buffer], _this->spec.size);
|
||||||
if (SL_RESULT_SUCCESS != result) {
|
if (SL_RESULT_SUCCESS != result) {
|
||||||
LOGE("Record enqueue buffers failed: %d", result);
|
LOGE("Record enqueue buffers failed: %d", result);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -695,22 +695,22 @@ static int openslES_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
audiodata->next_buffer = 0;
|
audiodata->next_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->spec.size;
|
return _this->spec.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_CloseDevice(_THIS)
|
static void openslES_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* struct SDL_PrivateAudioData *audiodata = this->hidden; */
|
/* struct SDL_PrivateAudioData *audiodata = _this->hidden; */
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
LOGI("openslES_CloseDevice() for capture");
|
LOGI("openslES_CloseDevice() for capture");
|
||||||
openslES_DestroyPCMRecorder(this);
|
openslES_DestroyPCMRecorder(_this);
|
||||||
} else {
|
} else {
|
||||||
LOGI("openslES_CloseDevice() for playing");
|
LOGI("openslES_CloseDevice() for playing");
|
||||||
openslES_DestroyPCMPlayer(this);
|
openslES_DestroyPCMPlayer(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl)
|
static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl)
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
|
|||||||
@@ -942,11 +942,11 @@ static void output_callback(void *data)
|
|||||||
struct spa_buffer *spa_buf;
|
struct spa_buffer *spa_buf;
|
||||||
Uint8 *dst;
|
Uint8 *dst;
|
||||||
|
|
||||||
_THIS = (SDL_AudioDevice *)data;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)data;
|
||||||
struct pw_stream *stream = this->hidden->stream;
|
struct pw_stream *stream = _this->hidden->stream;
|
||||||
|
|
||||||
/* Shutting down, don't do anything */
|
/* Shutting down, don't do anything */
|
||||||
if (SDL_AtomicGet(&this->shutdown)) {
|
if (SDL_AtomicGet(&_this->shutdown)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,37 +967,37 @@ static void output_callback(void *data)
|
|||||||
* and run the callback with the work buffer to keep the callback
|
* and run the callback with the work buffer to keep the callback
|
||||||
* firing regularly in case the audio is being used as a timer.
|
* firing regularly in case the audio is being used as a timer.
|
||||||
*/
|
*/
|
||||||
SDL_LockMutex(this->mixer_lock);
|
SDL_LockMutex(_this->mixer_lock);
|
||||||
if (!SDL_AtomicGet(&this->paused)) {
|
if (!SDL_AtomicGet(&_this->paused)) {
|
||||||
if (SDL_AtomicGet(&this->enabled)) {
|
if (SDL_AtomicGet(&_this->enabled)) {
|
||||||
dst = spa_buf->datas[0].data;
|
dst = spa_buf->datas[0].data;
|
||||||
} else {
|
} else {
|
||||||
dst = this->work_buffer;
|
dst = _this->work_buffer;
|
||||||
SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size);
|
SDL_memset(spa_buf->datas[0].data, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->stream) {
|
if (!_this->stream) {
|
||||||
this->callbackspec.callback(this->callbackspec.userdata, dst, this->callbackspec.size);
|
_this->callbackspec.callback(_this->callbackspec.userdata, dst, _this->callbackspec.size);
|
||||||
} else {
|
} else {
|
||||||
int got;
|
int got;
|
||||||
|
|
||||||
/* Fire the callback until we have enough to fill a buffer */
|
/* Fire the callback until we have enough to fill a buffer */
|
||||||
while (SDL_GetAudioStreamAvailable(this->stream) < this->spec.size) {
|
while (SDL_GetAudioStreamAvailable(_this->stream) < _this->spec.size) {
|
||||||
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
|
_this->callbackspec.callback(_this->callbackspec.userdata, _this->work_buffer, _this->callbackspec.size);
|
||||||
SDL_PutAudioStreamData(this->stream, this->work_buffer, this->callbackspec.size);
|
SDL_PutAudioStreamData(_this->stream, _this->work_buffer, _this->callbackspec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
got = SDL_GetAudioStreamData(this->stream, dst, this->spec.size);
|
got = SDL_GetAudioStreamData(_this->stream, dst, _this->spec.size);
|
||||||
SDL_assert(got == this->spec.size);
|
SDL_assert(got == _this->spec.size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size);
|
SDL_memset(spa_buf->datas[0].data, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
SDL_UnlockMutex(this->mixer_lock);
|
SDL_UnlockMutex(_this->mixer_lock);
|
||||||
|
|
||||||
spa_buf->datas[0].chunk->offset = 0;
|
spa_buf->datas[0].chunk->offset = 0;
|
||||||
spa_buf->datas[0].chunk->stride = this->hidden->stride;
|
spa_buf->datas[0].chunk->stride = _this->hidden->stride;
|
||||||
spa_buf->datas[0].chunk->size = this->spec.size;
|
spa_buf->datas[0].chunk->size = _this->spec.size;
|
||||||
|
|
||||||
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
||||||
}
|
}
|
||||||
@@ -1007,11 +1007,11 @@ static void input_callback(void *data)
|
|||||||
struct pw_buffer *pw_buf;
|
struct pw_buffer *pw_buf;
|
||||||
struct spa_buffer *spa_buf;
|
struct spa_buffer *spa_buf;
|
||||||
Uint8 *src;
|
Uint8 *src;
|
||||||
_THIS = (SDL_AudioDevice *)data;
|
SDL_AudioDevice *_this = (SDL_AudioDevice *)data;
|
||||||
struct pw_stream *stream = this->hidden->stream;
|
struct pw_stream *stream = _this->hidden->stream;
|
||||||
|
|
||||||
/* Shutting down, don't do anything */
|
/* Shutting down, don't do anything */
|
||||||
if (SDL_AtomicGet(&this->shutdown)) {
|
if (SDL_AtomicGet(&_this->shutdown)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,7 +1026,7 @@ static void input_callback(void *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SDL_AtomicGet(&this->paused)) {
|
if (!SDL_AtomicGet(&_this->paused)) {
|
||||||
/* Calculate the offset and data size */
|
/* Calculate the offset and data size */
|
||||||
const Uint32 offset = SPA_MIN(spa_buf->datas[0].chunk->offset, spa_buf->datas[0].maxsize);
|
const Uint32 offset = SPA_MIN(spa_buf->datas[0].chunk->offset, spa_buf->datas[0].maxsize);
|
||||||
const Uint32 size = SPA_MIN(spa_buf->datas[0].chunk->size, spa_buf->datas[0].maxsize - offset);
|
const Uint32 size = SPA_MIN(spa_buf->datas[0].chunk->size, spa_buf->datas[0].maxsize - offset);
|
||||||
@@ -1034,23 +1034,23 @@ static void input_callback(void *data)
|
|||||||
src += offset;
|
src += offset;
|
||||||
|
|
||||||
/* Fill the buffer with silence if the stream is disabled. */
|
/* Fill the buffer with silence if the stream is disabled. */
|
||||||
if (!SDL_AtomicGet(&this->enabled)) {
|
if (!SDL_AtomicGet(&_this->enabled)) {
|
||||||
SDL_memset(src, this->callbackspec.silence, size);
|
SDL_memset(src, _this->callbackspec.silence, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pipewire can vary the latency, so buffer all incoming data */
|
/* Pipewire can vary the latency, so buffer all incoming data */
|
||||||
SDL_WriteToDataQueue(this->hidden->buffer, src, size);
|
SDL_WriteToDataQueue(_this->hidden->buffer, src, size);
|
||||||
|
|
||||||
while (SDL_GetDataQueueSize(this->hidden->buffer) >= this->callbackspec.size) {
|
while (SDL_GetDataQueueSize(_this->hidden->buffer) >= _this->callbackspec.size) {
|
||||||
SDL_ReadFromDataQueue(this->hidden->buffer, this->work_buffer, this->callbackspec.size);
|
SDL_ReadFromDataQueue(_this->hidden->buffer, _this->work_buffer, _this->callbackspec.size);
|
||||||
|
|
||||||
SDL_LockMutex(this->mixer_lock);
|
SDL_LockMutex(_this->mixer_lock);
|
||||||
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
|
_this->callbackspec.callback(_this->callbackspec.userdata, _this->work_buffer, _this->callbackspec.size);
|
||||||
SDL_UnlockMutex(this->mixer_lock);
|
SDL_UnlockMutex(_this->mixer_lock);
|
||||||
}
|
}
|
||||||
} else if (this->hidden->buffer) { /* Flush the buffer when paused */
|
} else if (_this->hidden->buffer) { /* Flush the buffer when paused */
|
||||||
if (SDL_GetDataQueueSize(this->hidden->buffer) != 0) {
|
if (SDL_GetDataQueueSize(_this->hidden->buffer) != 0) {
|
||||||
SDL_ClearDataQueue(this->hidden->buffer, this->hidden->input_buffer_packet_size);
|
SDL_ClearDataQueue(_this->hidden->buffer, _this->hidden->input_buffer_packet_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,18 +1059,18 @@ static void input_callback(void *data)
|
|||||||
|
|
||||||
static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
||||||
{
|
{
|
||||||
_THIS = data;
|
SDL_AudioDevice *_this = data;
|
||||||
|
|
||||||
if (this->iscapture == SDL_FALSE) {
|
if (_this->iscapture == SDL_FALSE) {
|
||||||
/*
|
/*
|
||||||
* Clamp the output spec samples and size to the max size of the Pipewire buffer.
|
* Clamp the output spec samples and size to the max size of the Pipewire buffer.
|
||||||
* If they exceed the maximum size of the Pipewire buffer, double buffering will be used.
|
* If they exceed the maximum size of the Pipewire buffer, double buffering will be used.
|
||||||
*/
|
*/
|
||||||
if (this->spec.size > buffer->buffer->datas[0].maxsize) {
|
if (_this->spec.size > buffer->buffer->datas[0].maxsize) {
|
||||||
this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
|
_this->spec.samples = buffer->buffer->datas[0].maxsize / _this->hidden->stride;
|
||||||
this->spec.size = buffer->buffer->datas[0].maxsize;
|
_this->spec.size = buffer->buffer->datas[0].maxsize;
|
||||||
}
|
}
|
||||||
} else if (this->hidden->buffer == NULL) {
|
} else if (_this->hidden->buffer == NULL) {
|
||||||
/*
|
/*
|
||||||
* The latency of source nodes can change, so buffering is always required.
|
* The latency of source nodes can change, so buffering is always required.
|
||||||
*
|
*
|
||||||
@@ -1079,24 +1079,24 @@ static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
|||||||
*
|
*
|
||||||
* A packet size of 2 periods should be more than is ever needed.
|
* A packet size of 2 periods should be more than is ever needed.
|
||||||
*/
|
*/
|
||||||
this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
|
_this->hidden->input_buffer_packet_size = SPA_MAX(_this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
|
||||||
this->hidden->buffer = SDL_CreateDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
|
_this->hidden->buffer = SDL_CreateDataQueue(_this->hidden->input_buffer_packet_size, _this->hidden->input_buffer_packet_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
|
_this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
|
||||||
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
|
PIPEWIRE_pw_thread_loop_signal(_this->hidden->loop, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
static void stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
||||||
{
|
{
|
||||||
_THIS = data;
|
SDL_AudioDevice *_this = data;
|
||||||
|
|
||||||
if (state == PW_STREAM_STATE_STREAMING) {
|
if (state == PW_STREAM_STATE_STREAMING) {
|
||||||
this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY;
|
_this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
|
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
|
||||||
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
|
PIPEWIRE_pw_thread_loop_signal(_this->hidden->loop, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +1109,7 @@ static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_E
|
|||||||
.add_buffer = stream_add_buffer_callback,
|
.add_buffer = stream_add_buffer_callback,
|
||||||
.process = input_callback };
|
.process = input_callback };
|
||||||
|
|
||||||
static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
static int PIPEWIRE_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
|
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
|
||||||
@@ -1128,12 +1128,12 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||||||
struct SDL_PrivateAudioData *priv;
|
struct SDL_PrivateAudioData *priv;
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
const char *app_name, *stream_name, *stream_role, *error;
|
const char *app_name, *stream_name, *stream_role, *error;
|
||||||
Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
Uint32 node_id = _this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(_this->handle);
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* Clamp the period size to sane values */
|
/* Clamp the period size to sane values */
|
||||||
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
|
const int min_period = PW_MIN_SAMPLES * SPA_MAX(_this->spec.freq / PW_BASE_CLOCK_RATE, 1);
|
||||||
|
|
||||||
/* Get the hints for the application name, stream name and role */
|
/* Get the hints for the application name, stream name and role */
|
||||||
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||||
@@ -1159,27 +1159,27 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the Pipewire stream info from the SDL audio spec */
|
/* Initialize the Pipewire stream info from the SDL audio spec */
|
||||||
initialize_spa_info(&this->spec, &spa_info);
|
initialize_spa_info(&_this->spec, &spa_info);
|
||||||
params = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &spa_info);
|
params = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &spa_info);
|
||||||
if (params == NULL) {
|
if (params == NULL) {
|
||||||
return SDL_SetError("Pipewire: Failed to set audio format parameters");
|
return SDL_SetError("Pipewire: Failed to set audio format parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
|
priv = SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
|
||||||
this->hidden = priv;
|
_this->hidden = priv;
|
||||||
if (priv == NULL) {
|
if (priv == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Size of a single audio frame in bytes */
|
/* Size of a single audio frame in bytes */
|
||||||
priv->stride = (SDL_AUDIO_BITSIZE(this->spec.format) >> 3) * this->spec.channels;
|
priv->stride = (SDL_AUDIO_BITSIZE(_this->spec.format) >> 3) * _this->spec.channels;
|
||||||
|
|
||||||
if (this->spec.samples < min_period) {
|
if (_this->spec.samples < min_period) {
|
||||||
this->spec.samples = min_period;
|
_this->spec.samples = min_period;
|
||||||
this->spec.size = this->spec.samples * priv->stride;
|
_this->spec.size = _this->spec.samples * priv->stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
|
(void)SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)_this->handle);
|
||||||
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
|
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
|
||||||
if (priv->loop == NULL) {
|
if (priv->loop == NULL) {
|
||||||
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
|
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
|
||||||
@@ -1207,8 +1207,8 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||||||
PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name);
|
PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name);
|
||||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
|
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
|
||||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
|
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
|
||||||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", this->spec.samples, this->spec.freq);
|
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", _this->spec.samples, _this->spec.freq);
|
||||||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
|
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", _this->spec.freq);
|
||||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
|
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1234,7 +1234,7 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||||||
|
|
||||||
/* Create the new stream */
|
/* Create the new stream */
|
||||||
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
|
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
|
||||||
iscapture ? &stream_input_events : &stream_output_events, this);
|
iscapture ? &stream_input_events : &stream_output_events, _this);
|
||||||
if (priv->stream == NULL) {
|
if (priv->stream == NULL) {
|
||||||
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
|
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
|
||||||
}
|
}
|
||||||
@@ -1270,29 +1270,29 @@ static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PIPEWIRE_CloseDevice(_THIS)
|
static void PIPEWIRE_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->loop) {
|
if (_this->hidden->loop) {
|
||||||
PIPEWIRE_pw_thread_loop_stop(this->hidden->loop);
|
PIPEWIRE_pw_thread_loop_stop(_this->hidden->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->stream) {
|
if (_this->hidden->stream) {
|
||||||
PIPEWIRE_pw_stream_destroy(this->hidden->stream);
|
PIPEWIRE_pw_stream_destroy(_this->hidden->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->context) {
|
if (_this->hidden->context) {
|
||||||
PIPEWIRE_pw_context_destroy(this->hidden->context);
|
PIPEWIRE_pw_context_destroy(_this->hidden->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->loop) {
|
if (_this->hidden->loop) {
|
||||||
PIPEWIRE_pw_thread_loop_destroy(this->hidden->loop);
|
PIPEWIRE_pw_thread_loop_destroy(_this->hidden->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->buffer) {
|
if (_this->hidden->buffer) {
|
||||||
SDL_DestroyDataQueue(this->hidden->buffer);
|
SDL_DestroyDataQueue(_this->hidden->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
#include <pipewire/pipewire.h>
|
#include <pipewire/pipewire.h>
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
struct pw_thread_loop *loop;
|
struct pw_thread_loop *loop;
|
||||||
|
|||||||
@@ -33,20 +33,20 @@
|
|||||||
/* The tag name used by PS2 audio */
|
/* The tag name used by PS2 audio */
|
||||||
#define PS2AUDIO_DRIVER_NAME "ps2"
|
#define PS2AUDIO_DRIVER_NAME "ps2"
|
||||||
|
|
||||||
static int PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
static int PS2AUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
int i, mixlen;
|
int i, mixlen;
|
||||||
struct audsrv_fmt_t format;
|
struct audsrv_fmt_t format;
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)
|
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||||
SDL_malloc(sizeof(*this->hidden));
|
SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* These are the native supported audio PS2 configs */
|
/* These are the native supported audio PS2 configs */
|
||||||
switch (this->spec.freq) {
|
switch (_this->spec.freq) {
|
||||||
case 11025:
|
case 11025:
|
||||||
case 12000:
|
case 12000:
|
||||||
case 22050:
|
case 22050:
|
||||||
@@ -54,86 +54,86 @@ static int PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
case 32000:
|
case 32000:
|
||||||
case 44100:
|
case 44100:
|
||||||
case 48000:
|
case 48000:
|
||||||
this->spec.freq = this->spec.freq;
|
_this->spec.freq = _this->spec.freq;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->spec.freq = 48000;
|
_this->spec.freq = 48000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->spec.samples = 512;
|
_this->spec.samples = 512;
|
||||||
this->spec.channels = this->spec.channels == 1 ? 1 : 2;
|
_this->spec.channels = _this->spec.channels == 1 ? 1 : 2;
|
||||||
this->spec.format = this->spec.format == SDL_AUDIO_S8 ? SDL_AUDIO_S8 : SDL_AUDIO_S16;
|
_this->spec.format = _this->spec.format == SDL_AUDIO_S8 ? SDL_AUDIO_S8 : SDL_AUDIO_S16;
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
format.bits = this->spec.format == SDL_AUDIO_S8 ? 8 : 16;
|
format.bits = _this->spec.format == SDL_AUDIO_S8 ? 8 : 16;
|
||||||
format.freq = this->spec.freq;
|
format.freq = _this->spec.freq;
|
||||||
format.channels = this->spec.channels;
|
format.channels = _this->spec.channels;
|
||||||
|
|
||||||
this->hidden->channel = audsrv_set_format(&format);
|
_this->hidden->channel = audsrv_set_format(&format);
|
||||||
audsrv_set_volume(MAX_VOLUME);
|
audsrv_set_volume(MAX_VOLUME);
|
||||||
|
|
||||||
if (this->hidden->channel < 0) {
|
if (_this->hidden->channel < 0) {
|
||||||
free(this->hidden->rawbuf);
|
free(_this->hidden->rawbuf);
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
return SDL_SetError("Couldn't reserve hardware channel");
|
return SDL_SetError("Couldn't reserve hardware channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes. */
|
/* Update the fragment size as size in bytes. */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate the mixing buffer. Its size and starting address must
|
/* Allocate the mixing buffer. Its size and starting address must
|
||||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||||
64, so spec->size should be a multiple of 64 as well. */
|
64, so spec->size should be a multiple of 64 as well. */
|
||||||
mixlen = this->spec.size * NUM_BUFFERS;
|
mixlen = _this->spec.size * NUM_BUFFERS;
|
||||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
_this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||||
if (this->hidden->rawbuf == NULL) {
|
if (_this->hidden->rawbuf == NULL) {
|
||||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
SDL_memset(_this->hidden->rawbuf, 0, mixlen);
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
_this->hidden->mixbufs[i] = &_this->hidden->rawbuf[i * _this->spec.size];
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->next_buffer = 0;
|
_this->hidden->next_buffer = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PS2AUDIO_PlayDevice(_THIS)
|
static void PS2AUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
uint8_t *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
uint8_t *mixbuf = _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
audsrv_play_audio((char *)mixbuf, this->spec.size);
|
audsrv_play_audio((char *)mixbuf, _this->spec.size);
|
||||||
|
|
||||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
_this->hidden->next_buffer = (_this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void PS2AUDIO_WaitDevice(_THIS)
|
static void PS2AUDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
audsrv_wait_audio(this->spec.size);
|
audsrv_wait_audio(_this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *PS2AUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
return _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PS2AUDIO_CloseDevice(_THIS)
|
static void PS2AUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->channel >= 0) {
|
if (_this->hidden->channel >= 0) {
|
||||||
audsrv_stop_audio();
|
audsrv_stop_audio();
|
||||||
this->hidden->channel = -1;
|
_this->hidden->channel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->rawbuf != NULL) {
|
if (_this->hidden->rawbuf != NULL) {
|
||||||
free(this->hidden->rawbuf);
|
free(_this->hidden->rawbuf);
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PS2AUDIO_ThreadInit(_THIS)
|
static void PS2AUDIO_ThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Increase the priority of this audio thread by 1 to put it
|
/* Increase the priority of this audio thread by 1 to put it
|
||||||
ahead of other SDL threads. */
|
ahead of other SDL threads. */
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
#define NUM_BUFFERS 2
|
#define NUM_BUFFERS 2
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
|
|||||||
@@ -43,33 +43,33 @@ static inline SDL_bool isBasicAudioConfig(const SDL_AudioSpec *spec)
|
|||||||
return spec->freq == 44100;
|
return spec->freq == 44100;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
static int PSPAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
int format, mixlen, i;
|
int format, mixlen, i;
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)
|
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||||
SDL_malloc(sizeof(*this->hidden));
|
SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* device only natively supports S16LSB */
|
/* device only natively supports S16LSB */
|
||||||
this->spec.format = SDL_AUDIO_S16LSB;
|
_this->spec.format = SDL_AUDIO_S16LSB;
|
||||||
|
|
||||||
/* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo),
|
/* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo),
|
||||||
however with frequencies differents than 44.1KHz, it just supports Stereo,
|
however with frequencies differents than 44.1KHz, it just supports Stereo,
|
||||||
so a resampler must be done for these scenarios */
|
so a resampler must be done for these scenarios */
|
||||||
if (isBasicAudioConfig(&this->spec)) {
|
if (isBasicAudioConfig(&_this->spec)) {
|
||||||
/* The sample count must be a multiple of 64. */
|
/* The sample count must be a multiple of 64. */
|
||||||
this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
|
_this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(_this->spec.samples);
|
||||||
/* The number of channels (1 or 2). */
|
/* The number of channels (1 or 2). */
|
||||||
this->spec.channels = this->spec.channels == 1 ? 1 : 2;
|
_this->spec.channels = _this->spec.channels == 1 ? 1 : 2;
|
||||||
format = this->spec.channels == 1 ? PSP_AUDIO_FORMAT_MONO : PSP_AUDIO_FORMAT_STEREO;
|
format = _this->spec.channels == 1 ? PSP_AUDIO_FORMAT_MONO : PSP_AUDIO_FORMAT_STEREO;
|
||||||
this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
|
_this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, _this->spec.samples, format);
|
||||||
} else {
|
} else {
|
||||||
/* 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000 */
|
/* 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000 */
|
||||||
switch (this->spec.freq) {
|
switch (_this->spec.freq) {
|
||||||
case 8000:
|
case 8000:
|
||||||
case 11025:
|
case 11025:
|
||||||
case 12000:
|
case 12000:
|
||||||
@@ -79,87 +79,87 @@ static int PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
case 32000:
|
case 32000:
|
||||||
case 44100:
|
case 44100:
|
||||||
case 48000:
|
case 48000:
|
||||||
this->spec.freq = this->spec.freq;
|
_this->spec.freq = _this->spec.freq;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->spec.freq = 48000;
|
_this->spec.freq = 48000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* The number of samples to output in one output call (min 17, max 4111). */
|
/* The number of samples to output in one output call (min 17, max 4111). */
|
||||||
this->spec.samples = this->spec.samples < 17 ? 17 : (this->spec.samples > 4111 ? 4111 : this->spec.samples);
|
_this->spec.samples = _this->spec.samples < 17 ? 17 : (_this->spec.samples > 4111 ? 4111 : _this->spec.samples);
|
||||||
this->spec.channels = 2; /* we're forcing the hardware to stereo. */
|
_this->spec.channels = 2; /* we're forcing the hardware to stereo. */
|
||||||
this->hidden->channel = sceAudioSRCChReserve(this->spec.samples, this->spec.freq, 2);
|
_this->hidden->channel = sceAudioSRCChReserve(_this->spec.samples, _this->spec.freq, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->channel < 0) {
|
if (_this->hidden->channel < 0) {
|
||||||
free(this->hidden->rawbuf);
|
free(_this->hidden->rawbuf);
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
return SDL_SetError("Couldn't reserve hardware channel");
|
return SDL_SetError("Couldn't reserve hardware channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes. */
|
/* Update the fragment size as size in bytes. */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate the mixing buffer. Its size and starting address must
|
/* Allocate the mixing buffer. Its size and starting address must
|
||||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||||
64, so spec->size should be a multiple of 64 as well. */
|
64, so spec->size should be a multiple of 64 as well. */
|
||||||
mixlen = this->spec.size * NUM_BUFFERS;
|
mixlen = _this->spec.size * NUM_BUFFERS;
|
||||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
_this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||||
if (this->hidden->rawbuf == NULL) {
|
if (_this->hidden->rawbuf == NULL) {
|
||||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
SDL_memset(_this->hidden->rawbuf, 0, mixlen);
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
_this->hidden->mixbufs[i] = &_this->hidden->rawbuf[i * _this->spec.size];
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->next_buffer = 0;
|
_this->hidden->next_buffer = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PSPAUDIO_PlayDevice(_THIS)
|
static void PSPAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
Uint8 *mixbuf = _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
if (!isBasicAudioConfig(&this->spec)) {
|
if (!isBasicAudioConfig(&_this->spec)) {
|
||||||
SDL_assert(this->spec.channels == 2);
|
SDL_assert(_this->spec.channels == 2);
|
||||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, mixbuf);
|
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, mixbuf);
|
||||||
} else {
|
} else {
|
||||||
sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
sceAudioOutputPannedBlocking(_this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
_this->hidden->next_buffer = (_this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void PSPAUDIO_WaitDevice(_THIS)
|
static void PSPAUDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Because we block when sending audio, there's no need for this function to do anything. */
|
/* Because we block when sending audio, there's no need for this function to do anything. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *PSPAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
return _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PSPAUDIO_CloseDevice(_THIS)
|
static void PSPAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->channel >= 0) {
|
if (_this->hidden->channel >= 0) {
|
||||||
if (!isBasicAudioConfig(&this->spec)) {
|
if (!isBasicAudioConfig(&_this->spec)) {
|
||||||
sceAudioSRCChRelease();
|
sceAudioSRCChRelease();
|
||||||
} else {
|
} else {
|
||||||
sceAudioChRelease(this->hidden->channel);
|
sceAudioChRelease(_this->hidden->channel);
|
||||||
}
|
}
|
||||||
this->hidden->channel = -1;
|
_this->hidden->channel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->rawbuf != NULL) {
|
if (_this->hidden->rawbuf != NULL) {
|
||||||
free(this->hidden->rawbuf);
|
free(_this->hidden->rawbuf);
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PSPAUDIO_ThreadInit(_THIS)
|
static void PSPAUDIO_ThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Increase the priority of this audio thread by 1 to put it
|
/* Increase the priority of this audio thread by 1 to put it
|
||||||
ahead of other SDL threads. */
|
ahead of other SDL threads. */
|
||||||
|
|||||||
@@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
#define NUM_BUFFERS 2
|
#define NUM_BUFFERS 2
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ static int ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void PULSEAUDIO_WaitDevice(_THIS)
|
static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */
|
/* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */
|
||||||
}
|
}
|
||||||
@@ -344,20 +344,20 @@ static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
|
|||||||
h->bytes_requested += nbytes;
|
h->bytes_requested += nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PULSEAUDIO_PlayDevice(_THIS)
|
static void PULSEAUDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
int available = h->mixlen;
|
int available = h->mixlen;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
int cpy;
|
int cpy;
|
||||||
|
|
||||||
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
|
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
|
||||||
|
|
||||||
while (SDL_AtomicGet(&this->enabled) && (available > 0)) {
|
while (SDL_AtomicGet(&_this->enabled) && (available > 0)) {
|
||||||
cpy = SDL_min(h->bytes_requested, available);
|
cpy = SDL_min(h->bytes_requested, available);
|
||||||
if (cpy) {
|
if (cpy) {
|
||||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/
|
/*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/
|
||||||
@@ -371,7 +371,7 @@ static void PULSEAUDIO_PlayDevice(_THIS)
|
|||||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,18 +379,18 @@ static void PULSEAUDIO_PlayDevice(_THIS)
|
|||||||
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
|
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *PULSEAUDIO_GetDeviceBuf(_THIS)
|
static Uint8 *PULSEAUDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int PULSEAUDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
const void *data = NULL;
|
const void *data = NULL;
|
||||||
size_t nbytes = 0;
|
size_t nbytes = 0;
|
||||||
|
|
||||||
while (SDL_AtomicGet(&this->enabled)) {
|
while (SDL_AtomicGet(&_this->enabled)) {
|
||||||
if (h->capturebuf != NULL) {
|
if (h->capturebuf != NULL) {
|
||||||
const int cpy = SDL_min(buflen, h->capturelen);
|
const int cpy = SDL_min(buflen, h->capturelen);
|
||||||
SDL_memcpy(buffer, h->capturebuf, cpy);
|
SDL_memcpy(buffer, h->capturebuf, cpy);
|
||||||
@@ -407,7 +407,7 @@ static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return -1; /* uhoh, pulse failed! */
|
return -1; /* uhoh, pulse failed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,9 +432,9 @@ static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
return -1; /* not enabled? */
|
return -1; /* not enabled? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PULSEAUDIO_FlushCapture(_THIS)
|
static void PULSEAUDIO_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||||
const void *data = NULL;
|
const void *data = NULL;
|
||||||
size_t nbytes = 0;
|
size_t nbytes = 0;
|
||||||
|
|
||||||
@@ -444,11 +444,11 @@ static void PULSEAUDIO_FlushCapture(_THIS)
|
|||||||
h->capturelen = 0;
|
h->capturelen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (SDL_AtomicGet(&this->enabled)) {
|
while (SDL_AtomicGet(&_this->enabled)) {
|
||||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
return; /* uhoh, pulse failed! */
|
return; /* uhoh, pulse failed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,20 +462,20 @@ static void PULSEAUDIO_FlushCapture(_THIS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PULSEAUDIO_CloseDevice(_THIS)
|
static void PULSEAUDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->stream) {
|
if (_this->hidden->stream) {
|
||||||
if (this->hidden->capturebuf != NULL) {
|
if (_this->hidden->capturebuf != NULL) {
|
||||||
PULSEAUDIO_pa_stream_drop(this->hidden->stream);
|
PULSEAUDIO_pa_stream_drop(_this->hidden->stream);
|
||||||
}
|
}
|
||||||
PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
|
PULSEAUDIO_pa_stream_disconnect(_this->hidden->stream);
|
||||||
PULSEAUDIO_pa_stream_unref(this->hidden->stream);
|
PULSEAUDIO_pa_stream_unref(_this->hidden->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
|
DisconnectFromPulseServer(_this->hidden->mainloop, _this->hidden->context);
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden->device_name);
|
SDL_free(_this->hidden->device_name);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||||
@@ -515,7 +515,7 @@ static SDL_bool FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool is
|
|||||||
return h->device_name != NULL;
|
return h->device_name != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = NULL;
|
struct SDL_PrivateAudioData *h = NULL;
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
@@ -525,19 +525,19 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
pa_channel_map pacmap;
|
pa_channel_map pacmap;
|
||||||
pa_stream_flags_t flags = 0;
|
pa_stream_flags_t flags = 0;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
int state = 0, format = PA_SAMPLE_INVALID;
|
int state = 0, format = PA_SAMPLE_INVALID;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
h = this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden));
|
h = _this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
/* Try for a closest match on audio format */
|
/* Try for a closest match on audio format */
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
|
||||||
@@ -572,27 +572,27 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
if (!test_format) {
|
if (!test_format) {
|
||||||
return SDL_SetError("%s: Unsupported audio format", "pulseaudio");
|
return SDL_SetError("%s: Unsupported audio format", "pulseaudio");
|
||||||
}
|
}
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
paspec.format = format;
|
paspec.format = format;
|
||||||
|
|
||||||
/* Calculate the final parameters for this audio specification */
|
/* Calculate the final parameters for this audio specification */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
if (!iscapture) {
|
if (!iscapture) {
|
||||||
h->mixlen = this->spec.size;
|
h->mixlen = _this->spec.size;
|
||||||
h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen);
|
h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen);
|
||||||
if (h->mixbuf == NULL) {
|
if (h->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
|
SDL_memset(h->mixbuf, _this->spec.silence, _this->spec.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
paspec.channels = this->spec.channels;
|
paspec.channels = _this->spec.channels;
|
||||||
paspec.rate = this->spec.freq;
|
paspec.rate = _this->spec.freq;
|
||||||
|
|
||||||
/* Reduced prebuffering compared to the defaults. */
|
/* Reduced prebuffering compared to the defaults. */
|
||||||
paattr.fragsize = this->spec.size;
|
paattr.fragsize = _this->spec.size;
|
||||||
paattr.tlength = h->mixlen;
|
paattr.tlength = h->mixlen;
|
||||||
paattr.prebuf = -1;
|
paattr.prebuf = -1;
|
||||||
paattr.maxlength = -1;
|
paattr.maxlength = -1;
|
||||||
@@ -603,13 +603,13 @@ static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("Could not connect to PulseAudio server");
|
return SDL_SetError("Could not connect to PulseAudio server");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FindDeviceName(h, iscapture, this->handle)) {
|
if (!FindDeviceName(h, iscapture, _this->handle)) {
|
||||||
return SDL_SetError("Requested PulseAudio sink/source missing?");
|
return SDL_SetError("Requested PulseAudio sink/source missing?");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The SDL ALSA output hints us that we use Windows' channel mapping */
|
/* The SDL ALSA output hints us that we use Windows' channel mapping */
|
||||||
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
|
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
|
||||||
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
|
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, _this->spec.channels,
|
||||||
PA_CHANNEL_MAP_WAVEEX);
|
PA_CHANNEL_MAP_WAVEEX);
|
||||||
|
|
||||||
name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||||
|
|||||||
@@ -27,9 +27,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
char *device_name;
|
char *device_name;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ QSA_SetError(const char *fn, int status)
|
|||||||
|
|
||||||
/* !!! FIXME: does this need to be here? Does the SDL version not work? */
|
/* !!! FIXME: does this need to be here? Does the SDL version not work? */
|
||||||
static void
|
static void
|
||||||
QSA_ThreadInit(_THIS)
|
QSA_ThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Increase default 10 priority to 25 to avoid jerky sound */
|
/* Increase default 10 priority to 25 to avoid jerky sound */
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
@@ -111,7 +111,7 @@ QSA_InitAudioParams(snd_pcm_channel_params_t * cpars)
|
|||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void
|
static void
|
||||||
QSA_WaitDevice(_THIS)
|
QSA_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@@ -119,8 +119,8 @@ QSA_WaitDevice(_THIS)
|
|||||||
/* If timeout occured than something wrong with hardware or driver */
|
/* If timeout occured than something wrong with hardware or driver */
|
||||||
/* For example, Vortex 8820 audio driver stucks on second DAC because */
|
/* For example, Vortex 8820 audio driver stucks on second DAC because */
|
||||||
/* it doesn't exist ! */
|
/* it doesn't exist ! */
|
||||||
result = SDL_IOReady(this->hidden->audio_fd,
|
result = SDL_IOReady(_this->hidden->audio_fd,
|
||||||
this->hidden->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
_this->hidden->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
||||||
2 * 1000);
|
2 * 1000);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case -1:
|
case -1:
|
||||||
@@ -128,16 +128,16 @@ QSA_WaitDevice(_THIS)
|
|||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
SDL_SetError("QSA: timeout on buffer waiting occured");
|
SDL_SetError("QSA: timeout on buffer waiting occured");
|
||||||
this->hidden->timeout_on_wait = 1;
|
_this->hidden->timeout_on_wait = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->hidden->timeout_on_wait = 0;
|
_this->hidden->timeout_on_wait = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
QSA_PlayDevice(_THIS)
|
QSA_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
snd_pcm_channel_status_t cstatus;
|
snd_pcm_channel_status_t cstatus;
|
||||||
int written;
|
int written;
|
||||||
@@ -145,23 +145,23 @@ QSA_PlayDevice(_THIS)
|
|||||||
int towrite;
|
int towrite;
|
||||||
void *pcmbuffer;
|
void *pcmbuffer;
|
||||||
|
|
||||||
if (!SDL_AtomicGet(&this->enabled) || !this->hidden) {
|
if (!SDL_AtomicGet(&_this->enabled) || !_this->hidden) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
towrite = this->spec.size;
|
towrite = _this->spec.size;
|
||||||
pcmbuffer = this->hidden->pcm_buf;
|
pcmbuffer = _this->hidden->pcm_buf;
|
||||||
|
|
||||||
/* Write the audio data, checking for EAGAIN (buffer full) and underrun */
|
/* Write the audio data, checking for EAGAIN (buffer full) and underrun */
|
||||||
do {
|
do {
|
||||||
written =
|
written =
|
||||||
snd_pcm_plugin_write(this->hidden->audio_handle, pcmbuffer,
|
snd_pcm_plugin_write(_this->hidden->audio_handle, pcmbuffer,
|
||||||
towrite);
|
towrite);
|
||||||
if (written != towrite) {
|
if (written != towrite) {
|
||||||
/* Check if samples playback got stuck somewhere in hardware or in */
|
/* Check if samples playback got stuck somewhere in hardware or in */
|
||||||
/* the audio device driver */
|
/* the audio device driver */
|
||||||
if ((errno == EAGAIN) && (written == 0)) {
|
if ((errno == EAGAIN) && (written == 0)) {
|
||||||
if (this->hidden->timeout_on_wait != 0) {
|
if (_this->hidden->timeout_on_wait != 0) {
|
||||||
SDL_SetError("QSA: buffer playback timeout");
|
SDL_SetError("QSA: buffer playback timeout");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -174,19 +174,19 @@ QSA_PlayDevice(_THIS)
|
|||||||
|
|
||||||
/* if we wrote some data */
|
/* if we wrote some data */
|
||||||
towrite -= written;
|
towrite -= written;
|
||||||
pcmbuffer += written * this->spec.channels;
|
pcmbuffer += written * _this->spec.channels;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if ((errno == EINVAL) || (errno == EIO)) {
|
if ((errno == EINVAL) || (errno == EIO)) {
|
||||||
SDL_zero(cstatus);
|
SDL_zero(cstatus);
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
|
cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
|
||||||
} else {
|
} else {
|
||||||
cstatus.channel = SND_PCM_CHANNEL_CAPTURE;
|
cstatus.channel = SND_PCM_CHANNEL_CAPTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
status =
|
status =
|
||||||
snd_pcm_plugin_status(this->hidden->audio_handle,
|
snd_pcm_plugin_status(_this->hidden->audio_handle,
|
||||||
&cstatus);
|
&cstatus);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
QSA_SetError("snd_pcm_plugin_status", status);
|
QSA_SetError("snd_pcm_plugin_status", status);
|
||||||
@@ -195,14 +195,14 @@ QSA_PlayDevice(_THIS)
|
|||||||
|
|
||||||
if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) ||
|
if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) ||
|
||||||
(cstatus.status == SND_PCM_STATUS_READY)) {
|
(cstatus.status == SND_PCM_STATUS_READY)) {
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
status =
|
status =
|
||||||
snd_pcm_plugin_prepare(this->hidden->
|
snd_pcm_plugin_prepare(_this->hidden->
|
||||||
audio_handle,
|
audio_handle,
|
||||||
SND_PCM_CHANNEL_PLAYBACK);
|
SND_PCM_CHANNEL_PLAYBACK);
|
||||||
} else {
|
} else {
|
||||||
status =
|
status =
|
||||||
snd_pcm_plugin_prepare(this->hidden->
|
snd_pcm_plugin_prepare(_this->hidden->
|
||||||
audio_handle,
|
audio_handle,
|
||||||
SND_PCM_CHANNEL_CAPTURE);
|
SND_PCM_CHANNEL_CAPTURE);
|
||||||
}
|
}
|
||||||
@@ -219,46 +219,46 @@ QSA_PlayDevice(_THIS)
|
|||||||
} else {
|
} else {
|
||||||
/* we wrote all remaining data */
|
/* we wrote all remaining data */
|
||||||
towrite -= written;
|
towrite -= written;
|
||||||
pcmbuffer += written * this->spec.channels;
|
pcmbuffer += written * _this->spec.channels;
|
||||||
}
|
}
|
||||||
} while ((towrite > 0) && SDL_AtomicGet(&this->enabled));
|
} while ((towrite > 0) && SDL_AtomicGet(&_this->enabled));
|
||||||
|
|
||||||
/* If we couldn't write, assume fatal error for now */
|
/* If we couldn't write, assume fatal error for now */
|
||||||
if (towrite != 0) {
|
if (towrite != 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *
|
static Uint8 *
|
||||||
QSA_GetDeviceBuf(_THIS)
|
QSA_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->pcm_buf;
|
return _this->hidden->pcm_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
QSA_CloseDevice(_THIS)
|
QSA_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->audio_handle != NULL) {
|
if (_this->hidden->audio_handle != NULL) {
|
||||||
#if _NTO_VERSION < 710
|
#if _NTO_VERSION < 710
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
/* Finish playing available samples */
|
/* Finish playing available samples */
|
||||||
snd_pcm_plugin_flush(this->hidden->audio_handle,
|
snd_pcm_plugin_flush(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_PLAYBACK);
|
SND_PCM_CHANNEL_PLAYBACK);
|
||||||
} else {
|
} else {
|
||||||
/* Cancel unread samples during capture */
|
/* Cancel unread samples during capture */
|
||||||
snd_pcm_plugin_flush(this->hidden->audio_handle,
|
snd_pcm_plugin_flush(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_CAPTURE);
|
SND_PCM_CHANNEL_CAPTURE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
snd_pcm_close(this->hidden->audio_handle);
|
snd_pcm_close(_this->hidden->audio_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(this->hidden->pcm_buf);
|
SDL_free(_this->hidden->pcm_buf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
QSA_OpenDevice(_THIS, const char *devname)
|
QSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* !!! FIXME: SDL2 used to pass this handle. What's the alternative? */
|
/* !!! FIXME: SDL2 used to pass this handle. What's the alternative? */
|
||||||
@@ -272,15 +272,15 @@ QSA_OpenDevice(_THIS, const char *devname)
|
|||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
snd_pcm_channel_setup_t csetup;
|
snd_pcm_channel_setup_t csetup;
|
||||||
snd_pcm_channel_params_t cparams;
|
snd_pcm_channel_params_t cparams;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
this->hidden =
|
_this->hidden =
|
||||||
(struct SDL_PrivateAudioData *) SDL_calloc(1,
|
(struct SDL_PrivateAudioData *) SDL_calloc(1,
|
||||||
(sizeof
|
(sizeof
|
||||||
(struct
|
(struct
|
||||||
SDL_PrivateAudioData)));
|
SDL_PrivateAudioData)));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,31 +288,31 @@ QSA_OpenDevice(_THIS, const char *devname)
|
|||||||
QSA_InitAudioParams(&cparams);
|
QSA_InitAudioParams(&cparams);
|
||||||
|
|
||||||
/* Initialize channel direction: capture or playback */
|
/* Initialize channel direction: capture or playback */
|
||||||
this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
_this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
||||||
|
|
||||||
if (device != NULL) {
|
if (device != NULL) {
|
||||||
/* Open requested audio device */
|
/* Open requested audio device */
|
||||||
this->hidden->deviceno = device->deviceno;
|
_this->hidden->deviceno = device->deviceno;
|
||||||
this->hidden->cardno = device->cardno;
|
_this->hidden->cardno = device->cardno;
|
||||||
status = snd_pcm_open(&this->hidden->audio_handle,
|
status = snd_pcm_open(&_this->hidden->audio_handle,
|
||||||
device->cardno, device->deviceno,
|
device->cardno, device->deviceno,
|
||||||
iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK);
|
iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK);
|
||||||
} else {
|
} else {
|
||||||
/* Open system default audio device */
|
/* Open system default audio device */
|
||||||
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
|
status = snd_pcm_open_preferred(&_this->hidden->audio_handle,
|
||||||
&this->hidden->cardno,
|
&_this->hidden->cardno,
|
||||||
&this->hidden->deviceno,
|
&_this->hidden->deviceno,
|
||||||
iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK);
|
iscapture ? SND_PCM_OPEN_CAPTURE : SND_PCM_OPEN_PLAYBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if requested device is opened */
|
/* Check if requested device is opened */
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
this->hidden->audio_handle = NULL;
|
_this->hidden->audio_handle = NULL;
|
||||||
return QSA_SetError("snd_pcm_open", status);
|
return QSA_SetError("snd_pcm_open", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try for a closest match on audio format */
|
/* Try for a closest match on audio format */
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
/* if match found set format to equivalent QSA format */
|
/* if match found set format to equivalent QSA format */
|
||||||
switch (test_format) {
|
switch (test_format) {
|
||||||
@@ -336,44 +336,44 @@ QSA_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("QSA: Couldn't find any hardware audio formats");
|
return SDL_SetError("QSA: Couldn't find any hardware audio formats");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
|
|
||||||
/* Set the audio format */
|
/* Set the audio format */
|
||||||
cparams.format.format = format;
|
cparams.format.format = format;
|
||||||
|
|
||||||
/* Set mono/stereo/4ch/6ch/8ch audio */
|
/* Set mono/stereo/4ch/6ch/8ch audio */
|
||||||
cparams.format.voices = this->spec.channels;
|
cparams.format.voices = _this->spec.channels;
|
||||||
|
|
||||||
/* Set rate */
|
/* Set rate */
|
||||||
cparams.format.rate = this->spec.freq;
|
cparams.format.rate = _this->spec.freq;
|
||||||
|
|
||||||
/* Setup the transfer parameters according to cparams */
|
/* Setup the transfer parameters according to cparams */
|
||||||
status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams);
|
status = snd_pcm_plugin_params(_this->hidden->audio_handle, &cparams);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
return QSA_SetError("snd_pcm_plugin_params", status);
|
return QSA_SetError("snd_pcm_plugin_params", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure channel is setup right one last time */
|
/* Make sure channel is setup right one last time */
|
||||||
SDL_zero(csetup);
|
SDL_zero(csetup);
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
|
csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
|
||||||
} else {
|
} else {
|
||||||
csetup.channel = SND_PCM_CHANNEL_CAPTURE;
|
csetup.channel = SND_PCM_CHANNEL_CAPTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup an audio channel */
|
/* Setup an audio channel */
|
||||||
if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) {
|
if (snd_pcm_plugin_setup(_this->hidden->audio_handle, &csetup) < 0) {
|
||||||
return SDL_SetError("QSA: Unable to setup channel");
|
return SDL_SetError("QSA: Unable to setup channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the final parameters for this audio specification */
|
/* Calculate the final parameters for this audio specification */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
this->hidden->pcm_len = this->spec.size;
|
_this->hidden->pcm_len = _this->spec.size;
|
||||||
|
|
||||||
if (this->hidden->pcm_len == 0) {
|
if (_this->hidden->pcm_len == 0) {
|
||||||
this->hidden->pcm_len =
|
_this->hidden->pcm_len =
|
||||||
csetup.buf.block.frag_size * this->spec.channels *
|
csetup.buf.block.frag_size * _this->spec.channels *
|
||||||
(snd_pcm_format_width(format) / 8);
|
(snd_pcm_format_width(format) / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,39 +382,39 @@ QSA_OpenDevice(_THIS, const char *devname)
|
|||||||
* (Note that buffer size must be a multiple of fragment size, so find
|
* (Note that buffer size must be a multiple of fragment size, so find
|
||||||
* closest multiple)
|
* closest multiple)
|
||||||
*/
|
*/
|
||||||
this->hidden->pcm_buf =
|
_this->hidden->pcm_buf =
|
||||||
(Uint8 *) SDL_malloc(this->hidden->pcm_len);
|
(Uint8 *) SDL_malloc(_this->hidden->pcm_len);
|
||||||
if (this->hidden->pcm_buf == NULL) {
|
if (_this->hidden->pcm_buf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden->pcm_buf, this->spec.silence,
|
SDL_memset(_this->hidden->pcm_buf, _this->spec.silence,
|
||||||
this->hidden->pcm_len);
|
_this->hidden->pcm_len);
|
||||||
|
|
||||||
/* get the file descriptor */
|
/* get the file descriptor */
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
this->hidden->audio_fd =
|
_this->hidden->audio_fd =
|
||||||
snd_pcm_file_descriptor(this->hidden->audio_handle,
|
snd_pcm_file_descriptor(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_PLAYBACK);
|
SND_PCM_CHANNEL_PLAYBACK);
|
||||||
} else {
|
} else {
|
||||||
this->hidden->audio_fd =
|
_this->hidden->audio_fd =
|
||||||
snd_pcm_file_descriptor(this->hidden->audio_handle,
|
snd_pcm_file_descriptor(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_CAPTURE);
|
SND_PCM_CHANNEL_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->audio_fd < 0) {
|
if (_this->hidden->audio_fd < 0) {
|
||||||
return QSA_SetError("snd_pcm_file_descriptor", status);
|
return QSA_SetError("snd_pcm_file_descriptor", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare an audio channel */
|
/* Prepare an audio channel */
|
||||||
if (!this->hidden->iscapture) {
|
if (!_this->hidden->iscapture) {
|
||||||
/* Prepare audio playback */
|
/* Prepare audio playback */
|
||||||
status =
|
status =
|
||||||
snd_pcm_plugin_prepare(this->hidden->audio_handle,
|
snd_pcm_plugin_prepare(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_PLAYBACK);
|
SND_PCM_CHANNEL_PLAYBACK);
|
||||||
} else {
|
} else {
|
||||||
/* Prepare audio capture */
|
/* Prepare audio capture */
|
||||||
status =
|
status =
|
||||||
snd_pcm_plugin_prepare(this->hidden->audio_handle,
|
snd_pcm_plugin_prepare(_this->hidden->audio_handle,
|
||||||
SND_PCM_CHANNEL_CAPTURE);
|
SND_PCM_CHANNEL_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice* this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* SDL capture state */
|
/* SDL capture state */
|
||||||
|
|||||||
@@ -149,42 +149,42 @@ static int LoadSNDIOLibrary(void)
|
|||||||
|
|
||||||
#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */
|
#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */
|
||||||
|
|
||||||
static void SNDIO_WaitDevice(_THIS)
|
static void SNDIO_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* no-op; SNDIO_sio_write() blocks if necessary. */
|
/* no-op; SNDIO_sio_write() blocks if necessary. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SNDIO_PlayDevice(_THIS)
|
static void SNDIO_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
const int written = SNDIO_sio_write(this->hidden->dev,
|
const int written = SNDIO_sio_write(_this->hidden->dev,
|
||||||
this->hidden->mixbuf,
|
_this->hidden->mixbuf,
|
||||||
this->hidden->mixlen);
|
_this->hidden->mixlen);
|
||||||
|
|
||||||
/* If we couldn't write, assume fatal error for now */
|
/* If we couldn't write, assume fatal error for now */
|
||||||
if (written == 0) {
|
if (written == 0) {
|
||||||
SDL_OpenedAudioDeviceDisconnected(this);
|
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_AUDIO
|
#ifdef DEBUG_AUDIO
|
||||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int SNDIO_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
size_t r;
|
size_t r;
|
||||||
int revents;
|
int revents;
|
||||||
int nfds;
|
int nfds;
|
||||||
|
|
||||||
/* Emulate a blocking read */
|
/* Emulate a blocking read */
|
||||||
r = SNDIO_sio_read(this->hidden->dev, buffer, buflen);
|
r = SNDIO_sio_read(_this->hidden->dev, buffer, buflen);
|
||||||
while (r == 0 && !SNDIO_sio_eof(this->hidden->dev)) {
|
while (r == 0 && !SNDIO_sio_eof(_this->hidden->dev)) {
|
||||||
nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN);
|
nfds = SNDIO_sio_pollfd(_this->hidden->dev, _this->hidden->pfd, POLLIN);
|
||||||
if (nfds <= 0 || poll(this->hidden->pfd, nfds, INFTIM) < 0) {
|
if (nfds <= 0 || poll(_this->hidden->pfd, nfds, INFTIM) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
revents = SNDIO_sio_revents(this->hidden->dev, this->hidden->pfd);
|
revents = SNDIO_sio_revents(_this->hidden->dev, _this->hidden->pfd);
|
||||||
if (revents & POLLIN) {
|
if (revents & POLLIN) {
|
||||||
r = SNDIO_sio_read(this->hidden->dev, buffer, buflen);
|
r = SNDIO_sio_read(_this->hidden->dev, buffer, buflen);
|
||||||
}
|
}
|
||||||
if (revents & POLLHUP) {
|
if (revents & POLLHUP) {
|
||||||
break;
|
break;
|
||||||
@@ -193,83 +193,83 @@ static int SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
|||||||
return (int)r;
|
return (int)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SNDIO_FlushCapture(_THIS)
|
static void SNDIO_FlushCapture(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
while (SNDIO_sio_read(this->hidden->dev, buf, sizeof(buf)) != 0) {
|
while (SNDIO_sio_read(_this->hidden->dev, buf, sizeof(buf)) != 0) {
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *SNDIO_GetDeviceBuf(_THIS)
|
static Uint8 *SNDIO_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbuf;
|
return _this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SNDIO_CloseDevice(_THIS)
|
static void SNDIO_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->pfd != NULL) {
|
if (_this->hidden->pfd != NULL) {
|
||||||
SDL_free(this->hidden->pfd);
|
SDL_free(_this->hidden->pfd);
|
||||||
}
|
}
|
||||||
if (this->hidden->dev != NULL) {
|
if (_this->hidden->dev != NULL) {
|
||||||
SNDIO_sio_stop(this->hidden->dev);
|
SNDIO_sio_stop(_this->hidden->dev);
|
||||||
SNDIO_sio_close(this->hidden->dev);
|
SNDIO_sio_close(_this->hidden->dev);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(_this->hidden->mixbuf);
|
||||||
SDL_free(this->hidden);
|
SDL_free(_this->hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SNDIO_OpenDevice(_THIS, const char *devname)
|
static int SNDIO_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
struct sio_par par;
|
struct sio_par par;
|
||||||
SDL_bool iscapture = this->iscapture;
|
SDL_bool iscapture = _this->iscapture;
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)
|
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||||
SDL_malloc(sizeof(*this->hidden));
|
SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_zerop(this->hidden);
|
SDL_zerop(_this->hidden);
|
||||||
|
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
|
|
||||||
/* Capture devices must be non-blocking for SNDIO_FlushCapture */
|
/* Capture devices must be non-blocking for SNDIO_FlushCapture */
|
||||||
this->hidden->dev = SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY,
|
_this->hidden->dev = SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY,
|
||||||
iscapture ? SIO_REC : SIO_PLAY, iscapture);
|
iscapture ? SIO_REC : SIO_PLAY, iscapture);
|
||||||
if (this->hidden->dev == NULL) {
|
if (_this->hidden->dev == NULL) {
|
||||||
return SDL_SetError("sio_open() failed");
|
return SDL_SetError("sio_open() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the pollfd array for capture devices */
|
/* Allocate the pollfd array for capture devices */
|
||||||
if (iscapture) {
|
if (iscapture) {
|
||||||
this->hidden->pfd = SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev));
|
_this->hidden->pfd = SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(_this->hidden->dev));
|
||||||
if (this->hidden->pfd == NULL) {
|
if (_this->hidden->pfd == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SNDIO_sio_initpar(&par);
|
SNDIO_sio_initpar(&par);
|
||||||
|
|
||||||
par.rate = this->spec.freq;
|
par.rate = _this->spec.freq;
|
||||||
par.pchan = this->spec.channels;
|
par.pchan = _this->spec.channels;
|
||||||
par.round = this->spec.samples;
|
par.round = _this->spec.samples;
|
||||||
par.appbufsz = par.round * 2;
|
par.appbufsz = par.round * 2;
|
||||||
|
|
||||||
/* Try for a closest match on audio format */
|
/* Try for a closest match on audio format */
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
if (!SDL_AUDIO_ISFLOAT(test_format)) {
|
if (!SDL_AUDIO_ISFLOAT(test_format)) {
|
||||||
par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
|
par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
|
||||||
par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
|
par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
|
||||||
par.bits = SDL_AUDIO_BITSIZE(test_format);
|
par.bits = SDL_AUDIO_BITSIZE(test_format);
|
||||||
|
|
||||||
if (SNDIO_sio_setpar(this->hidden->dev, &par) == 0) {
|
if (SNDIO_sio_setpar(_this->hidden->dev, &par) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) {
|
if (SNDIO_sio_getpar(_this->hidden->dev, &par) == 0) {
|
||||||
return SDL_SetError("sio_getpar() failed");
|
return SDL_SetError("sio_getpar() failed");
|
||||||
}
|
}
|
||||||
if (par.bps != SIO_BPS(par.bits)) {
|
if (par.bps != SIO_BPS(par.bits)) {
|
||||||
@@ -286,37 +286,37 @@ static int SNDIO_OpenDevice(_THIS, const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((par.bps == 4) && (par.sig) && (par.le)) {
|
if ((par.bps == 4) && (par.sig) && (par.le)) {
|
||||||
this->spec.format = SDL_AUDIO_S32LSB;
|
_this->spec.format = SDL_AUDIO_S32LSB;
|
||||||
} else if ((par.bps == 4) && (par.sig) && (!par.le)) {
|
} else if ((par.bps == 4) && (par.sig) && (!par.le)) {
|
||||||
this->spec.format = SDL_AUDIO_S32MSB;
|
_this->spec.format = SDL_AUDIO_S32MSB;
|
||||||
} else if ((par.bps == 2) && (par.sig) && (par.le)) {
|
} else if ((par.bps == 2) && (par.sig) && (par.le)) {
|
||||||
this->spec.format = SDL_AUDIO_S16LSB;
|
_this->spec.format = SDL_AUDIO_S16LSB;
|
||||||
} else if ((par.bps == 2) && (par.sig) && (!par.le)) {
|
} else if ((par.bps == 2) && (par.sig) && (!par.le)) {
|
||||||
this->spec.format = SDL_AUDIO_S16MSB;
|
_this->spec.format = SDL_AUDIO_S16MSB;
|
||||||
} else if ((par.bps == 1) && (par.sig)) {
|
} else if ((par.bps == 1) && (par.sig)) {
|
||||||
this->spec.format = SDL_AUDIO_S8;
|
_this->spec.format = SDL_AUDIO_S8;
|
||||||
} else if ((par.bps == 1) && (!par.sig)) {
|
} else if ((par.bps == 1) && (!par.sig)) {
|
||||||
this->spec.format = SDL_AUDIO_U8;
|
_this->spec.format = SDL_AUDIO_U8;
|
||||||
} else {
|
} else {
|
||||||
return SDL_SetError("sndio: Got unsupported hardware audio format.");
|
return SDL_SetError("sndio: Got unsupported hardware audio format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->spec.freq = par.rate;
|
_this->spec.freq = par.rate;
|
||||||
this->spec.channels = par.pchan;
|
_this->spec.channels = par.pchan;
|
||||||
this->spec.samples = par.round;
|
_this->spec.samples = par.round;
|
||||||
|
|
||||||
/* Calculate the final parameters for this audio specification */
|
/* Calculate the final parameters for this audio specification */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate mixing buffer */
|
/* Allocate mixing buffer */
|
||||||
this->hidden->mixlen = this->spec.size;
|
_this->hidden->mixlen = _this->spec.size;
|
||||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen);
|
||||||
if (this->hidden->mixbuf == NULL) {
|
if (_this->hidden->mixbuf == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
|
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->hidden->mixlen);
|
||||||
|
|
||||||
if (!SNDIO_sio_start(this->hidden->dev)) {
|
if (!SNDIO_sio_start(_this->hidden->dev)) {
|
||||||
return SDL_SetError("sio_start() failed");
|
return SDL_SetError("sio_start() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
/* The audio device handle */
|
/* The audio device handle */
|
||||||
|
|||||||
@@ -39,41 +39,41 @@
|
|||||||
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
||||||
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
||||||
|
|
||||||
static int VITAAUD_OpenCaptureDevice(_THIS)
|
static int VITAAUD_OpenCaptureDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
this->spec.freq = 16000;
|
_this->spec.freq = 16000;
|
||||||
this->spec.samples = 512;
|
_this->spec.samples = 512;
|
||||||
this->spec.channels = 1;
|
_this->spec.channels = 1;
|
||||||
|
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE, 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
|
_this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE, 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
|
||||||
|
|
||||||
if (this->hidden->port < 0) {
|
if (_this->hidden->port < 0) {
|
||||||
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
|
return SDL_SetError("Couldn't open audio in port: %x", _this->hidden->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VITAAUD_OpenDevice(_THIS, const char *devname)
|
static int VITAAUD_OpenDevice(SDL_AudioDevice *_this, const char *devname)
|
||||||
{
|
{
|
||||||
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
|
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
|
||||||
int vols[2] = { SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME };
|
int vols[2] = { SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME };
|
||||||
SDL_AudioFormat test_format;
|
SDL_AudioFormat test_format;
|
||||||
const SDL_AudioFormat *closefmts;
|
const SDL_AudioFormat *closefmts;
|
||||||
|
|
||||||
this->hidden = (struct SDL_PrivateAudioData *)
|
_this->hidden = (struct SDL_PrivateAudioData *)
|
||||||
SDL_malloc(sizeof(*this->hidden));
|
SDL_malloc(sizeof(*_this->hidden));
|
||||||
if (this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return SDL_OutOfMemory();
|
||||||
}
|
}
|
||||||
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
|
SDL_memset(_this->hidden, 0, sizeof(*_this->hidden));
|
||||||
|
|
||||||
closefmts = SDL_ClosestAudioFormats(this->spec.format);
|
closefmts = SDL_ClosestAudioFormats(_this->spec.format);
|
||||||
while ((test_format = *(closefmts++)) != 0) {
|
while ((test_format = *(closefmts++)) != 0) {
|
||||||
if (test_format == SDL_AUDIO_S16LSB) {
|
if (test_format == SDL_AUDIO_S16LSB) {
|
||||||
this->spec.format = test_format;
|
_this->spec.format = test_format;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,103 +82,103 @@ static int VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||||||
return SDL_SetError("Unsupported audio format");
|
return SDL_SetError("Unsupported audio format");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
return VITAAUD_OpenCaptureDevice(this);
|
return VITAAUD_OpenCaptureDevice(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The sample count must be a multiple of 64. */
|
/* The sample count must be a multiple of 64. */
|
||||||
this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(this->spec.samples);
|
_this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(_this->spec.samples);
|
||||||
|
|
||||||
/* Update the fragment size as size in bytes. */
|
/* Update the fragment size as size in bytes. */
|
||||||
SDL_CalculateAudioSpec(&this->spec);
|
SDL_CalculateAudioSpec(&_this->spec);
|
||||||
|
|
||||||
/* Allocate the mixing buffer. Its size and starting address must
|
/* Allocate the mixing buffer. Its size and starting address must
|
||||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||||
64, so spec->size should be a multiple of 64 as well. */
|
64, so spec->size should be a multiple of 64 as well. */
|
||||||
mixlen = this->spec.size * NUM_BUFFERS;
|
mixlen = _this->spec.size * NUM_BUFFERS;
|
||||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
_this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||||
if (this->hidden->rawbuf == NULL) {
|
if (_this->hidden->rawbuf == NULL) {
|
||||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the hardware channel. */
|
/* Setup the hardware channel. */
|
||||||
if (this->spec.channels == 1) {
|
if (_this->spec.channels == 1) {
|
||||||
format = SCE_AUDIO_OUT_MODE_MONO;
|
format = SCE_AUDIO_OUT_MODE_MONO;
|
||||||
} else {
|
} else {
|
||||||
format = SCE_AUDIO_OUT_MODE_STEREO;
|
format = SCE_AUDIO_OUT_MODE_STEREO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->spec.freq < 48000) {
|
if (_this->spec.freq < 48000) {
|
||||||
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
|
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
|
_this->hidden->port = sceAudioOutOpenPort(port, _this->spec.samples, _this->spec.freq, format);
|
||||||
if (this->hidden->port < 0) {
|
if (_this->hidden->port < 0) {
|
||||||
free(this->hidden->rawbuf);
|
free(_this->hidden->rawbuf);
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
|
return SDL_SetError("Couldn't open audio out port: %x", _this->hidden->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
sceAudioOutSetVolume(_this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||||
|
|
||||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
SDL_memset(_this->hidden->rawbuf, 0, mixlen);
|
||||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
_this->hidden->mixbufs[i] = &_this->hidden->rawbuf[i * _this->spec.size];
|
||||||
}
|
}
|
||||||
|
|
||||||
this->hidden->next_buffer = 0;
|
_this->hidden->next_buffer = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VITAAUD_PlayDevice(_THIS)
|
static void VITAAUD_PlayDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
Uint8 *mixbuf = _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
|
|
||||||
sceAudioOutOutput(this->hidden->port, mixbuf);
|
sceAudioOutOutput(_this->hidden->port, mixbuf);
|
||||||
|
|
||||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
_this->hidden->next_buffer = (_this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void VITAAUD_WaitDevice(_THIS)
|
static void VITAAUD_WaitDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Because we block when sending audio, there's no need for this function to do anything. */
|
/* Because we block when sending audio, there's no need for this function to do anything. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
|
static Uint8 *VITAAUD_GetDeviceBuf(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
return _this->hidden->mixbufs[_this->hidden->next_buffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VITAAUD_CloseDevice(_THIS)
|
static void VITAAUD_CloseDevice(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
if (this->hidden->port >= 0) {
|
if (_this->hidden->port >= 0) {
|
||||||
if (this->iscapture) {
|
if (_this->iscapture) {
|
||||||
sceAudioInReleasePort(this->hidden->port);
|
sceAudioInReleasePort(_this->hidden->port);
|
||||||
} else {
|
} else {
|
||||||
sceAudioOutReleasePort(this->hidden->port);
|
sceAudioOutReleasePort(_this->hidden->port);
|
||||||
}
|
}
|
||||||
this->hidden->port = -1;
|
_this->hidden->port = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->iscapture && this->hidden->rawbuf != NULL) {
|
if (!_this->iscapture && _this->hidden->rawbuf != NULL) {
|
||||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
free(_this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||||
this->hidden->rawbuf = NULL;
|
_this->hidden->rawbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
static int VITAAUD_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
SDL_assert(buflen == this->spec.size);
|
SDL_assert(buflen == _this->spec.size);
|
||||||
ret = sceAudioInInput(this->hidden->port, buffer);
|
ret = sceAudioInInput(_this->hidden->port, buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return SDL_SetError("Failed to capture from device: %x", ret);
|
return SDL_SetError("Failed to capture from device: %x", ret);
|
||||||
}
|
}
|
||||||
return this->spec.size;
|
return _this->spec.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VITAAUD_ThreadInit(_THIS)
|
static void VITAAUD_ThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Increase the priority of this audio thread by 1 to put it
|
/* Increase the priority of this audio thread by 1 to put it
|
||||||
ahead of other SDL threads. */
|
ahead of other SDL threads. */
|
||||||
|
|||||||
@@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
|
|
||||||
#define NUM_BUFFERS 2
|
#define NUM_BUFFERS 2
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
|
|||||||
+154
-154
File diff suppressed because it is too large
Load Diff
@@ -29,13 +29,6 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
#include "../SDL_sysaudio.h"
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
#else
|
|
||||||
#define _THIS SDL_AudioDevice *this
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData
|
struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
SDL_AtomicInt refcount;
|
SDL_AtomicInt refcount;
|
||||||
@@ -56,18 +49,18 @@ struct SDL_PrivateAudioData
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* win32 and winrt implementations call into these. */
|
/* win32 and winrt implementations call into these. */
|
||||||
int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream);
|
int WASAPI_PrepDevice(SDL_AudioDevice *_this, const SDL_bool updatestream);
|
||||||
void WASAPI_RefDevice(_THIS);
|
void WASAPI_RefDevice(SDL_AudioDevice *_this);
|
||||||
void WASAPI_UnrefDevice(_THIS);
|
void WASAPI_UnrefDevice(SDL_AudioDevice *_this);
|
||||||
|
|
||||||
/* These are functions that are implemented differently for Windows vs WinRT. */
|
/* These are functions that are implemented differently for Windows vs WinRT. */
|
||||||
int WASAPI_PlatformInit(void);
|
int WASAPI_PlatformInit(void);
|
||||||
void WASAPI_PlatformDeinit(void);
|
void WASAPI_PlatformDeinit(void);
|
||||||
void WASAPI_EnumerateEndpoints(void);
|
void WASAPI_EnumerateEndpoints(void);
|
||||||
int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture);
|
int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture);
|
||||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery);
|
int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery);
|
||||||
void WASAPI_PlatformThreadInit(_THIS);
|
void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this);
|
||||||
void WASAPI_PlatformThreadDeinit(_THIS);
|
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this);
|
||||||
void WASAPI_PlatformDeleteActivationHandler(void *handler);
|
void WASAPI_PlatformDeleteActivationHandler(void *handler);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -75,55 +75,55 @@ void WASAPI_PlatformDeinit(void)
|
|||||||
SDL_IMMDevice_Quit();
|
SDL_IMMDevice_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WASAPI_PlatformThreadInit(_THIS)
|
void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* this thread uses COM. */
|
/* this thread uses COM. */
|
||||||
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
||||||
this->hidden->coinitialized = SDL_TRUE;
|
_this->hidden->coinitialized = SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set this thread to very high "Pro Audio" priority. */
|
/* Set this thread to very high "Pro Audio" priority. */
|
||||||
if (pAvSetMmThreadCharacteristicsW) {
|
if (pAvSetMmThreadCharacteristicsW) {
|
||||||
DWORD idx = 0;
|
DWORD idx = 0;
|
||||||
this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
_this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WASAPI_PlatformThreadDeinit(_THIS)
|
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
/* Set this thread back to normal priority. */
|
/* Set this thread back to normal priority. */
|
||||||
if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
|
if (_this->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||||
pAvRevertMmThreadCharacteristics(this->hidden->task);
|
pAvRevertMmThreadCharacteristics(_this->hidden->task);
|
||||||
this->hidden->task = NULL;
|
_this->hidden->task = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->hidden->coinitialized) {
|
if (_this->hidden->coinitialized) {
|
||||||
WIN_CoUninitialize();
|
WIN_CoUninitialize();
|
||||||
this->hidden->coinitialized = SDL_FALSE;
|
_this->hidden->coinitialized = SDL_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery)
|
||||||
{
|
{
|
||||||
IMMDevice *device = NULL;
|
IMMDevice *device = NULL;
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
|
|
||||||
if (SDL_IMMDevice_Get(this->hidden->devid, &device, this->iscapture) < 0) {
|
if (SDL_IMMDevice_Get(_this->hidden->devid, &device, _this->iscapture) < 0) {
|
||||||
this->hidden->client = NULL;
|
_this->hidden->client = NULL;
|
||||||
return -1; /* This is already set by SDL_IMMDevice_Get */
|
return -1; /* This is already set by SDL_IMMDevice_Get */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is not async in standard win32, yay! */
|
/* this is not async in standard win32, yay! */
|
||||||
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&this->hidden->client);
|
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&_this->hidden->client);
|
||||||
IMMDevice_Release(device);
|
IMMDevice_Release(device);
|
||||||
|
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
SDL_assert(this->hidden->client == NULL);
|
SDL_assert(_this->hidden->client == NULL);
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_assert(this->hidden->client != NULL);
|
SDL_assert(_this->hidden->client != NULL);
|
||||||
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
|
if (WASAPI_PrepDevice(_this, isrecovery) == -1) { /* not async, fire it right away. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
|||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
int WASAPI_ActivateDevice(SDL_AudioDevice *_this, const SDL_bool isrecovery)
|
||||||
{
|
{
|
||||||
LPCWSTR devid = _this->hidden->devid;
|
LPCWSTR devid = _this->hidden->devid;
|
||||||
Platform::String ^ defdevid;
|
Platform::String ^ defdevid;
|
||||||
@@ -326,12 +326,12 @@ int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WASAPI_PlatformThreadInit(_THIS)
|
void WASAPI_PlatformThreadInit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||||
}
|
}
|
||||||
|
|
||||||
void WASAPI_PlatformThreadDeinit(_THIS)
|
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *_this)
|
||||||
{
|
{
|
||||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user