只想划水的咸鱼 2019-02-19 13:51
浏览 513

Android:使用 AudioRecord 采集音频PCM并保存到Treemap中,但播放出现异常

最近在实现一个功能,做游戏客户端的音频采集,播放的。想调用AudioRecord获取PCM并用treemap保存。并用AudioTrack的stream模式尝试播放,但是在播放时却全是噪音。已尝试搜索过问题的解决方法,但都是用文件流的方式,上头要求不要创建文件。代码如下:

public class testRecorder{
    private static final String TAG = "jqd";
    private boolean isRecording;
    private AudioRecord audioRecord;
    private AudioTrack audioTrack;
    private TreeMap<Integer,byte[]> map;
    private String keyList = "";
    //treeMap<Int,byte[]> 帧的内存载体实例 TODO
    //开始录音
    public void startRecord()
    {
        final int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_INHZ,
                CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize);

        final byte data[] = new byte[minBufferSize];
        map = new TreeMap<Integer, byte[]>();

        audioRecord.startRecording();
        isRecording = true;

        new Thread(new Runnable() {
            @Override
            public void run() {
                int key = 0;
                while (isRecording) {
                    key += 1;
                    int read = audioRecord.read(data, 0, minBufferSize);

                    // 如果读取音频数据没有出现错误,就将数据写入到treeMap
                    if (AudioRecord.ERROR_INVALID_OPERATION != read)
                        map.put(key,data);
                }
            }
        }).start();
    }
    //停止录音
    public void stopRecord()
    {
        isRecording = false;
        // 释放资源
        if (null != audioRecord) {
            audioRecord.stop();
            audioRecord.release();
            audioRecord = null;
        }
    }
    //获取序列化数据 TODO
    public String getRecordData()
    {
        return null;
    }

    /**
     * 播放,使用stream模式
     */
    public void playInModeStream() {
        /*
         * SAMPLE_RATE_INHZ 对应pcm音频的采样率
         * channelConfig 对应pcm音频的声道
         * AUDIO_FORMAT 对应pcm音频的格式
         * */
        int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
        final int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_INHZ, channelConfig, AUDIO_FORMAT);
        audioTrack = new AudioTrack(
                new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .build(),
                new AudioFormat.Builder().setSampleRate(SAMPLE_RATE_INHZ)
                        .setEncoding(AUDIO_FORMAT)
                        .setChannelMask(channelConfig)
                        .build(),
                minBufferSize,
                AudioTrack.MODE_STREAM,
                AudioManager.AUDIO_SESSION_ID_GENERATE);
        audioTrack.play();

        new Thread(new Runnable() {
            @Override
            public void run() {
                byte[] tempBuffer = new byte[minBufferSize];
                Iterator iter = map.keySet().iterator();
                int key = NULL;
                while (iter.hasNext()) {
                    key = (Integer) iter.next();
                    keyList = keyList + key;

                    tempBuffer = map.get(key);
                    audioTrack.write(tempBuffer, 0, tempBuffer.length);
                }
            }
        }).start();
    }
}
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 微信会员卡接入微信支付商户号收款
    • ¥15 如何获取烟草零售终端数据
    • ¥15 数学建模招标中位数问题
    • ¥15 phython路径名过长报错 不知道什么问题
    • ¥15 深度学习中模型转换该怎么实现
    • ¥15 HLs设计手写数字识别程序编译通不过
    • ¥15 Stata外部命令安装问题求帮助!
    • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
    • ¥15 TYPCE母转母,插入认方向
    • ¥15 如何用python向钉钉机器人发送可以放大的图片?