Vita: add audio capture support

This commit is contained in:
Ivan Epifanov 2022-03-29 23:48:08 +03:00 committed by Sam Lantinga
parent 4d1905c9b6
commit 178ac19615
3 changed files with 55 additions and 27 deletions

View file

@ -2342,6 +2342,7 @@ elseif(VITA)
SceCtrl_stub SceCtrl_stub
SceAppMgr_stub SceAppMgr_stub
SceAudio_stub SceAudio_stub
SceAudioIn_stub
SceSysmodule_stub SceSysmodule_stub
SceDisplay_stub SceDisplay_stub
SceCtrl_stub SceCtrl_stub

View file

@ -37,12 +37,28 @@
#include <psp2/kernel/threadmgr.h> #include <psp2/kernel/threadmgr.h>
#include <psp2/audioout.h> #include <psp2/audioout.h>
#include <psp2/audioin.h>
#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
/* The tag name used by VITA audio */ static int
#define VITAAUD_DRIVER_NAME "vita" VITAAUD_OpenCaptureDevice(_THIS)
{
this->spec.freq = 16000;
this->spec.samples = 512;
this->spec.channels = 1;
SDL_CalculateAudioSpec(&this->spec);
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
if (this->hidden->port < 0) {
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
}
return 0;
}
static int static int
VITAAUD_OpenDevice(_THIS, const char *devname) VITAAUD_OpenDevice(_THIS, const char *devname)
@ -59,8 +75,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
SDL_memset(this->hidden, 0, sizeof(*this->hidden)); SDL_memset(this->hidden, 0, sizeof(*this->hidden));
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if ((test_format == AUDIO_U8) || if (test_format == AUDIO_S16LSB) {
(test_format == AUDIO_S16)) {
this->spec.format = test_format; this->spec.format = test_format;
break; break;
} }
@ -70,13 +85,8 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
return SDL_SetError("Unsupported audio format"); return SDL_SetError("Unsupported audio format");
} }
switch (this->spec.format & 0xff) { if (this->iscapture) {
case 8: return VITAAUD_OpenCaptureDevice(this);
case 16:
this->spec.format = AUDIO_S16LSB;
break;
default:
return SDL_SetError("Unsupported audio format");
} }
/* The sample count must be a multiple of 64. */ /* The sample count must be a multiple of 64. */
@ -105,14 +115,14 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
port = SCE_AUDIO_OUT_PORT_TYPE_BGM; port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
} }
this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
if (this->hidden->channel < 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 reserve hardware channel"); return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
} }
sceAudioOutSetVolume(this->hidden->channel, 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++) {
@ -127,7 +137,7 @@ static void VITAAUD_PlayDevice(_THIS)
{ {
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
sceAudioOutOutput(this->hidden->channel, 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;
} }
@ -137,6 +147,7 @@ static void VITAAUD_WaitDevice(_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(_THIS)
{ {
return this->hidden->mixbufs[this->hidden->next_buffer]; return this->hidden->mixbufs[this->hidden->next_buffer];
@ -144,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
static void VITAAUD_CloseDevice(_THIS) static void VITAAUD_CloseDevice(_THIS)
{ {
if (this->hidden->channel >= 0) { if (this->hidden->port >= 0) {
sceAudioOutReleasePort(this->hidden->channel); if (this->iscapture) {
this->hidden->channel = -1; sceAudioInReleasePort(this->hidden->port);
} else {
sceAudioOutReleasePort(this->hidden->port);
}
this->hidden->port = -1;
} }
if (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)
{
int ret;
SDL_assert(buflen == this->spec.size);
ret = sceAudioInInput(this->hidden->port, buffer);
if (ret < 0) {
return SDL_SetError("Failed to capture from device: %x", ret);
}
return this->spec.size;
}
static void VITAAUD_ThreadInit(_THIS) static void VITAAUD_ThreadInit(_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
@ -179,12 +205,13 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = VITAAUD_CloseDevice; impl->CloseDevice = VITAAUD_CloseDevice;
impl->ThreadInit = VITAAUD_ThreadInit; impl->ThreadInit = VITAAUD_ThreadInit;
/* VITA audio device */ impl->CaptureFromDevice = VITAAUD_CaptureFromDevice;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
/* /* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultInputDevice = SDL_TRUE; impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
*/ impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */ return SDL_TRUE; /* this audio target is available. */
} }

View file

@ -30,8 +30,8 @@
#define NUM_BUFFERS 2 #define NUM_BUFFERS 2
struct SDL_PrivateAudioData { struct SDL_PrivateAudioData {
/* The hardware output channel. */ /* The hardware input/output port. */
int channel; int port;
/* The raw allocated mixing buffer. */ /* The raw allocated mixing buffer. */
Uint8 *rawbuf; Uint8 *rawbuf;
/* Individual mixing buffers. */ /* Individual mixing buffers. */