Home | History | Annotate | Download | only in audio
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.verifier.audio;
     18 
     19 import android.content.Context;
     20 import android.media.AudioFormat;
     21 import android.media.AudioManager;
     22 import android.media.AudioTrack;
     23 import android.media.MediaPlayer;
     24 import android.net.Uri;
     25 import android.net.rtp.AudioStream;
     26 import android.util.Log;
     27 
     28 import com.android.cts.verifier.audio.wavelib.PipeShort;
     29 
     30 import java.io.IOException;
     31 
     32 public class SoundPlayerObject extends Thread {
     33     private static final String LOGTAG = "SoundPlayerObject";
     34     private MediaPlayer mMediaPlayer;
     35     private boolean isInitialized = false;
     36     private boolean isRunning = false;
     37 
     38     public PipeShort mPipe = new PipeShort(65536);
     39     private short[] mAudioShortArray;
     40 
     41     public AudioTrack mAudioTrack;
     42     public int mSamplingRate = 48000;
     43     private int mChannelConfigOut = AudioFormat.CHANNEL_OUT_MONO;
     44     private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
     45     int mMinPlayBufferSizeInBytes = 0;
     46     int mMinBufferSizeInSamples = 0;
     47 
     48     private int mStreamType = AudioManager.STREAM_MUSIC;
     49     private int mResId = -1;
     50     private boolean mUseMediaPlayer = true;
     51     private float mBalance = 0.5f; //0 left, 1 right
     52 
     53     public int getCurrentResId() {
     54         return mResId;
     55     }
     56 
     57     public int getStreamType () {
     58         return mStreamType;
     59     }
     60 
     61     public void run() {
     62         setPriority(Thread.MAX_PRIORITY);
     63         isRunning = true;
     64         while (isRunning) {
     65 
     66             if (!mUseMediaPlayer && isInitialized && isPlaying()) {
     67                 int valuesAvailable = mPipe.availableToRead();
     68                 if (valuesAvailable > 0) {
     69 
     70                     int valuesOfInterest = valuesAvailable;
     71                     if (mMinBufferSizeInSamples < valuesOfInterest) {
     72                         valuesOfInterest = mMinBufferSizeInSamples;
     73                     }
     74                     mPipe.read(mAudioShortArray, 0,valuesOfInterest);
     75                     //inject into output.
     76                     mAudioTrack.write(mAudioShortArray, 0, valuesOfInterest);
     77                 }
     78             } else {
     79                 try {
     80                     sleep(10);
     81                 } catch (InterruptedException e) {
     82                     e.printStackTrace();
     83                 }
     84             }
     85         }
     86     }
     87 
     88     public void setBalance(float balance) {
     89         mBalance = balance;
     90         if (mUseMediaPlayer) {
     91             if (mMediaPlayer != null) {
     92                 float left = Math.min(2.0f * (1.0f - mBalance), 1.0f);
     93                 float right = Math.min(2.0f * mBalance, 1.0f);
     94                 mMediaPlayer.setVolume(left, right);
     95                 log(String.format("Setting balance to %f", mBalance));
     96             }
     97         }
     98     }
     99 
    100     public void setStreamType(int streamType) {
    101         mStreamType = streamType;
    102     }
    103 
    104     public void rewind() {
    105         if (mUseMediaPlayer) {
    106             if (mMediaPlayer != null) {
    107                 mMediaPlayer.seekTo(0);
    108             }
    109         }
    110     }
    111 
    112     public void setSoundWithResId(Context context, int resId) {
    113         boolean playing = isPlaying();
    114         //release player
    115         releasePlayer();
    116         mResId = resId;
    117         if (mUseMediaPlayer) {
    118             mMediaPlayer = new MediaPlayer();
    119             try {
    120                 log("opening resource with stream type: " + mStreamType);
    121                 mMediaPlayer.setAudioStreamType(mStreamType);
    122                 mMediaPlayer.setDataSource(context.getApplicationContext(),
    123                         Uri.parse("android.resource://com.android.cts.verifier/" + resId));
    124                 mMediaPlayer.prepare();
    125             } catch (IOException e) {
    126                 e.printStackTrace();
    127             }
    128             mMediaPlayer.setLooping(true);
    129             setBalance(mBalance);
    130         } else {
    131             mMinPlayBufferSizeInBytes = AudioTrack.getMinBufferSize(mSamplingRate,
    132                     mChannelConfigOut, mAudioFormat);
    133 
    134             mMinBufferSizeInSamples = mMinPlayBufferSizeInBytes / 2;
    135             mAudioShortArray = new short[mMinBufferSizeInSamples * 4];
    136 
    137             mAudioTrack = new AudioTrack(mStreamType,
    138                     mSamplingRate,
    139                     mChannelConfigOut,
    140                     mAudioFormat,
    141                     mMinPlayBufferSizeInBytes,
    142                     AudioTrack.MODE_STREAM /* FIXME runtime test for API level 9 ,
    143                 mSessionId */);
    144             mPipe.flush();
    145             isInitialized = true;
    146         }
    147 
    148         log("done preparing media player");
    149         if (playing)
    150             play(true); //start playing if it was playing before
    151     }
    152 
    153     public boolean isPlaying() {
    154         boolean result = false;
    155         if (mUseMediaPlayer) {
    156             if (mMediaPlayer != null) {
    157                 result = mMediaPlayer.isPlaying();
    158             }
    159         } else {
    160             if (mAudioTrack != null) {
    161                 result = mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING;
    162             }
    163         }
    164         return result;
    165     }
    166 
    167     public void play(boolean play) {
    168         if (mUseMediaPlayer) {
    169             if (mMediaPlayer != null) {
    170                 if (play) {
    171                     mMediaPlayer.start();
    172                 } else {
    173                     mMediaPlayer.pause();
    174                 }
    175             }
    176         } else {
    177             if (mAudioTrack != null && isInitialized) {
    178                 if (play) {
    179                     mPipe.flush();
    180                     mAudioTrack.flush();
    181                     mAudioTrack.play();
    182                 } else {
    183                     mAudioTrack.pause();
    184                 }
    185             }
    186         }
    187     }
    188 
    189     public void finish() {
    190         play(false);
    191         releasePlayer();
    192     }
    193 
    194     private void releasePlayer() {
    195         if (mMediaPlayer != null) {
    196             mMediaPlayer.stop();
    197             mMediaPlayer.release();
    198             mMediaPlayer = null;
    199         }
    200 
    201         if (mAudioTrack != null) {
    202             mAudioTrack.stop();
    203             mAudioTrack.release();
    204             mAudioTrack = null;
    205         }
    206         isInitialized = false;
    207     }
    208 
    209     /*
    210        Misc
    211     */
    212     private static void log(String msg) {
    213         Log.v(LOGTAG, msg);
    214     }
    215 }
    216