效果图

源码

源码下载,请先移步Android左右声道的控制

我这里主要是用到了AudioTrack实现的左右声道的控制,手机一般都只有两个声道,即左声道和右声道,我们在输出的时候可以选择单声道,也可以选择双声道(立体声)。

查看了AudioTrack的API,提供了play()pause()stop()write()等一系列的方法。
通过write()方法,可以实现将音频数据发送出去(播放出来)。

AudioTrack对象的构造

有三个构造方法

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_MONOAudioFormat.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);}@Overridepublic 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;}}
}

使用

从头开始播放

mPlayThread = new PlayThread(this, "tts1.pcm");
mPlayThread.start();

暂停

mPlayThread.pause();

暂停后继续播放

mPlayThread.play();

停止播放

mPlayThread.stopp();
mPlayThread = null;

左右声道控制

// 禁用左声道(右声道同理)
mPlayThread.setChannel(false, true);

向左右声道单独输出不同的音频数据

也是一个很”呵呵“的做法,但是依然还没有找到更好的方法。
构造两个AudioTrack对象,分别输出两个音频,一个禁用左声道,一个禁用右声道,达到预期效果。

mChannelLeftPlayer = new PlayThread(this, "tts1.pcm");
mChannelRightPlayer = new PlayThread(this, "tts2.pcm");mChannelLeftPlayer.setChannel(true, false);
mChannelRightPlayer.setChannel(false, true);mChannelLeftPlayer.start();
mChannelRightPlayer.start();

Android左右声道的控制相关推荐

  1. Android左右声道控制软件,Android左右声道的控制

    效果图 源码 源码下载,请先移步Android左右声道的控制 我这里主要是用到了AudioTrack实现的左右声道的控制,手机一般都只有两个声道,即左声道和右声道,我们在输出的时候可以选择单声道,也可 ...

  2. android 左右声道,Android左右声道的控制

    效果图 源码 我这里主要是用到了AudioTrack实现的左右声道的控制,手机一般都只有两个声道,即左声道和右声道,我们在输出的时候可以选择单声道,也可以选择双声道(立体声). 查看了AudioTra ...

  3. 蓝牙模块hc05原理图_使用步进电机和Android App的蓝牙控制迷你升降机

    背景知识视频教程 使用App Inventor创建Android应用​viadean.com Arduino微控制器:学习Arduino制作项目 - 国外课栈​viadean.com Arduino ...

  4. android 手势事件 重写,Android实现通过手势控制图片大小缩放的方法

    本文实例讲述了Android实现通过手势控制图片大小缩放的方法.分享给大家供大家参考,具体如下: 该程序实现的是通过手势来缩放图片,从左向右挥动图片时图片被放大,从右向左挥动图片时图片被缩小,挥动速度 ...

  5. android多个闹钟实现,Android编程实现PendingIntent控制多个闹钟的方法

    本文实例讲述了Android编程实现PendingIntent控制多个闹钟的方法.分享给大家供大家参考,具体如下: 要用 android.app.PendingIntent.getBroadcast( ...

  6. android 通过adb命令控制wifi开关

    android 通过adb命令控制wifi开关 2017年08月23日 17:47:46 刘国栋 阅读数:14598 版权声明:本文为博主原创文章,转载请声明文章出处. https://blog.cs ...

  7. android系统手机流量控制方法,如何实现Android手机流量的控制

    如何实现Android手机流量的控制 随着智能手机变得强大起来,也变得很耗流量了.那么如何实现Android手机流量的控制呢?下面就让jy135小编来告诉大家吧,欢迎阅读. 1.打开手机,进入设置按钮 ...

  8. android:elevation属性,控制View底部渐变阴影

    android:elevation属性,控制View底部渐变阴影 android:elevation这一属性,可以控制View底部渐变阴影,给一个View在其底部增加一定的灰度渐变阴影效果,如图: 上 ...

  9. Android系统的音量控制

    Android系统的音量控制 效果图: GitHub GitHub(源码):https://github.com/kongqw/VolumeController 方法 获取AudioManager m ...

最新文章

  1. 企业级 SpringBoot 教程 (二十三)异步方法
  2. php证券k线图,php画K线图的一个工具
  3. 组合筛选vue_Vue 3 组合式API介绍
  4. 神秘大三角(判断点与三角形的关系)
  5. cacti pdo_mysql_搭建配置cacti,采集信息监控
  6. mysql5.7.11解压版安装_Mysql5.7.11在windows10上的安装与配置(解压版)
  7. WDA 程序文本翻译OTR
  8. 图书馆数字化库存管理_将公共领域中的任何图书数字化
  9. c++除法保留小数_Golang中除法和取模运算与Python3的区别
  10. Java基础学习总结(185)—— Java 在云原生时代的进化
  11. 项目实用-不登录就无法访问主页
  12. windows快捷键一览表
  13. 计算机id和密码忘了怎么办,苹果平板电脑忘了ID号和密码怎么办?
  14. 浏览器清理缓存的几种方法
  15. Java对接支付宝的支付、退款、提现
  16. off邮箱服务器怎么看,没有和账号服务器连接 Kick Off 怎么办?
  17. 说明文中国第一台亮子计算机揭秘,2018届九年级语文中考复习(河南)课件:第2部分 第二讲 说明文阅读 2017名题强化训练.ppt...
  18. 纯 html 以及 js 多域名跳转
  19. 多表联查时的条件筛选
  20. 面试官问出这几道算法题,你能扛住么?

热门文章

  1. RealityCapture场景建模笔记
  2. 在C++与python间传视频帧
  3. JMS之——ActiveMQ消息持久化
  4. EditText禁止输入表情
  5. 私域流量运营之社交裂变
  6. 删除xml或者图像文件夹多余的文件
  7. 熬夜整理Java面试笔试题,你还看不懂吗?
  8. GIT 中如何打标签(git tag)
  9. 思考项目 求1+2的2次方+3的3次方+4的4次方+5的5次方+6的6次方的值。(异种循环嵌套)
  10. Arduino Uno + PAJ7620U2 实现手势识别控制LED灯工作