一个特殊需求的环形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 size
	private 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;
    }

}
时间: 2024-10-25 06:00:33

一个特殊需求的环形Buffer设计的相关文章

HBase概念学习(八)开发一个类twitter系统之表设计

这边文章先将可能的需求分析一下,设计出HBase表,下一步再开始编写客户端代码. TwiBase系统 1.背景 为了加深HBase基本概念的学习,参考HBase实战这本书实际动手做了这个例子. 2.需求 这是一个用户推特系统,用户登陆到系统,需要维护用户的基本信息,然后用户可以发帖和其他用户进行互动.用户之间可以相互关注,用户可以浏览关注用户的推文等等. 这是一个比较简单的推特系统,不考虑用户之间的私信,用户评论推特等功能. 3.概要设计 3.1表设计 首先需要设计三个表:用户表,推特表以及用户

分析需求场景对产品设计的意义

需求场景是一种更接地气的分析和描述用户需求的方法(我个人偏爱“需求场景”这个词).它应该拥有这样的结构: “在某某时间(when),某某地点(where),周围出现了某些事物时(with what),特定类型的用户(who)萌发了某种欲望(desire),会想到通过某种手段(method)来满足欲望.” 1.需求场景的意义 传统的软件开发流程中,产品经理/产品策划首先会提供一份功能列表.这种功能列表所使用的描述方式往往是以程序为导向的,比如“商品列表支持按照价格从低到高排序”. 这种描述方式的弊

不做需求复印机——批量操作流程设计

相信每个技术人员都不会甘心做"需求复印机".    不做需求复印机,有两种简单的方式.一种是在代码/模块/系统的结构上下功夫,例如前面几篇设计方案(审批.分发等).另一种则是直接对业务流程开刀,例如这篇文章要举的例子. 背景 大家一定都遇到过"批处理"这类需求.这次的背景就是一个批处理需求.按产品提出的需求,系统流程是这样的:     如果将这个流程直接"复印"到系统.代码中,显而易见会有性能风险. 思路 这个需求的业务逻辑并不复杂,设计的关注点

如何做一个软件需求分析师(转来的)

这篇不想再去重复一个软件需求分析员的知识体系结构,而是挑重点来谈下成为一个合格的软件需求分析人员的关键点. 我原来对软件需求的定义或描述更多是偏于对现实世界的定义,而对软件架构的描述为现实到实现之间的第一层抽象.在这里纠正 一下即:用户需求是对现实世界的定义,而 软件系统需求是现实到实现的第一层抽象,即业务建模和软件系统用例建模.在原来的软件工程里面我们更多谈到的一个词是系统分析员,我现在将其拆分为了软件 需求BA和系统架构SA两个角色.而实际上一个真正优秀的软件需求人员必须具备两方面的能力.

软件需求分、架构设计与建模最佳实践

软件需求分.架构设计与建模最佳实践 cxx 2019-04-13 一.为什么要详细设计,价值? 在多人团队环境中,详细设计驱动开发可实现明确交付的目标和标准 可复用的设计成果 提高代码的可维护性 可对交付进行工作量和质量的评估 实现知识传承,提高软件生命周期 二.控制软件复杂性的基本方法 分解法 抽象法 三.UML有哪些元素 结构 行为 四.基于用户目标的需求组织形式 交互式需求 清晰的责任 场景化 文档的五大功效 有助于编写使用手册 测试用例转化:帮助开发人员设计测试用例 需求用例 利于详细设

Linux下一个简单的日志系统的设计及其C代码实现

1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回值及其执行情况.脚本执行及调用情况等.通过阅读日志文件,我们能够较快地跟踪程序流程,并发现程序问题. 因此,熟练掌握日志系统的编写方法并快速地阅读日志文件,是对一个软件开发工程师的基本要求. 本文详细地介绍了Linux下一个简单的日志系统的设计方法,并给出了其C代码实现.本文为相关开发项目Linux

一个Linux内核的自旋锁设计-接力嵌套堆栈式自旋锁

锁的开销 锁的开销是巨大的,特别是对于多核多处理来讲.       引入多处理,本身就是为了将并行化处理以提高性能,然而由于存在共享临界区,而这个临界区同时只能有一个线程访问(特别是对于写操作),那么本来并行的执行流在这里被串行化了,形象地看,这里好像是宽阔马路上的一个瓶颈,由于串行化是本质上存在的,因此该瓶颈就是不可消除的.问题是线程执行流如何度过这个瓶颈,很显然,它们谁都绕不开,现在问题是是它们到达这个瓶颈时该怎么办.       很显然,斗殴抢先是一种不合理但实用的简单方案,朴素的自旋锁就

一个渲染需求

用unity3d做游戏也有一段时间了,这周有一个渲染的需求,用到的技术不算很深,但确实也比较繁琐,值得记录一下. 需求大概是这样的,有四层图,我们称为A,B,C,D四层.他们的Blend顺序是A->B->C->D,其中C对D的Blend算法使用的是PS中的叠加算法,B->C,D是替换,A->B,C,D也是PS的叠加.这个问题的难点在于两部分:第一,有部分层的Blend算法是使用的PS的叠加,而叠加公式为(B < 128) ? (2 * A * B / 255):(255

一个简单的DELPHI程序注册码设计 .

当你辛辛苦苦用DELPHI做好了一个你认为十分不错的程序,你是否想把它发布出去成为共享软件呢  做为一个共享软件,注册码肯定是少不了的,你可以通过判断程序是否注册来进行功能,时间或一些其它限制.现在就介绍一种简单的注册码制造方法.思路是这样的:程序运行时先检测注册表,如果找到注册项,则表明已经注册,如果没有找到注册项,则提示要求注册. <注册例程>在DELPHI下新建一工程,放置Edit1,Edit2,Label1,Label2,Button1组件.具体代码如下:unit Unit1;inte