一个特殊需求的环形Buffer设计

最近有一个特别坑人的需求,厂家平板提供了一个回声消除接口,但每次只能读固定大小的字节数,但我们的编码器每次读取的自己数和这个大小不一样,于是就萌生了一种做一个buffer来临时存储声音数据,然后编码器再去读取,这样不管厂家每次读多少个自己,codec这边也可以控制读取的字节数了。

首先映入眼帘的肯定首选环形buffer

我先定义一个writeIndex 一个 readIndex,和一个当前buffer已经放入数据的大小 size,重点就在于判断何时可写入数据,何时又可以读出数据。

可写入必须要buffer里面有足够多的剩余空间,比如我每次厂家接口只能得到512byte ,,那么buffer里面必须有>=512的空间,这样才能往buffer里面push ,get的时候因为codec每次都是读取320个byte,那么必须确保当前buffer里面有>=320个byte的内容,最后就是读写到头的时候需要回到开头这个就比较简单了,以下贴出代码,帮助那些需要写这种特殊环形buffer的同学们:

/* * Author: Vincent Luo * Date : 20150409 * Description: 用于声音数据的缓冲,put 每次是512 ,get 每次是320,保证数据的同步 * */public class RoundQueue {private final static String TAG = "RoundQueue";private final int PUT = 512;private final int GET = 320;private int readIndex = 0;private int writeIndex = 0;private static final int MAX_SIZE = 512*100;private byte[] voiceData = new byte[MAX_SIZE];private int size = 0;//current data sizeprivate boolean isFull(){return (MAX_SIZE – size < PUT)?true:false;}private boolean isEmpty(){return size < GET?true:false;}public synchronized boolean putVoiceData(byte[] data){if(!isFull()){System.arraycopy(data, 0, voiceData, writeIndex, data.length);writeIndex = (writeIndex + PUT) % MAX_SIZE;size+=PUT;return true;}else{Log.e(TAG,"Buffer is not enough readIndex = " + readIndex + ",writeIndex = " + writeIndex);}return false;}public synchronized boolean getVoiceData(byte[] data){if(!isEmpty()){System.arraycopy(voiceData, readIndex, data, 0, data.length);readIndex = (readIndex + GET) % MAX_SIZE;size-=GET;return true;}else{Log.e(TAG,"Buffer is empty readIndex = " + readIndex + ",writeIndex = " + writeIndex);}return false;}public synchronized void clear(){size = readIndex = writeIndex = 0;}}

收敛自己的脾气,偶尔要刻意沉默,

一个特殊需求的环形Buffer设计

相关文章:

你感兴趣的文章:

标签云: