├── README.md └── main ├── AndroidManifest.xml ├── java └── com │ └── sample │ ├── MainActivity.java │ └── audio │ ├── calculators │ ├── AudioCalculator.java │ ├── FrequencyCalculator.java │ └── RealDoubleFFT.java │ └── core │ ├── Callback.java │ └── Recorder.java └── res ├── layout └── activity_main.xml ├── mipmap-hdpi └── ic_launcher.png ├── mipmap-mdpi └── ic_launcher.png ├── mipmap-xhdpi └── ic_launcher.png ├── mipmap-xxhdpi └── ic_launcher.png ├── mipmap-xxxhdpi └── ic_launcher.png └── values ├── colors.xml ├── dimens.xml ├── strings.xml └── styles.xml /README.md: -------------------------------------------------------------------------------- 1 | # Android-Audio-Sample 2 | 3 | Este é um app Android de exemplo, simples e direto, cuja intenção é extrair informações básicas do áudio gravado, freqüência, amplitude e decibel. Baseado em um antigo exemplo da Google, o Spectrum Analyzer. 4 | 5 | ![anigif](https://cloud.githubusercontent.com/assets/16022034/23332089/9d5bbea4-fb51-11e6-8126-de6487d56b60.gif) 6 | -------------------------------------------------------------------------------- /main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /main/java/com/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.sample; 2 | 3 | import android.app.Activity; 4 | import android.content.pm.ActivityInfo; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.os.Looper; 8 | import android.widget.TextView; 9 | 10 | import com.sample.audio.calculators.AudioCalculator; 11 | import com.sample.audio.core.Callback; 12 | import com.sample.audio.core.Recorder; 13 | 14 | public class MainActivity extends Activity { 15 | 16 | private Recorder recorder; 17 | private AudioCalculator audioCalculator; 18 | private Handler handler; 19 | 20 | private TextView textAmplitude; 21 | private TextView textDecibel; 22 | private TextView textFrequency; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_main); 28 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 29 | 30 | recorder = new Recorder(callback); 31 | audioCalculator = new AudioCalculator(); 32 | handler = new Handler(Looper.getMainLooper()); 33 | 34 | textAmplitude = (TextView) findViewById(R.id.textAmplitude); 35 | textDecibel = (TextView) findViewById(R.id.textDecibel); 36 | textFrequency = (TextView) findViewById(R.id.textFrequency); 37 | } 38 | 39 | private Callback callback = new Callback() { 40 | 41 | @Override 42 | public void onBufferAvailable(byte[] buffer) { 43 | audioCalculator.setBytes(buffer); 44 | int amplitude = audioCalculator.getAmplitude(); 45 | double decibel = audioCalculator.getDecibel(); 46 | double frequency = audioCalculator.getFrequency(); 47 | 48 | final String amp = String.valueOf(amplitude + " Amp"); 49 | final String db = String.valueOf(decibel + " db"); 50 | final String hz = String.valueOf(frequency + " Hz"); 51 | 52 | handler.post(new Runnable() { 53 | @Override 54 | public void run() { 55 | textAmplitude.setText(amp); 56 | textDecibel.setText(db); 57 | textFrequency.setText(hz); 58 | } 59 | }); 60 | } 61 | }; 62 | 63 | @Override 64 | protected void onResume() { 65 | super.onResume(); 66 | recorder.start(); 67 | } 68 | 69 | @Override 70 | protected void onPause() { 71 | super.onPause(); 72 | recorder.stop(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /main/java/com/sample/audio/calculators/AudioCalculator.java: -------------------------------------------------------------------------------- 1 | package com.sample.audio.calculators; 2 | 3 | import android.util.Log; 4 | 5 | public class AudioCalculator { 6 | 7 | private byte[] bytes; 8 | private int[] amplitudes; 9 | private double[] decibels; 10 | private double frequency; 11 | private int amplitude; 12 | private double decibel; 13 | 14 | public AudioCalculator() { 15 | } 16 | 17 | public AudioCalculator(byte[] bytes) { 18 | this.bytes = bytes; 19 | amplitudes = null; 20 | decibels = null; 21 | frequency = 0.0D; 22 | amplitude = 0; 23 | decibel = 0.0D; 24 | } 25 | 26 | public void setBytes(byte[] bytes) { 27 | this.bytes = bytes; 28 | amplitudes = null; 29 | decibels = null; 30 | frequency = 0.0D; 31 | amplitude = 0; 32 | decibel = 0.0D; 33 | } 34 | 35 | public int[] getAmplitudes() { 36 | if (amplitudes == null) amplitudes = getAmplitudesFromBytes(bytes); 37 | return amplitudes; 38 | } 39 | 40 | public double[] getDecibels() { 41 | if (amplitudes == null) amplitudes = getAmplitudesFromBytes(bytes); 42 | if (decibels == null) { 43 | decibels = new double[amplitudes.length]; 44 | for (int i = 0; i < amplitudes.length; i++) { 45 | decibels[i] = resizeNumber(getRealDecibel(amplitudes[i])); 46 | } 47 | } 48 | return decibels; 49 | } 50 | 51 | public int[] getAmplitudeLevels() { 52 | if (amplitudes == null) getAmplitudes(); 53 | int major = 0; 54 | int minor = 0; 55 | for (int i : amplitudes) { 56 | if (i > major) major = i; 57 | if (i < minor) minor = i; 58 | } 59 | amplitude = Math.max(major, minor * (-1)); 60 | return new int[] {major, minor}; 61 | } 62 | 63 | public int getAmplitude() { 64 | if (amplitude == 0) getAmplitudeLevels(); 65 | return amplitude; 66 | } 67 | 68 | public double getDecibel() { 69 | if (decibel == 0.0D) decibel = resizeNumber(getRealDecibel(amplitude)); 70 | return decibel; 71 | } 72 | 73 | public double getFrequency() { 74 | if (frequency == 0.0D) frequency = retrieveFrequency(); 75 | return frequency; 76 | } 77 | 78 | private double retrieveFrequency() { 79 | int length = bytes.length / 2; 80 | int sampleSize = 8192; 81 | while (sampleSize > length) sampleSize = sampleSize >> 1; 82 | 83 | FrequencyCalculator frequencyCalculator = new FrequencyCalculator(sampleSize); 84 | frequencyCalculator.feedData(bytes, length); 85 | 86 | return resizeNumber(frequencyCalculator.getFreq()); 87 | } 88 | 89 | private double getRealDecibel(int amplitude) { 90 | if (amplitude < 0) amplitude *= -1; 91 | double amp = (((double) amplitude) / 32767.0d) * 100.0d; 92 | if (amp == 0.0d) { 93 | amp = 1.0d; 94 | } 95 | double decibel = Math.sqrt(100.0d / amp); 96 | decibel *= decibel; 97 | if (decibel > 100.0d) { 98 | decibel = 100.0d; 99 | } 100 | return ((-1.0d * decibel) + 1.0d) / Math.PI; 101 | } 102 | 103 | public double resizeNumber(double value) { 104 | int temp = (int) (value * 10.0d); 105 | return temp / 10.0d; 106 | } 107 | 108 | private int[] getAmplitudesFromBytes(byte[] bytes) { 109 | int[] amps = new int[bytes.length / 2]; 110 | for (int i = 0; i < bytes.length; i += 2) { 111 | short buff = bytes[i + 1]; 112 | short buff2 = bytes[i]; 113 | 114 | buff = (short) ((buff & 0xFF) << 8); 115 | buff2 = (short) (buff2 & 0xFF); 116 | 117 | short res = (short) (buff | buff2); 118 | amps[i == 0 ? 0 : i / 2] = (int) res; 119 | } 120 | return amps; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /main/java/com/sample/audio/calculators/FrequencyCalculator.java: -------------------------------------------------------------------------------- 1 | package com.sample.audio.calculators; 2 | 3 | import java.util.Arrays; 4 | 5 | public class FrequencyCalculator { 6 | 7 | private RealDoubleFFT spectrumAmpFFT; 8 | private double[] spectrumAmpOutCum; 9 | private double[] spectrumAmpOutTmp; 10 | private double[] spectrumAmpOut; 11 | private double[] spectrumAmpOutDB; 12 | private double[] spectrumAmpIn; 13 | private double[] spectrumAmpInTmp; 14 | private double[] wnd; 15 | private double[][] spectrumAmpOutArray; 16 | 17 | private int fftLen; 18 | private int spectrumAmpPt; 19 | private int spectrumAmpOutArrayPt = 0; 20 | private int nAnalysed = 0; 21 | 22 | private void init(int fftlen) { 23 | fftLen = fftlen; 24 | spectrumAmpOutCum = new double[fftlen]; 25 | spectrumAmpOutTmp = new double[fftlen]; 26 | spectrumAmpOut = new double[fftlen]; 27 | spectrumAmpOutDB = new double[fftlen]; 28 | spectrumAmpIn = new double[fftlen]; 29 | spectrumAmpInTmp = new double[fftlen]; 30 | spectrumAmpFFT = new RealDoubleFFT(fftlen); 31 | spectrumAmpOutArray = new double[(int) Math.ceil((double) 1 / fftlen)][]; 32 | 33 | for (int i = 0; i < spectrumAmpOutArray.length; i++) { 34 | spectrumAmpOutArray[i] = new double[fftlen]; 35 | } 36 | wnd = new double[fftlen]; 37 | for (int i = 0; i < wnd.length; i++) { 38 | wnd[i] = Math.asin(Math.sin(Math.PI * i / wnd.length)) / Math.PI * 2; 39 | } 40 | } 41 | 42 | public FrequencyCalculator(int fftlen) { 43 | init(fftlen); 44 | } 45 | 46 | private short getShortFromBytes(int index) { 47 | index *= 2; 48 | short buff = bytes[index + 1]; 49 | short buff2 = bytes[index]; 50 | 51 | buff = (short) ((buff & 0xFF) << 8); 52 | buff2 = (short) (buff2 & 0xFF); 53 | 54 | return (short) (buff | buff2); 55 | } 56 | 57 | private byte[] bytes; 58 | 59 | public void feedData(byte[] ds, int dsLen) { 60 | bytes = ds; 61 | int dsPt = 0; 62 | while (dsPt < dsLen) { 63 | while (spectrumAmpPt < fftLen && dsPt < dsLen) { 64 | double s = getShortFromBytes(dsPt++) / 32768.0; 65 | spectrumAmpIn[spectrumAmpPt++] = s; 66 | } 67 | if (spectrumAmpPt == fftLen) { 68 | for (int i = 0; i < fftLen; i++) { 69 | spectrumAmpInTmp[i] = spectrumAmpIn[i] * wnd[i]; 70 | } 71 | spectrumAmpFFT.ft(spectrumAmpInTmp); 72 | fftToAmp(spectrumAmpOutTmp, spectrumAmpInTmp); 73 | System.arraycopy(spectrumAmpOutTmp, 0, spectrumAmpOutArray[spectrumAmpOutArrayPt], 0, spectrumAmpOutTmp.length); 74 | spectrumAmpOutArrayPt = (spectrumAmpOutArrayPt + 1) % spectrumAmpOutArray.length; 75 | for (int i = 0; i < fftLen; i++) { 76 | spectrumAmpOutCum[i] += spectrumAmpOutTmp[i]; 77 | } 78 | nAnalysed++; 79 | int n2 = spectrumAmpIn.length / 2; 80 | System.arraycopy(spectrumAmpIn, n2, spectrumAmpIn, 0, n2); 81 | spectrumAmpPt = n2; 82 | } 83 | } 84 | } 85 | 86 | private void fftToAmp(double[] dataOut, double[] data) { 87 | double scaler = 2.0 * 2.0 / (data.length * data.length); 88 | dataOut[0] = data[0] * data[0] * scaler / 4.0; 89 | int j = 1; 90 | for (int i = 1; i < data.length - 1; i += 2, j++) { 91 | dataOut[j] = (data[i] * data[i] + data[i + 1] * data[i + 1]) * scaler; 92 | } 93 | dataOut[j] = data[data.length - 1] * data[data.length - 1] * scaler / 4.0; 94 | } 95 | 96 | public double getFreq() { 97 | if (nAnalysed != 0) { 98 | int outLen = spectrumAmpOut.length; 99 | double[] sAOC = spectrumAmpOutCum; 100 | for (int j = 0; j < outLen; j++) { 101 | sAOC[j] /= nAnalysed; 102 | } 103 | System.arraycopy(sAOC, 0, spectrumAmpOut, 0, outLen); 104 | Arrays.fill(sAOC, 0.0); 105 | nAnalysed = 0; 106 | for (int i = 0; i < outLen; i++) { 107 | spectrumAmpOutDB[i] = 10.0 * Math.log10(spectrumAmpOut[i]); 108 | } 109 | } 110 | 111 | double maxAmpDB = 20 * Math.log10(0.125 / 32768); 112 | double maxAmpFreq = 0; 113 | for (int i = 1; i < spectrumAmpOutDB.length; i++) { 114 | if (spectrumAmpOutDB[i] > maxAmpDB) { 115 | maxAmpDB = spectrumAmpOutDB[i]; 116 | maxAmpFreq = i; 117 | } 118 | } 119 | int sampleRate = 44100; 120 | maxAmpFreq = maxAmpFreq * sampleRate / fftLen; 121 | if (sampleRate / fftLen < maxAmpFreq && maxAmpFreq < sampleRate / 2 - sampleRate / fftLen) { 122 | int id = (int) (Math.round(maxAmpFreq / sampleRate * fftLen)); 123 | double x1 = spectrumAmpOutDB[id - 1]; 124 | double x2 = spectrumAmpOutDB[id]; 125 | double x3 = spectrumAmpOutDB[id + 1]; 126 | double a = (x3 + x1) / 2 - x2; 127 | double b = (x3 - x1) / 2; 128 | if (a < 0) { 129 | double xPeak = -b / (2 * a); 130 | if (Math.abs(xPeak) < 1) { 131 | maxAmpFreq += xPeak * sampleRate / fftLen; 132 | } 133 | } 134 | } 135 | return maxAmpFreq; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /main/java/com/sample/audio/calculators/RealDoubleFFT.java: -------------------------------------------------------------------------------- 1 | package com.sample.audio.calculators; 2 | 3 | public class RealDoubleFFT { 4 | 5 | public double norm_factor; 6 | private double wavetable[]; 7 | private double[] ch; // reusable work array 8 | private int ndim; 9 | 10 | public RealDoubleFFT(int n) { 11 | ndim = n; 12 | norm_factor = n; 13 | if (wavetable == null || wavetable.length != (2 * ndim + 15)) { 14 | wavetable = new double[2 * ndim + 15]; 15 | } 16 | rffti(ndim, wavetable); 17 | ch = new double[n]; 18 | } 19 | 20 | public void ft(double x[]) { 21 | if (x.length != ndim) 22 | throw new IllegalArgumentException("The length of data can not match that of the wavetable"); 23 | rfftf(ndim, x, wavetable, ch); 24 | } 25 | 26 | 27 | ///////////////////////////////////// Mixed //////////////////////////////////// 28 | 29 | 30 | static final int[] ntryh = new int[]{4, 2, 3, 5}; 31 | 32 | void radf2(int ido, int l1, final double cc[], double ch[], 33 | final double wtable[], int offset) { 34 | int i, k, ic; 35 | double ti2, tr2; 36 | int iw1; 37 | iw1 = offset; 38 | 39 | for (k = 0; k < l1; k++) { 40 | ch[2 * k * ido] = cc[k * ido] + cc[(k + l1) * ido]; 41 | ch[(2 * k + 1) * ido + ido - 1] = cc[k * ido] - cc[(k + l1) * ido]; 42 | } 43 | if (ido < 2) return; 44 | if (ido != 2) { 45 | for (k = 0; k < l1; k++) { 46 | for (i = 2; i < ido; i += 2) { 47 | ic = ido - i; 48 | tr2 = wtable[i - 2 + iw1] * cc[i - 1 + (k + l1) * ido] + wtable[i - 1 + iw1] * cc[i + (k + l1) * ido]; 49 | ti2 = wtable[i - 2 + iw1] * cc[i + (k + l1) * ido] - wtable[i - 1 + iw1] * cc[i - 1 + (k + l1) * ido]; 50 | ch[i + 2 * k * ido] = cc[i + k * ido] + ti2; 51 | ch[ic + (2 * k + 1) * ido] = ti2 - cc[i + k * ido]; 52 | ch[i - 1 + 2 * k * ido] = cc[i - 1 + k * ido] + tr2; 53 | ch[ic - 1 + (2 * k + 1) * ido] = cc[i - 1 + k * ido] - tr2; 54 | } 55 | } 56 | if (ido % 2 == 1) return; 57 | } 58 | for (k = 0; k < l1; k++) { 59 | ch[(2 * k + 1) * ido] = -cc[ido - 1 + (k + l1) * ido]; 60 | ch[ido - 1 + 2 * k * ido] = cc[ido - 1 + k * ido]; 61 | } 62 | } 63 | 64 | void radf3(int ido, int l1, final double cc[], double ch[], 65 | final double wtable[], int offset) { 66 | final double taur = -0.5D; 67 | final double taui = 0.866025403784439D; 68 | int i, k, ic; 69 | double ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3; 70 | int iw1, iw2; 71 | iw1 = offset; 72 | iw2 = iw1 + ido; 73 | 74 | for (k = 0; k < l1; k++) { 75 | cr2 = cc[(k + l1) * ido] + cc[(k + 2 * l1) * ido]; 76 | ch[3 * k * ido] = cc[k * ido] + cr2; 77 | ch[(3 * k + 2) * ido] = taui * (cc[(k + l1 * 2) * ido] - cc[(k + l1) * ido]); 78 | ch[ido - 1 + (3 * k + 1) * ido] = cc[k * ido] + taur * cr2; 79 | } 80 | if (ido == 1) return; 81 | for (k = 0; k < l1; k++) { 82 | for (i = 2; i < ido; i += 2) { 83 | ic = ido - i; 84 | dr2 = wtable[i - 2 + iw1] * cc[i - 1 + (k + l1) * ido] + wtable[i - 1 + iw1] * cc[i + (k + l1) * ido]; 85 | di2 = wtable[i - 2 + iw1] * cc[i + (k + l1) * ido] - wtable[i - 1 + iw1] * cc[i - 1 + (k + l1) * ido]; 86 | dr3 = wtable[i - 2 + iw2] * cc[i - 1 + (k + l1 * 2) * ido] + wtable[i - 1 + iw2] * cc[i + (k + l1 * 2) * ido]; 87 | di3 = wtable[i - 2 + iw2] * cc[i + (k + l1 * 2) * ido] - wtable[i - 1 + iw2] * cc[i - 1 + (k + l1 * 2) * ido]; 88 | cr2 = dr2 + dr3; 89 | ci2 = di2 + di3; 90 | ch[i - 1 + 3 * k * ido] = cc[i - 1 + k * ido] + cr2; 91 | ch[i + 3 * k * ido] = cc[i + k * ido] + ci2; 92 | tr2 = cc[i - 1 + k * ido] + taur * cr2; 93 | ti2 = cc[i + k * ido] + taur * ci2; 94 | tr3 = taui * (di2 - di3); 95 | ti3 = taui * (dr3 - dr2); 96 | ch[i - 1 + (3 * k + 2) * ido] = tr2 + tr3; 97 | ch[ic - 1 + (3 * k + 1) * ido] = tr2 - tr3; 98 | ch[i + (3 * k + 2) * ido] = ti2 + ti3; 99 | ch[ic + (3 * k + 1) * ido] = ti3 - ti2; 100 | } 101 | } 102 | } 103 | 104 | void radf4(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset) { 105 | final double hsqt2 = 0.7071067811865475D; 106 | int i, k, ic; 107 | double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4; 108 | int iw1, iw2, iw3; 109 | iw1 = offset; 110 | iw2 = offset + ido; 111 | iw3 = iw2 + ido; 112 | for (k = 0; k < l1; k++) { 113 | tr1 = cc[(k + l1) * ido] + cc[(k + 3 * l1) * ido]; 114 | tr2 = cc[k * ido] + cc[(k + 2 * l1) * ido]; 115 | ch[4 * k * ido] = tr1 + tr2; 116 | ch[ido - 1 + (4 * k + 3) * ido] = tr2 - tr1; 117 | ch[ido - 1 + (4 * k + 1) * ido] = cc[k * ido] - cc[(k + 2 * l1) * ido]; 118 | ch[(4 * k + 2) * ido] = cc[(k + 3 * l1) * ido] - cc[(k + l1) * ido]; 119 | } 120 | if (ido < 2) return; 121 | if (ido != 2) { 122 | for (k = 0; k < l1; k++) { 123 | for (i = 2; i < ido; i += 2) { 124 | ic = ido - i; 125 | cr2 = wtable[i - 2 + iw1] * cc[i - 1 + (k + l1) * ido] + wtable[i - 1 + iw1] * cc[i + (k + l1) * ido]; 126 | ci2 = wtable[i - 2 + iw1] * cc[i + (k + l1) * ido] - wtable[i - 1 + iw1] * cc[i - 1 + (k + l1) * ido]; 127 | cr3 = wtable[i - 2 + iw2] * cc[i - 1 + (k + 2 * l1) * ido] + wtable[i - 1 + iw2] * cc[i + (k + 2 * l1) * ido]; 128 | ci3 = wtable[i - 2 + iw2] * cc[i + (k + 2 * l1) * ido] - wtable[i - 1 + iw2] * cc[i - 1 + (k + 2 * l1) * ido]; 129 | cr4 = wtable[i - 2 + iw3] * cc[i - 1 + (k + 3 * l1) * ido] + wtable[i - 1 + iw3] * cc[i + (k + 3 * l1) * ido]; 130 | ci4 = wtable[i - 2 + iw3] * cc[i + (k + 3 * l1) * ido] - wtable[i - 1 + iw3] * cc[i - 1 + (k + 3 * l1) * ido]; 131 | tr1 = cr2 + cr4; 132 | tr4 = cr4 - cr2; 133 | ti1 = ci2 + ci4; 134 | ti4 = ci2 - ci4; 135 | ti2 = cc[i + k * ido] + ci3; 136 | ti3 = cc[i + k * ido] - ci3; 137 | tr2 = cc[i - 1 + k * ido] + cr3; 138 | tr3 = cc[i - 1 + k * ido] - cr3; 139 | ch[i - 1 + 4 * k * ido] = tr1 + tr2; 140 | ch[ic - 1 + (4 * k + 3) * ido] = tr2 - tr1; 141 | ch[i + 4 * k * ido] = ti1 + ti2; 142 | ch[ic + (4 * k + 3) * ido] = ti1 - ti2; 143 | ch[i - 1 + (4 * k + 2) * ido] = ti4 + tr3; 144 | ch[ic - 1 + (4 * k + 1) * ido] = tr3 - ti4; 145 | ch[i + (4 * k + 2) * ido] = tr4 + ti3; 146 | ch[ic + (4 * k + 1) * ido] = tr4 - ti3; 147 | } 148 | } 149 | if (ido % 2 == 1) return; 150 | } 151 | for (k = 0; k < l1; k++) { 152 | ti1 = -hsqt2 * (cc[ido - 1 + (k + l1) * ido] + cc[ido - 1 + (k + 3 * l1) * ido]); 153 | tr1 = hsqt2 * (cc[ido - 1 + (k + l1) * ido] - cc[ido - 1 + (k + 3 * l1) * ido]); 154 | ch[ido - 1 + 4 * k * ido] = tr1 + cc[ido - 1 + k * ido]; 155 | ch[ido - 1 + (4 * k + 2) * ido] = cc[ido - 1 + k * ido] - tr1; 156 | ch[(4 * k + 1) * ido] = ti1 - cc[ido - 1 + (k + 2 * l1) * ido]; 157 | ch[(4 * k + 3) * ido] = ti1 + cc[ido - 1 + (k + 2 * l1) * ido]; 158 | } 159 | } 160 | 161 | void radf5(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset) { 162 | final double tr11 = 0.309016994374947D; 163 | final double ti11 = 0.951056516295154D; 164 | final double tr12 = -0.809016994374947D; 165 | final double ti12 = 0.587785252292473D; 166 | int i, k, ic; 167 | double ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5; 168 | int iw1, iw2, iw3, iw4; 169 | iw1 = offset; 170 | iw2 = iw1 + ido; 171 | iw3 = iw2 + ido; 172 | iw4 = iw3 + ido; 173 | 174 | for (k = 0; k < l1; k++) { 175 | cr2 = cc[(k + 4 * l1) * ido] + cc[(k + l1) * ido]; 176 | ci5 = cc[(k + 4 * l1) * ido] - cc[(k + l1) * ido]; 177 | cr3 = cc[(k + 3 * l1) * ido] + cc[(k + 2 * l1) * ido]; 178 | ci4 = cc[(k + 3 * l1) * ido] - cc[(k + 2 * l1) * ido]; 179 | ch[5 * k * ido] = cc[k * ido] + cr2 + cr3; 180 | ch[ido - 1 + (5 * k + 1) * ido] = cc[k * ido] + tr11 * cr2 + tr12 * cr3; 181 | ch[(5 * k + 2) * ido] = ti11 * ci5 + ti12 * ci4; 182 | ch[ido - 1 + (5 * k + 3) * ido] = cc[k * ido] + tr12 * cr2 + tr11 * cr3; 183 | ch[(5 * k + 4) * ido] = ti12 * ci5 - ti11 * ci4; 184 | } 185 | if (ido == 1) return; 186 | for (k = 0; k < l1; ++k) { 187 | for (i = 2; i < ido; i += 2) { 188 | ic = ido - i; 189 | dr2 = wtable[i - 2 + iw1] * cc[i - 1 + (k + l1) * ido] + wtable[i - 1 + iw1] * cc[i + (k + l1) * ido]; 190 | di2 = wtable[i - 2 + iw1] * cc[i + (k + l1) * ido] - wtable[i - 1 + iw1] * cc[i - 1 + (k + l1) * ido]; 191 | dr3 = wtable[i - 2 + iw2] * cc[i - 1 + (k + 2 * l1) * ido] + wtable[i - 1 + iw2] * cc[i + (k + 2 * l1) * ido]; 192 | di3 = wtable[i - 2 + iw2] * cc[i + (k + 2 * l1) * ido] - wtable[i - 1 + iw2] * cc[i - 1 + (k + 2 * l1) * ido]; 193 | dr4 = wtable[i - 2 + iw3] * cc[i - 1 + (k + 3 * l1) * ido] + wtable[i - 1 + iw3] * cc[i + (k + 3 * l1) * ido]; 194 | di4 = wtable[i - 2 + iw3] * cc[i + (k + 3 * l1) * ido] - wtable[i - 1 + iw3] * cc[i - 1 + (k + 3 * l1) * ido]; 195 | dr5 = wtable[i - 2 + iw4] * cc[i - 1 + (k + 4 * l1) * ido] + wtable[i - 1 + iw4] * cc[i + (k + 4 * l1) * ido]; 196 | di5 = wtable[i - 2 + iw4] * cc[i + (k + 4 * l1) * ido] - wtable[i - 1 + iw4] * cc[i - 1 + (k + 4 * l1) * ido]; 197 | cr2 = dr2 + dr5; 198 | ci5 = dr5 - dr2; 199 | cr5 = di2 - di5; 200 | ci2 = di2 + di5; 201 | cr3 = dr3 + dr4; 202 | ci4 = dr4 - dr3; 203 | cr4 = di3 - di4; 204 | ci3 = di3 + di4; 205 | ch[i - 1 + 5 * k * ido] = cc[i - 1 + k * ido] + cr2 + cr3; 206 | ch[i + 5 * k * ido] = cc[i + k * ido] + ci2 + ci3; 207 | tr2 = cc[i - 1 + k * ido] + tr11 * cr2 + tr12 * cr3; 208 | ti2 = cc[i + k * ido] + tr11 * ci2 + tr12 * ci3; 209 | tr3 = cc[i - 1 + k * ido] + tr12 * cr2 + tr11 * cr3; 210 | ti3 = cc[i + k * ido] + tr12 * ci2 + tr11 * ci3; 211 | tr5 = ti11 * cr5 + ti12 * cr4; 212 | ti5 = ti11 * ci5 + ti12 * ci4; 213 | tr4 = ti12 * cr5 - ti11 * cr4; 214 | ti4 = ti12 * ci5 - ti11 * ci4; 215 | ch[i - 1 + (5 * k + 2) * ido] = tr2 + tr5; 216 | ch[ic - 1 + (5 * k + 1) * ido] = tr2 - tr5; 217 | ch[i + (5 * k + 2) * ido] = ti2 + ti5; 218 | ch[ic + (5 * k + 1) * ido] = ti5 - ti2; 219 | ch[i - 1 + (5 * k + 4) * ido] = tr3 + tr4; 220 | ch[ic - 1 + (5 * k + 3) * ido] = tr3 - tr4; 221 | ch[i + (5 * k + 4) * ido] = ti3 + ti4; 222 | ch[ic + (5 * k + 3) * ido] = ti4 - ti3; 223 | } 224 | } 225 | } 226 | 227 | void radfg(int ido, int ip, int l1, int idl1, double cc[], double c1[], double c2[], double ch[], double ch2[], final double wtable[], int offset) { 228 | final double twopi = 2.0D * Math.PI; //6.28318530717959; 229 | int idij, ipph, i, j, k, l, j2, ic, jc, lc, ik, is, nbd; 230 | double dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h; 231 | int iw1 = offset; 232 | 233 | arg = twopi / ip; 234 | dcp = Math.cos(arg); 235 | dsp = Math.sin(arg); 236 | ipph = (ip + 1) / 2; 237 | nbd = (ido - 1) / 2; 238 | if (ido != 1) { 239 | for (ik = 0; ik < idl1; ik++) ch2[ik] = c2[ik]; 240 | for (j = 1; j < ip; j++) 241 | for (k = 0; k < l1; k++) 242 | ch[(k + j * l1) * ido] = c1[(k + j * l1) * ido]; 243 | if (nbd <= l1) { 244 | is = -ido; 245 | for (j = 1; j < ip; j++) { 246 | is += ido; 247 | idij = is - 1; 248 | for (i = 2; i < ido; i += 2) { 249 | idij += 2; 250 | for (k = 0; k < l1; k++) { 251 | ch[i - 1 + (k + j * l1) * ido] = 252 | wtable[idij - 1 + iw1] * c1[i - 1 + (k + j * l1) * ido] 253 | + wtable[idij + iw1] * c1[i + (k + j * l1) * ido]; 254 | ch[i + (k + j * l1) * ido] = 255 | wtable[idij - 1 + iw1] * c1[i + (k + j * l1) * ido] 256 | - wtable[idij + iw1] * c1[i - 1 + (k + j * l1) * ido]; 257 | } 258 | } 259 | } 260 | } else { 261 | is = -ido; 262 | for (j = 1; j < ip; j++) { 263 | is += ido; 264 | for (k = 0; k < l1; k++) { 265 | idij = is - 1; 266 | for (i = 2; i < ido; i += 2) { 267 | idij += 2; 268 | ch[i - 1 + (k + j * l1) * ido] = 269 | wtable[idij - 1 + iw1] * c1[i - 1 + (k + j * l1) * ido] 270 | + wtable[idij + iw1] * c1[i + (k + j * l1) * ido]; 271 | ch[i + (k + j * l1) * ido] = 272 | wtable[idij - 1 + iw1] * c1[i + (k + j * l1) * ido] 273 | - wtable[idij + iw1] * c1[i - 1 + (k + j * l1) * ido]; 274 | } 275 | } 276 | } 277 | } 278 | if (nbd >= l1) { 279 | for (j = 1; j < ipph; j++) { 280 | jc = ip - j; 281 | for (k = 0; k < l1; k++) { 282 | for (i = 2; i < ido; i += 2) { 283 | c1[i - 1 + (k + j * l1) * ido] = ch[i - 1 + (k + j * l1) * ido] + ch[i - 1 + (k + jc * l1) * ido]; 284 | c1[i - 1 + (k + jc * l1) * ido] = ch[i + (k + j * l1) * ido] - ch[i + (k + jc * l1) * ido]; 285 | c1[i + (k + j * l1) * ido] = ch[i + (k + j * l1) * ido] + ch[i + (k + jc * l1) * ido]; 286 | c1[i + (k + jc * l1) * ido] = ch[i - 1 + (k + jc * l1) * ido] - ch[i - 1 + (k + j * l1) * ido]; 287 | } 288 | } 289 | } 290 | } else { 291 | for (j = 1; j < ipph; j++) { 292 | jc = ip - j; 293 | for (i = 2; i < ido; i += 2) { 294 | for (k = 0; k < l1; k++) { 295 | c1[i - 1 + (k + j * l1) * ido] = 296 | ch[i - 1 + (k + j * l1) * ido] + ch[i - 1 + (k + jc * l1) * ido]; 297 | c1[i - 1 + (k + jc * l1) * ido] = ch[i + (k + j * l1) * ido] - ch[i + (k + jc * l1) * ido]; 298 | c1[i + (k + j * l1) * ido] = ch[i + (k + j * l1) * ido] + ch[i + (k + jc * l1) * ido]; 299 | c1[i + (k + jc * l1) * ido] = ch[i - 1 + (k + jc * l1) * ido] - ch[i - 1 + (k + j * l1) * ido]; 300 | } 301 | } 302 | } 303 | } 304 | } else { 305 | for (ik = 0; ik < idl1; ik++) c2[ik] = ch2[ik]; 306 | } 307 | for (j = 1; j < ipph; j++) { 308 | jc = ip - j; 309 | for (k = 0; k < l1; k++) { 310 | c1[(k + j * l1) * ido] = ch[(k + j * l1) * ido] + ch[(k + jc * l1) * ido]; 311 | c1[(k + jc * l1) * ido] = ch[(k + jc * l1) * ido] - ch[(k + j * l1) * ido]; 312 | } 313 | } 314 | 315 | ar1 = 1; 316 | ai1 = 0; 317 | for (l = 1; l < ipph; l++) { 318 | lc = ip - l; 319 | ar1h = dcp * ar1 - dsp * ai1; 320 | ai1 = dcp * ai1 + dsp * ar1; 321 | ar1 = ar1h; 322 | for (ik = 0; ik < idl1; ik++) { 323 | ch2[ik + l * idl1] = c2[ik] + ar1 * c2[ik + idl1]; 324 | ch2[ik + lc * idl1] = ai1 * c2[ik + (ip - 1) * idl1]; 325 | } 326 | dc2 = ar1; 327 | ds2 = ai1; 328 | ar2 = ar1; 329 | ai2 = ai1; 330 | for (j = 2; j < ipph; j++) { 331 | jc = ip - j; 332 | ar2h = dc2 * ar2 - ds2 * ai2; 333 | ai2 = dc2 * ai2 + ds2 * ar2; 334 | ar2 = ar2h; 335 | for (ik = 0; ik < idl1; ik++) { 336 | ch2[ik + l * idl1] += ar2 * c2[ik + j * idl1]; 337 | ch2[ik + lc * idl1] += ai2 * c2[ik + jc * idl1]; 338 | } 339 | } 340 | } 341 | for (j = 1; j < ipph; j++) 342 | for (ik = 0; ik < idl1; ik++) 343 | ch2[ik] += c2[ik + j * idl1]; 344 | 345 | if (ido >= l1) { 346 | for (k = 0; k < l1; k++) { 347 | for (i = 0; i < ido; i++) { 348 | cc[i + k * ip * ido] = ch[i + k * ido]; 349 | } 350 | } 351 | } else { 352 | for (i = 0; i < ido; i++) { 353 | for (k = 0; k < l1; k++) { 354 | cc[i + k * ip * ido] = ch[i + k * ido]; 355 | } 356 | } 357 | } 358 | for (j = 1; j < ipph; j++) { 359 | jc = ip - j; 360 | j2 = 2 * j; 361 | for (k = 0; k < l1; k++) { 362 | cc[ido - 1 + (j2 - 1 + k * ip) * ido] = ch[(k + j * l1) * ido]; 363 | cc[(j2 + k * ip) * ido] = ch[(k + jc * l1) * ido]; 364 | } 365 | } 366 | if (ido == 1) return; 367 | if (nbd >= l1) { 368 | for (j = 1; j < ipph; j++) { 369 | jc = ip - j; 370 | j2 = 2 * j; 371 | for (k = 0; k < l1; k++) { 372 | for (i = 2; i < ido; i += 2) { 373 | ic = ido - i; 374 | cc[i - 1 + (j2 + k * ip) * ido] = ch[i - 1 + (k + j * l1) * ido] + ch[i - 1 + (k + jc * l1) * ido]; 375 | cc[ic - 1 + (j2 - 1 + k * ip) * ido] = ch[i - 1 + (k + j * l1) * ido] - ch[i - 1 + (k + jc * l1) * ido]; 376 | cc[i + (j2 + k * ip) * ido] = ch[i + (k + j * l1) * ido] + ch[i + (k + jc * l1) * ido]; 377 | cc[ic + (j2 - 1 + k * ip) * ido] = ch[i + (k + jc * l1) * ido] - ch[i + (k + j * l1) * ido]; 378 | } 379 | } 380 | } 381 | } else { 382 | for (j = 1; j < ipph; j++) { 383 | jc = ip - j; 384 | j2 = 2 * j; 385 | for (i = 2; i < ido; i += 2) { 386 | ic = ido - i; 387 | for (k = 0; k < l1; k++) { 388 | cc[i - 1 + (j2 + k * ip) * ido] = ch[i - 1 + (k + j * l1) * ido] + ch[i - 1 + (k + jc * l1) * ido]; 389 | cc[ic - 1 + (j2 - 1 + k * ip) * ido] = ch[i - 1 + (k + j * l1) * ido] - ch[i - 1 + (k + jc * l1) * ido]; 390 | cc[i + (j2 + k * ip) * ido] = ch[i + (k + j * l1) * ido] + ch[i + (k + jc * l1) * ido]; 391 | cc[ic + (j2 - 1 + k * ip) * ido] = ch[i + (k + jc * l1) * ido] - ch[i + (k + j * l1) * ido]; 392 | } 393 | } 394 | } 395 | } 396 | } 397 | 398 | void rfftf1(int n, double c[], final double wtable[], int offset, double[] ch) { 399 | int i; 400 | int k1, l1, l2, na, kh, nf, ip, iw, ido, idl1; 401 | 402 | System.arraycopy(wtable, offset, ch, 0, n); 403 | 404 | nf = (int) wtable[1 + 2 * n + offset]; 405 | na = 1; 406 | l2 = n; 407 | iw = n - 1 + n + offset; 408 | for (k1 = 1; k1 <= nf; ++k1) { 409 | kh = nf - k1; 410 | ip = (int) wtable[kh + 2 + 2 * n + offset]; 411 | l1 = l2 / ip; 412 | ido = n / l2; 413 | idl1 = ido * l1; 414 | iw -= (ip - 1) * ido; 415 | na = 1 - na; 416 | if (ip == 4) { 417 | if (na == 0) { 418 | radf4(ido, l1, c, ch, wtable, iw); 419 | } else { 420 | radf4(ido, l1, ch, c, wtable, iw); 421 | } 422 | } else if (ip == 2) { 423 | if (na == 0) { 424 | radf2(ido, l1, c, ch, wtable, iw); 425 | } else { 426 | radf2(ido, l1, ch, c, wtable, iw); 427 | } 428 | } else if (ip == 3) { 429 | if (na == 0) { 430 | radf3(ido, l1, c, ch, wtable, iw); 431 | } else { 432 | radf3(ido, l1, ch, c, wtable, iw); 433 | } 434 | } else if (ip == 5) { 435 | if (na == 0) { 436 | radf5(ido, l1, c, ch, wtable, iw); 437 | } else { 438 | radf5(ido, l1, ch, c, wtable, iw); 439 | } 440 | } else { 441 | if (ido == 1) na = 1 - na; 442 | if (na == 0) { 443 | radfg(ido, ip, l1, idl1, c, c, c, ch, ch, wtable, iw); 444 | na = 1; 445 | } else { 446 | radfg(ido, ip, l1, idl1, ch, ch, ch, c, c, wtable, iw); 447 | na = 0; 448 | } 449 | } 450 | l2 = l1; 451 | } 452 | if (na == 1) return; 453 | for (i = 0; i < n; i++) c[i] = ch[i]; 454 | } 455 | 456 | void rfftf(int n, double r[], double wtable[], double[] ch) { 457 | if (n == 1) return; 458 | rfftf1(n, r, wtable, 0, ch); 459 | } 460 | 461 | void rffti1(int n, double wtable[], int offset) { 462 | 463 | final double twopi = 2.0D * Math.PI; 464 | double argh; 465 | int ntry = 0, i, j; 466 | double argld; 467 | int k1, l1, l2, ib; 468 | double fi; 469 | int ld, ii, nf, ip, nl, is, nq, nr; 470 | double arg; 471 | int ido, ipm; 472 | int nfm1; 473 | 474 | nl = n; 475 | nf = 0; 476 | j = 0; 477 | 478 | factorize_loop: 479 | while (true) { 480 | ++j; 481 | if (j <= 4) 482 | ntry = ntryh[j - 1]; 483 | else 484 | ntry += 2; 485 | do { 486 | nq = nl / ntry; 487 | nr = nl - ntry * nq; 488 | if (nr != 0) continue factorize_loop; 489 | ++nf; 490 | wtable[nf + 1 + 2 * n + offset] = ntry; 491 | 492 | nl = nq; 493 | if (ntry == 2 && nf != 1) { 494 | for (i = 2; i <= nf; i++) { 495 | ib = nf - i + 2; 496 | wtable[ib + 1 + 2 * n + offset] = wtable[ib + 2 * n + offset]; 497 | } 498 | wtable[2 + 2 * n + offset] = 2; 499 | } 500 | } while (nl != 1); 501 | break factorize_loop; 502 | } 503 | wtable[0 + 2 * n + offset] = n; 504 | wtable[1 + 2 * n + offset] = nf; 505 | argh = twopi / (n); 506 | is = 0; 507 | nfm1 = nf - 1; 508 | l1 = 1; 509 | if (nfm1 == 0) return; 510 | for (k1 = 1; k1 <= nfm1; k1++) { 511 | ip = (int) wtable[k1 + 1 + 2 * n + offset]; 512 | ld = 0; 513 | l2 = l1 * ip; 514 | ido = n / l2; 515 | ipm = ip - 1; 516 | for (j = 1; j <= ipm; ++j) { 517 | ld += l1; 518 | i = is; 519 | argld = ld * argh; 520 | 521 | fi = 0; 522 | for (ii = 3; ii <= ido; ii += 2) { 523 | i += 2; 524 | fi += 1; 525 | arg = fi * argld; 526 | wtable[i - 2 + n + offset] = Math.cos(arg); 527 | wtable[i - 1 + n + offset] = Math.sin(arg); 528 | } 529 | is += ido; 530 | } 531 | l1 = l2; 532 | } 533 | } 534 | 535 | void rffti(int n, double wtable[]) { 536 | if (n == 1) return; 537 | rffti1(n, wtable, 0); 538 | } 539 | 540 | } -------------------------------------------------------------------------------- /main/java/com/sample/audio/core/Callback.java: -------------------------------------------------------------------------------- 1 | package com.sample.audio.core; 2 | 3 | public interface Callback { 4 | void onBufferAvailable(byte[] buffer); 5 | } -------------------------------------------------------------------------------- /main/java/com/sample/audio/core/Recorder.java: -------------------------------------------------------------------------------- 1 | package com.sample.audio.core; 2 | 3 | import android.media.AudioFormat; 4 | import android.media.AudioRecord; 5 | import android.media.MediaRecorder; 6 | import android.os.Process; 7 | import android.util.Log; 8 | 9 | public class Recorder { 10 | 11 | private int audioSource = MediaRecorder.AudioSource.DEFAULT; 12 | private int channelConfig = AudioFormat.CHANNEL_IN_MONO; 13 | private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 14 | private int sampleRate = 44100; 15 | private Thread thread; 16 | private Callback callback; 17 | 18 | public Recorder() { 19 | } 20 | 21 | public Recorder(Callback callback) { 22 | this.callback = callback; 23 | } 24 | 25 | public void setCallback(Callback callback) { 26 | this.callback = callback; 27 | } 28 | 29 | public void start() { 30 | if (thread != null) return; 31 | thread = new Thread(new Runnable() { 32 | @Override 33 | public void run() { 34 | Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO); 35 | 36 | int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding); 37 | AudioRecord recorder = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, minBufferSize); 38 | 39 | if (recorder.getState() == AudioRecord.STATE_UNINITIALIZED) { 40 | Thread.currentThread().interrupt(); 41 | return; 42 | } else { 43 | Log.i(Recorder.class.getSimpleName(), "Started."); 44 | //callback.onStart(); 45 | } 46 | byte[] buffer = new byte[minBufferSize]; 47 | recorder.startRecording(); 48 | 49 | while (thread != null && !thread.isInterrupted() && recorder.read(buffer, 0, minBufferSize) > 0) { 50 | callback.onBufferAvailable(buffer); 51 | } 52 | recorder.stop(); 53 | recorder.release(); 54 | } 55 | }, Recorder.class.getName()); 56 | thread.start(); 57 | } 58 | 59 | public void stop() { 60 | if (thread != null) { 61 | thread.interrupt(); 62 | thread = null; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | 28 | 29 | 39 | 40 | -------------------------------------------------------------------------------- /main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucns/Android-Audio-Sample/adb84427f62481dc69a933a4e1a0473039edf818/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucns/Android-Audio-Sample/adb84427f62481dc69a933a4e1a0473039edf818/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucns/Android-Audio-Sample/adb84427f62481dc69a933a4e1a0473039edf818/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucns/Android-Audio-Sample/adb84427f62481dc69a933a4e1a0473039edf818/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucns/Android-Audio-Sample/adb84427f62481dc69a933a4e1a0473039edf818/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #efefef 4 | #d6d6d6 5 | #b3b3b3 6 | #a6a6a6 7 | #939393 8 | #888888 9 | #7b7b7b 10 | #747474 11 | #6c6c6c 12 | #686868 13 | #5e5e5e 14 | #4d4c4c 15 | #454545 16 | #3d3d3d 17 | #2e2e2e 18 | #282828 19 | #242424 20 | #202020 21 | #161616 22 | #121212 23 | #080808 24 | 25 | #5ebfff 26 | #3db1ff 27 | #0099ff 28 | #1281c1 29 | #145786 30 | 31 | -------------------------------------------------------------------------------- /main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 8dp 3 | 12dp 4 | 16dp 5 | 24dp 6 | 36dp 7 | 42dp 8 | 9 | 8dp 10 | 11 | -------------------------------------------------------------------------------- /main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Audio Sample 3 | 4 | -------------------------------------------------------------------------------- /main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | --------------------------------------------------------------------------------