diff --git a/CMakeLists.txt b/CMakeLists.txt index 59bacf0f5..4cf6f2a23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2342,6 +2342,7 @@ elseif(VITA) SceCtrl_stub SceAppMgr_stub SceAudio_stub + SceAudioIn_stub SceSysmodule_stub SceDisplay_stub SceCtrl_stub diff --git a/src/audio/vita/SDL_vitaaudio.c b/src/audio/vita/SDL_vitaaudio.c index 948bc3667..88f4a3285 100644 --- a/src/audio/vita/SDL_vitaaudio.c +++ b/src/audio/vita/SDL_vitaaudio.c @@ -37,12 +37,28 @@ #include #include +#include #define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63) #define SCE_AUDIO_MAX_VOLUME 0x8000 -/* The tag name used by VITA audio */ -#define VITAAUD_DRIVER_NAME "vita" +static int +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 VITAAUD_OpenDevice(_THIS, const char *devname) @@ -59,8 +75,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname) SDL_memset(this->hidden, 0, sizeof(*this->hidden)); for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { - if ((test_format == AUDIO_U8) || - (test_format == AUDIO_S16)) { + if (test_format == AUDIO_S16LSB) { this->spec.format = test_format; break; } @@ -70,13 +85,8 @@ VITAAUD_OpenDevice(_THIS, const char *devname) return SDL_SetError("Unsupported audio format"); } - switch (this->spec.format & 0xff) { - case 8: - case 16: - this->spec.format = AUDIO_S16LSB; - break; - default: - return SDL_SetError("Unsupported audio format"); + if (this->iscapture) { + return VITAAUD_OpenCaptureDevice(this); } /* 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; } - this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); - if (this->hidden->channel < 0) { + this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); + if (this->hidden->port < 0) { free(this->hidden->rawbuf); 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); 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]; - sceAudioOutOutput(this->hidden->channel, mixbuf); + sceAudioOutOutput(this->hidden->port, mixbuf); 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. */ } + static Uint8 *VITAAUD_GetDeviceBuf(_THIS) { return this->hidden->mixbufs[this->hidden->next_buffer]; @@ -144,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS) static void VITAAUD_CloseDevice(_THIS) { - if (this->hidden->channel >= 0) { - sceAudioOutReleasePort(this->hidden->channel); - this->hidden->channel = -1; + if (this->hidden->port >= 0) { + if (this->iscapture) { + 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(). */ 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) { /* 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->ThreadInit = VITAAUD_ThreadInit; - /* VITA audio device */ - impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - /* + impl->CaptureFromDevice = VITAAUD_CaptureFromDevice; + + /* and the capabilities */ impl->HasCaptureSupport = SDL_TRUE; - impl->OnlyHasDefaultInputDevice = SDL_TRUE; - */ + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; + return SDL_TRUE; /* this audio target is available. */ } diff --git a/src/audio/vita/SDL_vitaaudio.h b/src/audio/vita/SDL_vitaaudio.h index 73870759b..a5601b28c 100644 --- a/src/audio/vita/SDL_vitaaudio.h +++ b/src/audio/vita/SDL_vitaaudio.h @@ -30,8 +30,8 @@ #define NUM_BUFFERS 2 struct SDL_PrivateAudioData { - /* The hardware output channel. */ - int channel; + /* The hardware input/output port. */ + int port; /* The raw allocated mixing buffer. */ Uint8 *rawbuf; /* Individual mixing buffers. */