Vita: add audio capture support
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 59bacf0..4cf6f2a 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 948bc36..88f4a32 100644
--- a/src/audio/vita/SDL_vitaaudio.c
+++ b/src/audio/vita/SDL_vitaaudio.c
@@ -37,12 +37,28 @@
#include <psp2/kernel/threadmgr.h>
#include <psp2/audioout.h>
+#include <psp2/audioin.h>
#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 7387075..a5601b2 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. */