SDL  2.0
org.libsdl.app.SDLAudioManager Class Reference

Static Public Member Functions

static void initialize ()
 
static int [] audioOpen (int sampleRate, int audioFormat, int desiredChannels, int desiredFrames)
 
static void audioWriteFloatBuffer (float[] buffer)
 
static void audioWriteShortBuffer (short[] buffer)
 
static void audioWriteByteBuffer (byte[] buffer)
 
static int [] captureOpen (int sampleRate, int audioFormat, int desiredChannels, int desiredFrames)
 
static int captureReadFloatBuffer (float[] buffer, boolean blocking)
 
static int captureReadShortBuffer (short[] buffer, boolean blocking)
 
static int captureReadByteBuffer (byte[] buffer, boolean blocking)
 
static void audioClose ()
 
static void captureClose ()
 
static native int nativeSetupJNI ()
 

Static Protected Member Functions

static String getAudioFormatString (int audioFormat)
 
static int [] open (boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames)
 

Static Protected Attributes

static final String TAG = "SDLAudio"
 
static AudioTrack mAudioTrack
 
static AudioRecord mAudioRecord
 

Detailed Description

Definition at line 7 of file SDLAudioManager.java.

Member Function Documentation

◆ audioClose()

static void org.libsdl.app.SDLAudioManager.audioClose ( )
inlinestatic

This method is called by SDL using JNI.

Definition at line 350 of file SDLAudioManager.java.

350  {
351  if (mAudioTrack != null) {
352  mAudioTrack.stop();
353  mAudioTrack.release();
354  mAudioTrack = null;
355  }
356  }

◆ audioOpen()

static int [] org.libsdl.app.SDLAudioManager.audioOpen ( int  sampleRate,
int  audioFormat,
int  desiredChannels,
int  desiredFrames 
)
inlinestatic

This method is called by SDL using JNI.

Definition at line 237 of file SDLAudioManager.java.

References org.libsdl.app.SDLAudioManager.open().

237  {
238  return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
239  }
static int [] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames)

◆ audioWriteByteBuffer()

static void org.libsdl.app.SDLAudioManager.audioWriteByteBuffer ( byte []  buffer)
inlinestatic

This method is called by SDL using JNI.

Definition at line 296 of file SDLAudioManager.java.

References e, and i.

296  {
297  if (mAudioTrack == null) {
298  Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
299  return;
300  }
301 
302  for (int i = 0; i < buffer.length; ) {
303  int result = mAudioTrack.write(buffer, i, buffer.length - i);
304  if (result > 0) {
305  i += result;
306  } else if (result == 0) {
307  try {
308  Thread.sleep(1);
309  } catch(InterruptedException e) {
310  // Nom nom
311  }
312  } else {
313  Log.w(TAG, "SDL audio: error return from write(byte)");
314  return;
315  }
316  }
317  }
GLuint64EXT * result
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
GLuint buffer

◆ audioWriteFloatBuffer()

static void org.libsdl.app.SDLAudioManager.audioWriteFloatBuffer ( float []  buffer)
inlinestatic

This method is called by SDL using JNI.

Definition at line 244 of file SDLAudioManager.java.

References e, and i.

244  {
245  if (mAudioTrack == null) {
246  Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
247  return;
248  }
249 
250  for (int i = 0; i < buffer.length;) {
251  int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
252  if (result > 0) {
253  i += result;
254  } else if (result == 0) {
255  try {
256  Thread.sleep(1);
257  } catch(InterruptedException e) {
258  // Nom nom
259  }
260  } else {
261  Log.w(TAG, "SDL audio: error return from write(float)");
262  return;
263  }
264  }
265  }
GLuint64EXT * result
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
GLuint buffer

◆ audioWriteShortBuffer()

static void org.libsdl.app.SDLAudioManager.audioWriteShortBuffer ( short []  buffer)
inlinestatic

This method is called by SDL using JNI.

Definition at line 270 of file SDLAudioManager.java.

References e, and i.

270  {
271  if (mAudioTrack == null) {
272  Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
273  return;
274  }
275 
276  for (int i = 0; i < buffer.length;) {
277  int result = mAudioTrack.write(buffer, i, buffer.length - i);
278  if (result > 0) {
279  i += result;
280  } else if (result == 0) {
281  try {
282  Thread.sleep(1);
283  } catch(InterruptedException e) {
284  // Nom nom
285  }
286  } else {
287  Log.w(TAG, "SDL audio: error return from write(short)");
288  return;
289  }
290  }
291  }
GLuint64EXT * result
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
GLuint buffer

◆ captureClose()

static void org.libsdl.app.SDLAudioManager.captureClose ( )
inlinestatic

This method is called by SDL using JNI.

Definition at line 359 of file SDLAudioManager.java.

References org.libsdl.app.SDLAudioManager.nativeSetupJNI().

359  {
360  if (mAudioRecord != null) {
361  mAudioRecord.stop();
362  mAudioRecord.release();
363  mAudioRecord = null;
364  }
365  }

