mirror of
https://github.com/encounter/SDL.git
synced 2025-12-10 05:57:44 +00:00
android: implement audio capture support.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
/* Output audio to Android */
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_androidaudio.h"
|
||||
@@ -33,24 +34,22 @@
|
||||
#include <android/log.h>
|
||||
|
||||
static SDL_AudioDevice* audioDevice = NULL;
|
||||
static SDL_AudioDevice* captureDevice = NULL;
|
||||
|
||||
static int
|
||||
AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
SDL_assert((captureDevice == NULL) || !iscapture);
|
||||
SDL_assert((audioDevice == NULL) || iscapture);
|
||||
|
||||
if (iscapture) {
|
||||
/* TODO: implement capture */
|
||||
return SDL_SetError("Capture not supported on Android");
|
||||
captureDevice = this;
|
||||
} else {
|
||||
audioDevice = this;
|
||||
}
|
||||
|
||||
/* !!! FIXME: higher level will prevent this now. Lose this check (and global?). */
|
||||
if (audioDevice != NULL) {
|
||||
return SDL_SetError("Only one audio device at a time please!");
|
||||
}
|
||||
|
||||
audioDevice = this;
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
@@ -83,15 +82,16 @@ AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
this->spec.freq = 48000;
|
||||
}
|
||||
|
||||
/* TODO: pass in/return a (Java) device ID, also whether we're opening for input or output */
|
||||
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
/* TODO: pass in/return a (Java) device ID */
|
||||
this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||
|
||||
if (this->spec.samples == 0) {
|
||||
/* Init failed? */
|
||||
return SDL_SetError("Java-side initialization failed!");
|
||||
}
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -107,18 +107,33 @@ AndroidAUD_GetDeviceBuf(_THIS)
|
||||
return Android_JNI_GetAudioBuffer();
|
||||
}
|
||||
|
||||
static int
|
||||
AndroidAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
return Android_JNI_CaptureAudioBuffer(buffer, buflen);
|
||||
}
|
||||
|
||||
static void
|
||||
AndroidAUD_FlushCapture(_THIS)
|
||||
{
|
||||
Android_JNI_FlushCapturedAudio();
|
||||
}
|
||||
|
||||
static void
|
||||
AndroidAUD_CloseDevice(_THIS)
|
||||
{
|
||||
/* 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
|
||||
*/
|
||||
Android_JNI_CloseAudioDevice();
|
||||
|
||||
if (audioDevice == this) {
|
||||
SDL_free(this->hidden);
|
||||
Android_JNI_CloseAudioDevice(this->iscapture);
|
||||
if (this->iscapture) {
|
||||
SDL_assert(captureDevice == this);
|
||||
captureDevice = NULL;
|
||||
} else {
|
||||
SDL_assert(audioDevice == this);
|
||||
audioDevice = NULL;
|
||||
}
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -129,9 +144,11 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->PlayDevice = AndroidAUD_PlayDevice;
|
||||
impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
|
||||
impl->CloseDevice = AndroidAUD_CloseDevice;
|
||||
impl->CaptureFromDevice = AndroidAUD_CaptureFromDevice;
|
||||
impl->FlushCapture = AndroidAUD_FlushCapture;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = 0; /* TODO */
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultCaptureDevice = 1;
|
||||
|
||||
@@ -159,6 +176,19 @@ void AndroidAUD_PauseDevices(void)
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
if (SDL_AtomicGet(&captureDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
}
|
||||
else {
|
||||
SDL_LockMutex(captureDevice->mixer_lock);
|
||||
SDL_AtomicSet(&captureDevice->paused, 1);
|
||||
private->resume = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
|
||||
@@ -174,6 +204,15 @@ void AndroidAUD_ResumeDevices(void)
|
||||
SDL_UnlockMutex(audioDevice->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
if(captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&captureDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(captureDevice->mixer_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user