comparison src/audio/android/SDL_androidaudio.c @ 4995:9f9bea41e88f

Working audio implementation contributed by Joseph Lunderville
author Sam Lantinga <slouken@libsdl.org>
date Thu, 13 Jan 2011 11:14:20 -0800
parents 58b6bb4a45e9
children 8d7315668e35
comparison
equal deleted inserted replaced
4994:e4ed74189d63 4995:9f9bea41e88f
16 License along with this library; if not, write to the Free Software 16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21
22 This file written by Ryan C. Gordon (icculus@icculus.org)
23 */ 21 */
24 #include "SDL_config.h" 22 #include "SDL_config.h"
25 23
26 /* Output audio to Android */ 24 /* Output audio to Android */
27 25
28 #include "SDL_audio.h" 26 #include "SDL_audio.h"
29 #include "../SDL_audio_c.h" 27 #include "../SDL_audio_c.h"
30 #include "SDL_androidaudio.h" 28 #include "SDL_androidaudio.h"
29
31 #include "../../SDL_android.h" 30 #include "../../SDL_android.h"
32 31
33 #include <android/log.h> 32 #include <android/log.h>
34 33
34 static void * audioDevice;
35
35 static int 36 static int
36 AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture) 37 AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
37 { 38 {
38 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); 39 SDL_AudioFormat test_format;
39 int valid_datatype = 0; 40 int valid_datatype = 0;
40 41
41 //TODO: Sample rates etc 42 if (iscapture) {
42 __android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Open\n"); 43 //TODO: implement capture
44 SDL_SetError("Capture not supported on Android");
45 return 0;
46 }
47
48 if (audioDevice != NULL) {
49 SDL_SetError("Only one audio device at a time please!");
50 return 0;
51 }
52
53 audioDevice = this;
43 54
44 this->hidden = SDL_malloc(sizeof(*(this->hidden))); 55 this->hidden = SDL_malloc(sizeof(*(this->hidden)));
45 if (!this->hidden) { 56 if (!this->hidden) {
46 SDL_OutOfMemory(); 57 SDL_OutOfMemory();
47 return 0; 58 return 0;
48 } 59 }
49 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 60 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
50 61
51 while ((!valid_datatype) && (test_format)) { 62 test_format = SDL_FirstAudioFormat(this->spec.format);
52 this->spec.format = test_format; 63 while (test_format != 0) { // no "UNKNOWN" constant
53 switch (test_format) { 64 if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
54 case AUDIO_S8: 65 this->spec.format = test_format;
55 /*case AUDIO_S16LSB: */
56 valid_datatype = 1;
57 break;
58 default:
59 test_format = SDL_NextAudioFormat();
60 break; 66 break;
61 } 67 }
68 test_format = SDL_NextAudioFormat();
62 } 69 }
63 70
71 if (test_format == 0) {
72 // Didn't find a compatible format :(
73 SDL_SetError("No compatible audio format!");
74 return 0;
75 }
76
77 if (this->spec.channels > 1) {
78 this->spec.channels = 2;
79 } else {
80 this->spec.channels = 1;
81 }
82
83 if (this->spec.freq < 8000) {
84 this->spec.freq = 8000;
85 }
86 if (this->spec.freq > 48000) {
87 this->spec.freq = 48000;
88 }
89
90 // TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
91 this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
92 SDL_CalculateAudioSpec(&this->spec);
93
94 if (this->spec.samples == 0) {
95 // Init failed?
96 SDL_SetError("Java-side initialization failed!");
97 return 0;
98 }
99
64 return 1; 100 return 1;
65 } 101 }
66 102
67 static void 103 static void
68 AndroidAUD_PlayDevice(_THIS) 104 AndroidAUD_PlayDevice(_THIS)
69 { 105 {
70 __android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Play\n"); 106 Android_JNI_WriteAudioBufferAndUnpin();
71 107 this->hidden->mixbuf = NULL;
72
73 //playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
74
75 #if 0
76
77 // sound->rate = 22050; /* sample rate = 22050Hz */
78 // sound->vol = 127; /* volume [0..127] for [min..max] */
79 // sound->pan = 64; /* balance [0..127] for [left..right] */
80 // sound->format = 0; /* 0 for 16-bit, 1 for 8-bit */
81 // playSound(sound);
82 #endif
83 } 108 }
84
85 109
86 static Uint8 * 110 static Uint8 *
87 AndroidAUD_GetDeviceBuf(_THIS) 111 AndroidAUD_GetDeviceBuf(_THIS)
88 { 112 {
89 //__android_log_print(ANDROID_LOG_INFO, "SDL", "****** get device buf\n"); 113 if (this->hidden->mixbuf == NULL) {
90 114 this->hidden->mixbuf = Android_JNI_PinAudioBuffer();
91 115 }
92 // sound->data = this->hidden->mixbuf;/* pointer to raw audio data */ 116 return this->hidden->mixbuf;
93 // sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
94
95
96 Android_JNI_UpdateAudioBuffer(this->hidden->mixbuf, this->hidden->mixlen);
97
98 return this->hidden->mixbuf; /* is this right? */
99 }
100
101 static void
102 AndroidAUD_WaitDevice(_THIS)
103 {
104 /* stub */
105 __android_log_print(ANDROID_LOG_INFO, "SDL", "****** wait device buf\n");
106 } 117 }
107 118
108 static void 119 static void
109 AndroidAUD_CloseDevice(_THIS) 120 AndroidAUD_CloseDevice(_THIS)
110 { 121 {
111 /* stub */ 122 if (this->hidden != NULL) {
112 __android_log_print(ANDROID_LOG_INFO, "SDL", "****** close device buf\n"); 123 if (this->hidden->mixbuf != NULL) {
124 Android_JNI_WriteAudioBufferAndUnpin();
125 }
126 SDL_free(this->hidden);
127 this->hidden = NULL;
128 }
129 Android_JNI_CloseAudioDevice();
130
131 if (audioDevice == this) {
132 audioDevice = NULL;
133 }
113 } 134 }
114 135
115 static int 136 static int
116 AndroidAUD_Init(SDL_AudioDriverImpl * impl) 137 AndroidAUD_Init(SDL_AudioDriverImpl * impl)
117 { 138 {
118 /* Set the function pointers */ 139 /* Set the function pointers */
119 impl->OpenDevice = AndroidAUD_OpenDevice; 140 impl->OpenDevice = AndroidAUD_OpenDevice;
120 impl->PlayDevice = AndroidAUD_PlayDevice; 141 impl->PlayDevice = AndroidAUD_PlayDevice;
121 impl->WaitDevice = AndroidAUD_WaitDevice;
122 impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf; 142 impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
123 impl->CloseDevice = AndroidAUD_CloseDevice; 143 impl->CloseDevice = AndroidAUD_CloseDevice;
124 144
125 /* and the capabilities */ 145 /* and the capabilities */
146 impl->ProvidesOwnCallbackThread = 1;
126 impl->HasCaptureSupport = 0; //TODO 147 impl->HasCaptureSupport = 0; //TODO
127 impl->OnlyHasDefaultOutputDevice = 1; 148 impl->OnlyHasDefaultOutputDevice = 1;
128 impl->OnlyHasDefaultInputDevice = 1; 149 impl->OnlyHasDefaultInputDevice = 1;
129
130 __android_log_print(ANDROID_LOG_INFO, "SDL","Audio init\n");
131 150
132 return 1; /* this audio target is available. */ 151 return 1; /* this audio target is available. */
133 } 152 }
134 153
135 AudioBootStrap ANDROIDAUD_bootstrap = { 154 AudioBootStrap ANDROIDAUD_bootstrap = {
136 "android", "SDL Android audio driver", AndroidAUD_Init, 0 /*1? */ 155 "android", "SDL Android audio driver", AndroidAUD_Init, 0 /*1? */
137 }; 156 };
138 157
158 /* Called by the Java code to start the audio processing on a thread */
159 void
160 Android_RunAudioThread()
161 {
162 SDL_RunAudio(audioDevice);
163 }
164
139 /* vi: set ts=4 sw=4 expandtab: */ 165 /* vi: set ts=4 sw=4 expandtab: */