◆ captureOpen()

static int [] org.libsdl.app.SDLAudioManager.captureOpen ( int  sampleRate,
int  audioFormat,
int  desiredChannels,
int  desiredFrames 
)
inlinestatic

This method is called by SDL using JNI.

Definition at line 322 of file SDLAudioManager.java.

References org.libsdl.app.SDLAudioManager.open().

322  {
323  return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
324  }
static int [] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames)

◆ captureReadByteBuffer()

static int org.libsdl.app.SDLAudioManager.captureReadByteBuffer ( byte []  buffer,
boolean  blocking 
)
inlinestatic

This method is called by SDL using JNI.

Definition at line 341 of file SDLAudioManager.java.

341  {
342  if (Build.VERSION.SDK_INT < 23) {
343  return mAudioRecord.read(buffer, 0, buffer.length);
344  } else {
345  return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
346  }
347  }
GLuint buffer

◆ captureReadFloatBuffer()

static int org.libsdl.app.SDLAudioManager.captureReadFloatBuffer ( float []  buffer,
boolean  blocking 
)
inlinestatic

This method is called by SDL using JNI.

Definition at line 327 of file SDLAudioManager.java.

327  {
328  return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
329  }
GLuint buffer

◆ captureReadShortBuffer()

static int org.libsdl.app.SDLAudioManager.captureReadShortBuffer ( short []  buffer,
boolean  blocking 
)
inlinestatic

This method is called by SDL using JNI.

Definition at line 332 of file SDLAudioManager.java.

332  {
333  if (Build.VERSION.SDK_INT < 23) {
334  return mAudioRecord.read(buffer, 0, buffer.length);
335  } else {
336  return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
337  }
338  }
GLuint buffer

◆ getAudioFormatString()

static String org.libsdl.app.SDLAudioManager.getAudioFormatString ( int  audioFormat)
inlinestaticprotected

Definition at line 21 of file SDLAudioManager.java.

Referenced by org.libsdl.app.SDLAudioManager.open().

21  {
22  switch (audioFormat) {
23  case AudioFormat.ENCODING_PCM_8BIT:
24  return "8-bit";
25  case AudioFormat.ENCODING_PCM_16BIT:
26  return "16-bit";
27  case AudioFormat.ENCODING_PCM_FLOAT:
28  return "float";
29  default:
30  return Integer.toString(audioFormat);
31  }
32  }

◆ initialize()

static void org.libsdl.app.SDLAudioManager.initialize ( )
inlinestatic

Definition at line 14 of file SDLAudioManager.java.

Referenced by org.libsdl.app.SDL.initialize().

14  {
15  mAudioTrack = null;
16  mAudioRecord = null;
17  }

◆ nativeSetupJNI()

static native int org.libsdl.app.SDLAudioManager.nativeSetupJNI ( )
static

◆ open()

static int [] org.libsdl.app.SDLAudioManager.open ( boolean  isCapture,
int  sampleRate,
int  audioFormat,
int  desiredChannels,
int  desiredFrames 
)
inlinestaticprotected

Definition at line 34 of file SDLAudioManager.java.

References org.libsdl.app.SDLAudioManager.getAudioFormatString().

Referenced by org.libsdl.app.SDLAudioManager.audioOpen(), and org.libsdl.app.SDLAudioManager.captureOpen().

