Working audio implementation contributed by Joseph Lunderville

This commit is contained in:
Sam Lantinga 2011-01-13 11:14:20 -08:00
parent a409f9858f
commit 4f9db82a4c
5 changed files with 291 additions and 148 deletions

View file

@ -18,8 +18,6 @@
Sam Lantinga
slouken@libsdl.org
This file written by Ryan C. Gordon (icculus@icculus.org)
*/
#include "SDL_config.h"
@ -28,18 +26,31 @@
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_androidaudio.h"
#include "../../SDL_android.h"
#include <android/log.h>
static void * audioDevice;
static int
AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
{
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
SDL_AudioFormat test_format;
int valid_datatype = 0;
//TODO: Sample rates etc
__android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Open\n");
if (iscapture) {
//TODO: implement capture
SDL_SetError("Capture not supported on Android");
return 0;
}
if (audioDevice != NULL) {
SDL_SetError("Only one audio device at a time please!");
return 0;
}
audioDevice = this;
this->hidden = SDL_malloc(sizeof(*(this->hidden)));
if (!this->hidden) {
@ -48,68 +59,78 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
while ((!valid_datatype) && (test_format)) {
this->spec.format = test_format;
switch (test_format) {
case AUDIO_S8:
/*case AUDIO_S16LSB: */
valid_datatype = 1;
break;
default:
test_format = SDL_NextAudioFormat();
test_format = SDL_FirstAudioFormat(this->spec.format);
while (test_format != 0) { // no "UNKNOWN" constant
if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
this->spec.format = test_format;
break;
}
test_format = SDL_NextAudioFormat();
}
if (test_format == 0) {
// Didn't find a compatible format :(
SDL_SetError("No compatible audio format!");
return 0;
}
if (this->spec.channels > 1) {
this->spec.channels = 2;
} else {
this->spec.channels = 1;
}
if (this->spec.freq < 8000) {
this->spec.freq = 8000;
}
if (this->spec.freq > 48000) {
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);
if (this->spec.samples == 0) {
// Init failed?
SDL_SetError("Java-side initialization failed!");
return 0;
}
return 1;
}
static void
AndroidAUD_PlayDevice(_THIS)
{
__android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Play\n");
//playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
#if 0
// sound->rate = 22050; /* sample rate = 22050Hz */
// sound->vol = 127; /* volume [0..127] for [min..max] */
// sound->pan = 64; /* balance [0..127] for [left..right] */
// sound->format = 0; /* 0 for 16-bit, 1 for 8-bit */
// playSound(sound);
#endif
Android_JNI_WriteAudioBufferAndUnpin();
this->hidden->mixbuf = NULL;
}
static Uint8 *
AndroidAUD_GetDeviceBuf(_THIS)
{
//__android_log_print(ANDROID_LOG_INFO, "SDL", "****** get device buf\n");
// sound->data = this->hidden->mixbuf;/* pointer to raw audio data */
// sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
Android_JNI_UpdateAudioBuffer(this->hidden->mixbuf, this->hidden->mixlen);
return this->hidden->mixbuf; /* is this right? */
}
static void
AndroidAUD_WaitDevice(_THIS)
{
/* stub */
__android_log_print(ANDROID_LOG_INFO, "SDL", "****** wait device buf\n");
if (this->hidden->mixbuf == NULL) {
this->hidden->mixbuf = Android_JNI_PinAudioBuffer();
}
return this->hidden->mixbuf;
}
static void
AndroidAUD_CloseDevice(_THIS)
{
/* stub */
__android_log_print(ANDROID_LOG_INFO, "SDL", "****** close device buf\n");
if (this->hidden != NULL) {
if (this->hidden->mixbuf != NULL) {
Android_JNI_WriteAudioBufferAndUnpin();
}
SDL_free(this->hidden);
this->hidden = NULL;
}
Android_JNI_CloseAudioDevice();
if (audioDevice == this) {
audioDevice = NULL;
}
}
static int
@ -118,17 +139,15 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
/* Set the function pointers */
impl->OpenDevice = AndroidAUD_OpenDevice;
impl->PlayDevice = AndroidAUD_PlayDevice;
impl->WaitDevice = AndroidAUD_WaitDevice;
impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
impl->CloseDevice = AndroidAUD_CloseDevice;
/* and the capabilities */
impl->ProvidesOwnCallbackThread = 1;
impl->HasCaptureSupport = 0; //TODO
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultInputDevice = 1;
__android_log_print(ANDROID_LOG_INFO, "SDL","Audio init\n");
return 1; /* this audio target is available. */
}
@ -136,4 +155,11 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
"android", "SDL Android audio driver", AndroidAUD_Init, 0 /*1? */
};
/* Called by the Java code to start the audio processing on a thread */
void
Android_RunAudioThread()
{
SDL_RunAudio(audioDevice);
}
/* vi: set ts=4 sw=4 expandtab: */