Android左右声道的控制

AudioTrack (int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)

AudioTrack (int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId)

AudioTrack (AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId)




主要参数有如下几个



*   streamType:以什么形式播放

    

    *   STREAM\_VOICE\_CALL

    *   STREAM\_SYSTEM

    *   STREAM\_RING

    *   STREAM\_MUSIC

    *   STREAM\_ALARM

    *   STREAM\_NOTIFICATION

*   sampleRateInHz:采样率

    

*   channelConfig:声道

    

    *   AudioFormat.CHANNEL\_OUT\_MONO:输出单声道音频数据

    *   AudioFormat.CHANNEL\_OUT\_STEREO:输出双声道音频数据(立体声)

*   audioFormat:音频数据格式

    

*   mode:缓冲模式

    

    *   MODE\_STATIC:一次性将音频载入以后再播放

    *   MODE\_STREAM:以流的形式,加载一点就播放一点



把channelConfig的相关参数都看了一遍,没发现有可以指定向某声道发送数据的,只能通过`AudioFormat.CHANNEL_OUT_MONO`和`AudioFormat.CHANNEL_OUT_STEREO`选择是输出单声道的音频数据还是双声道的音频数据。



左右声道控制

======



构造的时候不能选择指定声道输出音频,但是有这样一个方法



setStereoVolume(float leftGain, float rightGain)




可以通过把某一个声道的音量设置到最小,达到只想某个声道输出音频的效果。  

我自己也有点”呵呵“,但是也没有发现还有别的方法可以实现这样的效果。



> 这个方法还有一点小问题,在个别手机上,即使将某个声道的声音设置到了最小,也还是会有一点声音,这个我也还没有搞清楚为什么,个人猜测可能和手机硬件有关系。



封装

==



我这里的缓冲模式使用的`MODE_STREAM`的形式,以流的形式播放,因为这个逻辑要稍微复杂一点,尤其是暂停以后再继续播放的位置。



package kong.qingwei.androidsoundmanagerdemo;

import android.app.Activity;

import android.media.AudioFormat;

import android.media.AudioManager;

import android.media.AudioTrack;

import android.util.Log;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

/**

  • Created by kqw on 2016/8/26.

  • 播放音乐的线程

*/

public class PlayThread extends Thread {

// 采样率

private int mSampleRateInHz = 16000;

// 单声道

private int mChannelConfig = AudioFormat.CHANNEL_OUT_MONO;

// 双声道(立体声)

// private int mChannelConfig = AudioFormat.CHANNEL_OUT_STEREO;



private static final String TAG = "PlayThread";

private Activity mActivity;

private AudioTrack mAudioTrack;

private byte[] data;

private String mFileName;



public PlayThread(Activity activity, String fileName) {

    mActivity = activity;

    mFileName = fileName;



    int bufferSize = AudioTrack.getMinBufferSize(mSampleRateInHz, mChannelConfig, AudioFormat.ENCODING_PCM_16BIT);

    mAudioTrack = new AudioTrack(

            AudioManager.STREAM_MUSIC,

            mSampleRateInHz,

            mChannelConfig,

            AudioFormat.ENCODING_PCM_16BIT,

            bufferSize,

            AudioTrack.MODE_STREAM);

}



@Override

public void run() {

    super.run();

    try {

        if (null != mAudioTrack)

            mAudioTrack.play();



        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        InputStream inputStream = mActivity.getResources().getAssets().open(mFileName);



        // 缓冲区

        byte[] buffer = new byte[1024];

        // 播放进度

        int playIndex = 0;

        // 是否缓冲完成

        boolean isLoaded = false;

        // 缓冲 + 播放

        while (null != mAudioTrack && AudioTrack.PLAYSTATE_STOPPED != mAudioTrack.getPlayState()) {

            // 字符长度

            int len;

            if (-1 != (len = inputStream.read(buffer))) {

                byteArrayOutputStream.write(buffer, 0, len);

                data = byteArrayOutputStream.toByteArray();

                Log.i(TAG, "run: 已缓冲 : " + data.length);

            } else {

                // 缓冲完成

                isLoaded = true;

            }



            if (AudioTrack.PLAYSTATE_PAUSED == mAudioTrack.getPlayState()) {

                // TODO 已经暂停

            }

            if (AudioTrack.PLAYSTATE_PLAYING == mAudioTrack.getPlayState()) {

                Log.i(TAG, "run: 开始从 " + playIndex + " 播放");

                playIndex += mAudioTrack.write(data, playIndex, data.length - playIndex);

                Log.i(TAG, "run: 播放到了 : " + playIndex);

                if (isLoaded && playIndex == data.length) {

                    Log.i(TAG, "run: 播放完了");

                    mAudioTrack.stop();

                }



                if (playIndex < 0) {

                    Log.i(TAG, "run: 播放出错");

                    mAudioTrack.stop();

                    break;

                }

            }

        }

        Log.i(TAG, "run: play end");

    } catch (IOException e) {

        e.printStackTrace();

    }

}



/**

 * 设置左右声道平衡

 *

 * @param max     最大值

 * @param balance 当前值

 */

public void setBalance(int max, int balance) {

    float b = (float) balance / (float) max;

    Log.i(TAG, "setBalance: b = " + b);

    if (null != mAudioTrack)

        mAudioTrack.setStereoVolume(1 - b, b);

}



/**

 * 设置左右声道是否可用

 *

 * @param left  左声道

 * @param right 右声道

 */

public void setChannel(boolean left, boolean right) {

    if (null != mAudioTrack) {

        mAudioTrack.setStereoVolume(left ? 1 : 0, right ? 1 : 0);

        mAudioTrack.play();

    }

}



public void pause() {

    if (null != mAudioTrack)

        mAudioTrack.pause();

}



public void play() {

    if (null != mAudioTrack)

        mAudioTrack.play();

}



public void stopp() {

    releaseAudioTrack();

}



private void releaseAudioTrack() {

    if (null != mAudioTrack) {

        mAudioTrack.stop();

        mAudioTrack.release();

        mAudioTrack = null;

    }

}

}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值