/** * * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. * */ package org.puredata.android.io; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.AudioTrack; /** * * AudioParameters sniffs out the number of audio input and output channels as well as * supported sample rates. * * @author Peter Brinkmann (peter.brinkmann@gmail.com) * */ public class AudioParameters { private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT; private static final int COMMON_RATE = 8000; // 8kHz seems to work everywhere, including the simulator private static final int MAX_CHANNELS = 8; private static int sampleRate = 0, inputChannels = 0, outputChannels = 0; private static float bufsizeMillis = 100.0f; // conservative choice... static { init(); } /** * @return a reasonable sample rate that the device supports, 0 if audio output is unavailable */ public static int suggestSampleRate() { return sampleRate; } /** * @return the largest number of input channels that the device supports */ public static int suggestInputChannels() { return inputChannels; } /** * @return the largest number of output channels that the device supports */ public static int suggestOutputChannels() { return outputChannels; } /** * @return suggested buffer size in milliseconds; suggests 100ms, i.e., a fairly conservative choice */ public static float suggestBufferSizeMillis() { return bufsizeMillis; } /** * @param srate sample rate * @param nin number of input channels * @param nout number of output channels * @return true if and only if the device supports the given set of parameters */ public static boolean checkParameters(int srate, int nin, int nout) { return checkInputParameters(srate, nin) && checkOutputParameters(srate, nout); } /** * @param srate sample rate * @param nin number of input channels * @return true if and only if the device supports the given set of parameters */ public static boolean checkInputParameters(int srate, int nin) { try { return nin == 0 || AudioRecord.getMinBufferSize(srate, VersionedAudioFormat.getInFormat(nin), ENCODING) > 0; } catch (Exception e) { return false; } } /** * @param srate sample rate * @param nout number of output channels * @return true if and only if the device supports the given set of parameters */ public static boolean checkOutputParameters(int srate, int nout) { try { return AudioTrack.getMinBufferSize(srate, VersionedAudioFormat.getOutFormat(nout), ENCODING) > 0; } catch (Exception e) { return false; } } private static void init() { for (int n = 1; n < MAX_CHANNELS; n++) { if (checkOutputParameters(COMMON_RATE, n)) outputChannels = n; } if (outputChannels == 0) return; // no audio output found; give up for (int n = 0; n < MAX_CHANNELS; n++) { if (checkInputParameters(COMMON_RATE, n)) inputChannels = n; } sampleRate = COMMON_RATE; for (int sr: new int[] {11025, 16000, 22050, 32000, 44100}) { if (checkParameters(sr, inputChannels, outputChannels)) sampleRate = sr; } } }