34  {
35  int channelConfig;
36  int sampleSize;
37  int frameSize;
38 
39  Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
40 
41  /* On older devices let's use known good settings */
42  if (Build.VERSION.SDK_INT < 21) {
43  if (desiredChannels > 2) {
44  desiredChannels = 2;
45  }
46  if (sampleRate < 8000) {
47  sampleRate = 8000;
48  } else if (sampleRate > 48000) {
49  sampleRate = 48000;
50  }
51  }
52 
53  if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
54  int minSDKVersion = (isCapture ? 23 : 21);
55  if (Build.VERSION.SDK_INT < minSDKVersion) {
56  audioFormat = AudioFormat.ENCODING_PCM_16BIT;
57  }
58  }
59  switch (audioFormat)
60  {
61  case AudioFormat.ENCODING_PCM_8BIT:
62  sampleSize = 1;
63  break;
64  case AudioFormat.ENCODING_PCM_16BIT:
65  sampleSize = 2;
66  break;
67  case AudioFormat.ENCODING_PCM_FLOAT:
68  sampleSize = 4;
69  break;
70  default:
71  Log.v(TAG, "Requested format " + audioFormat + ", getting ENCODING_PCM_16BIT");
72  audioFormat = AudioFormat.ENCODING_PCM_16BIT;
73  sampleSize = 2;
74  break;
75  }
76 
77  if (isCapture) {
78  switch (desiredChannels) {
79  case 1:
80  channelConfig = AudioFormat.CHANNEL_IN_MONO;
81  break;
82  case 2:
83  channelConfig = AudioFormat.CHANNEL_IN_STEREO;
84  break;
85  default:
86  Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
87  desiredChannels = 2;
88  channelConfig = AudioFormat.CHANNEL_IN_STEREO;
89  break;
90  }
91  } else {
92  switch (desiredChannels) {
93  case 1:
94  channelConfig = AudioFormat.CHANNEL_OUT_MONO;
95  break;
96  case 2:
97  channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
98  break;
99  case 3:
100  channelConfig = AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
101  break;
102  case 4:
103  channelConfig = AudioFormat.CHANNEL_OUT_QUAD;
104  break;
105  case 5:
106  channelConfig = AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
107  break;
108  case 6:
109  channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
110  break;
111  case 7:
112  channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
113  break;
114  case 8:
115  if (Build.VERSION.SDK_INT >= 23) {
116  channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
117  } else {
118  Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
119  desiredChannels = 6;
120  channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
121  }
122  break;
123  default:
124  Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
125  desiredChannels = 2;
126  channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
127  break;
128  }
129 
130 /*
131  Log.v(TAG, "Speaker configuration (and order of channels):");
132 
133  if ((channelConfig & 0x00000004) != 0) {
134  Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT");
135  }
136  if ((channelConfig & 0x00000008) != 0) {
137  Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT");
138  }
139  if ((channelConfig & 0x00000010) != 0) {
140  Log.v(TAG, " CHANNEL_OUT_FRONT_CENTER");
141  }
142  if ((channelConfig & 0x00000020) != 0) {
143  Log.v(TAG, " CHANNEL_OUT_LOW_FREQUENCY");
144  }
145  if ((channelConfig & 0x00000040) != 0) {
146  Log.v(TAG, " CHANNEL_OUT_BACK_LEFT");
147  }
148  if ((channelConfig & 0x00000080) != 0) {
149  Log.v(TAG, " CHANNEL_OUT_BACK_RIGHT");
150  }
151  if ((channelConfig & 0x00000100) != 0) {
152  Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT_OF_CENTER");
153  }
154  if ((channelConfig & 0x00000200) != 0) {
155  Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT_OF_CENTER");
156  }
157  if ((channelConfig & 0x00000400) != 0) {
158  Log.v(TAG, " CHANNEL_OUT_BACK_CENTER");
159  }
160  if ((channelConfig & 0x00000800) != 0) {
161  Log.v(TAG, " CHANNEL_OUT_SIDE_LEFT");
162  }
163  if ((channelConfig & 0x00001000) != 0) {
164  Log.v(TAG, " CHANNEL_OUT_SIDE_RIGHT");
165  }
166 */
167  }
168  frameSize = (sampleSize * desiredChannels);
169 
170  // Let the user pick a larger buffer if they really want -- but ye
171  // gods they probably shouldn't, the minimums are horrifyingly high
172  // latency already
173  int minBufferSize;
174  if (isCapture) {
175  minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
176  } else {
177  minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
178  }
179  desiredFrames = Math.max(desiredFrames, (minBufferSize + frameSize - 1) / frameSize);
180 
181  int[] results = new int[4];
182 
183  if (isCapture) {
184  if (mAudioRecord == null) {
185  mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
186  channelConfig, audioFormat, desiredFrames * frameSize);
187 
188  // see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
189  if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
190  Log.e(TAG, "Failed during initialization of AudioRecord");
191  mAudioRecord.release();
192  mAudioRecord = null;
193  return null;
194  }
195 
196  mAudioRecord.startRecording();
197  }
198 
199  results[0] = mAudioRecord.getSampleRate();
200  results[1] = mAudioRecord.getAudioFormat();
201  results[2] = mAudioRecord.getChannelCount();
202  results[3] = desiredFrames;
203 
204  } else {
205  if (mAudioTrack == null) {
206  mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
207 
208  // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
209  // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
210  // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
211  if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
212  /* Try again, with safer values */
213 
214  Log.e(TAG, "Failed during initialization of Audio Track");
215  mAudioTrack.release();
216  mAudioTrack = null;
217  return null;
218  }
219 
220  mAudioTrack.play();
221  }
222 
223  results[0] = mAudioTrack.getSampleRate();
224  results[1] = mAudioTrack.getAudioFormat();
225  results[2] = mAudioTrack.getChannelCount();
226  results[3] = desiredFrames;
227  }
228 
229  Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", got " + results[3] + " frames of " + results[2] + " channel " + getAudioFormatString(results[1]) + " audio at " + results[0] + " Hz");
230 
231  return results;
232  }
static String getAudioFormatString(int audioFormat)

Field Documentation

◆ mAudioRecord

AudioRecord org.libsdl.app.SDLAudioManager.mAudioRecord
staticprotected

Definition at line 12 of file SDLAudioManager.java.

◆ mAudioTrack

AudioTrack org.libsdl.app.SDLAudioManager.mAudioTrack
staticprotected

Definition at line 11 of file SDLAudioManager.java.

◆ TAG

final String org.libsdl.app.SDLAudioManager.TAG = "SDLAudio"
staticprotected

Definition at line 9 of file SDLAudioManager.java.


The documentation for this class was generated from the following file: