音频应用   音频插件联盟,正版插件,欢迎大家选择!

 找回密码
 快速注册

QQ登录

只需一步,快速开始

阅读: 17884|回复: 2

[技术] Android高级音频应用

[复制链接]

1万

积分

35

听众

4163

音贝

超级版主

Rank: 28Rank: 28Rank: 28Rank: 28

积分
10312
发表于 2016-3-24 | |阅读模式
音频应用公众号资讯免费发布推广
说到音频应用,首先想到的就是音乐播放器。有些播放器可以播放流媒体,有些可以播放本地音乐文件。随着Android平台的演变,需要更多高级的音频API。好在谷歌新增了这方面的API,支持低延迟的音频流媒体和录制。



Android音频API提供了一些高级的功能,开发者可以把它们集成到自己的应用中。有了这些API,现在可以更容易地实现VoIP应用程序,构建定制的流媒体音乐客户端,实现低延迟的游戏音效。此外,还有提供文本到语音转换以及语音识别的API,用户可以直接使用音频和应用交互,而不需要使用用户界面或者触控技术。



低延迟音频


Android有四个用来播放音频的API(算上MIDI的话一共五个)和三个用来录音的API。接下来会简要的介绍这些API,以及一些高级用法示例。



①音频播放API


音乐播放默认使用MediaPlayer。该类适合播放音乐或者视频,既能播放流式资源,还可以播放本地文件。每个MediaPlayer都有一个关联的状态机,需要在应用程序中跟踪这些状态。开发者可以使用MediaPlayer类的API在自己应用中嵌入音乐或者视频播放功能,而无需额外处理或者考虑延迟要求。



第二个选择是SoundPool类,它提供了低延迟支持,适合播放音效和其他比较短的音频,比如可以使用SoundPool播放游戏声音。但是,它不支持音频流,所以不适合那些需要实时音频流处理的应用,如VoIP。



第三个选择是AudioTrack类,它允许把音频流缓冲到硬件中,支持低延迟播放,甚至适合流媒体场景。AudioTrack类通常提供足够低的延迟,可在VoIP或类似应用中使用。



下面的代码展示了如何在VoIP应用中使用AudioTrack:

欢迎厂家入驻,推文!免费!微信:yinpinyingyong

1万

积分

35

听众

4163

音贝

超级版主

Rank: 28Rank: 28Rank: 28Rank: 28

积分
10312
 楼主| 发表于 2016-3-24 |
public class AudioTrackDemo {    private final int mMinBufferSize;    private final AudioTrack mAudioTrack;    public AudioTrackDemo() {        this.mMinBufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);        this.mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, this.mMinBufferSize*2, AudioTrack.MODE_STREAM);    }    public void playPcmPacket(byte[] pcmData) {        if (this.mAudioTrack != null && this.mAudioTrack.getState() == AudioTrack.STATE_INITIALIZED) {            if (this.mAudioTrack.getPlaybackRate() != AudioTrack.PLAYSTATE_PLAYING) {                this.mAudioTrack.play();            }            this.mAudioTrack.write(pcmData, 0, pcmData.length);        }    }    public void stopPlayback() {        if (this.mAudioTrack != null) {            this.mAudioTrack.stop();            this.mAudioTrack.release();        }    }}
欢迎厂家入驻,推文!免费!微信:yinpinyingyong

1万

积分

35

听众

4163

音贝

超级版主

Rank: 28Rank: 28Rank: 28Rank: 28

积分
10312
 楼主| 发表于 2016-3-24 |
首先,确定音频流的最小缓冲区大小。要做到这一点,需要知道采样率,数据是单声道还是立体声,以及是否使用8位或者16位PCM编码。然后以采样率和采样大小作为参数调用AudioTrack.getMinBufferSize(),该方法会以字节形式返回AudioTrack实例的最小缓冲区大小。



接下来,根据需要使用正确参数创建AudioTrack实例。第一个参数为音频的类型,不同的应用使用不同的值。对VoIP应用来说,使用STREAM_VOICE_CALL,而对于流媒体音乐应用则使用STREAM_MUSIC。



具体的选择有:

STREAM_ALARM:手机闹铃的声音

STREAM_MUSIC:手机音乐的声音

STREAM_DTMF:DTMF音调的声音

STREAM_RING:电话铃声的声音

STREAM_NOTFICATION:系统提示的声音

STREAM_SYSTEM:系统的声音

STREAM_VOICE_CALL:语音电话声音




第二,第三,第四个参数根据使用场景会有所不同。这些参数分别表示采样率,立体声或者单声道,以及采样大小。一般而言,一个VoIP应用会使用16KHZ的16位单声道,而常规的音乐CD可能采用44.1KHZ的16位立体声。16位立体声高采样率需要更大的缓冲区以及更多的数据传输,但是音质会更好。所有的Android设备都支持PCM以8KHZ,16KHZ,44.1KHZ的采样率播放8或者16位立体声。



缓冲区大小参数应该是最小缓冲区的倍数,实际取决于具体的需求,有时网络延迟等因素也会影响缓冲区大小。

任何时候都应该避免使用空的缓冲区,因为可能导致播放出现故障。



最后一个参数决定只发送一次音频数据(MODE_STATIC)还是连续发送数据流(MODE_STREAM)。第一种情况需要一次发送整个音频剪辑。对于持续发送音频流的情况,可以发送任大小块的PCM数据,处理流媒体音乐或者VoIP通话可以会使用这种方式。



②录制API


谈到录制音频,首先要考虑的API是MediaRecorder。和MediaPlayer类似,需要在应用代码中跟踪MediaRecorder类的内部状态。由于MediaRecorder只能把录音保存到文件中,所以它不适合录制流媒体。

如果需要录制流媒体,可以使用AudioRecord,和刚才展示的代码非常类似。



下面的示例显示了如何创建AudioRecord实例录制16位单声道16KHZ的音频采样:

public class AudioRecordDemo {
    private final AudioRecord mAudioRecord;
    private final int mMinBufferSize;
    private boolean mDoRecord = false;

    public AudioRecordDemo() {
        this.mMinBufferSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        this.mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 16000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, this.mMinBufferSize * 2);
    }

    public void writeAudioToStream(OutputStream stream){
        this.mDoRecord=true;
        this.mAudioRecord.startRecording();
        byte[] buffer=new byte[this.mMinBufferSize*2];
        while(this.mDoRecord){
            int byteWritten=this.mAudioRecord.read(buffer,0,buffer.length);
            try{
                stream.write(buffer,0,byteWritten);
            }catch(IOException e){
                this.mDoRecord=false;
            }
        }
        this.mAudioRecord.stop();
        this.mAudioRecord.release();
    }

    public void stopRecording(){
        this.mDoRecord=false;
    }


}

因为和AudioTrack的创建过程非常类似,在使用VoIP或者类似应用时可以很方便地把它们结合起来。



相信学过多媒体的人对采样率等这些东西并不陌生,如果缺乏这方面的知识,可以适当的补充后在来看这段代码。

如果看的认真的人会发现本文只介绍了三个播放API和两个录制API,说好的四个的三个呢?其实最后一个不是一两句就能说清楚,还需要单独列出一篇文章讲解——OpenSL ES请关注本博客后续会讲解到。
欢迎厂家入驻,推文!免费!微信:yinpinyingyong
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

音频应用搜索

小黑屋|手机版|音频应用官网微博|音频招标|音频应用 (鄂ICP备16002437号)

Powered by Audio app

快速回复 返回顶部 返回列表