在音频流解析过程中,常常会涉及到顺序读取某些bit的操作。

#include<stdio.h>

typedef struct _BIT_BUF {
unsigned char buffer[1024];
unsigned int byteSize;
unsigned int bytePosition;
unsigned int bitPosition;
unsigned int wBytePosition;
unsigned int wBitPosition;
}tBitBuffer;

//mask:baoliu保留低bit位,可用while 循环0x1右移bit-1 位。

unsigned int mask(unsigned int bit){
  switch (bit) {
    case 1:
      return 0x1;
    break;
    case 2:
      return 0x3;
    break;
    case 3:
      return 0x7;
    break;
    case 4:
      return 0xf;
    break;
    case 5:
      return 0x1f;
    break;
    case 6:
      return 0x3f;
    break;
    case 7:
      return 0x7f;
    break;
    case 8:
      return 0xff;
    break;

  case 9:
    return 0x1ff;
  break;
  case 10:
    return 0x3ff;
  break;
  case 11:
    return 0x7ff;
  break;
  case 12:
    return 0xfff;
  break;
  case 13:
    return 0x1fff;
  break;
  case 14:
    return 0x3fff;
  break;
  case 15:
    return 0x7fff;
  break;
  case 16:
    return 0xffff;
  break;

  }
}

//顺序读取bitbuffer 中的bits位,返回结果
unsigned long bitBuffer_readBits(tBitBuffer *pBitBuffer, unsigned int bits) {
  unsigned long result = 0;
  if (bits > 64) {
    return 0;
  }
  

  if (pBitBuffer->bytePosition * 8 + (pBitBuffer->bitPosition + bits ) >pBitBuffer->wBytePosition * 8 + pBitBuffer->wBitPosition) {
  printf("L%d, error,no data,bytePos:%d, bitPos:%d, wBytePos: %d, wBitPos:%d\n",__LINE__, pBitBuffer->bytePosition, pBitBuffer->bitPosition, pBitBuffer->wBytePosition,     pBitBuffer->wBitPosition);
  return 0;
}

  unsigned int bitsRemainning = 8 - pBitBuffer->bitPosition;
  while (bits != 0) {
    printf("bits:%d,bitPositon:%d, bitsRemainning:%d\n", bits, pBitBuffer->bitPosition, bitsRemainning);
    if (bitsRemainning > bits) {
      result <<= bits;
      pBitBuffer->bitPosition += bits;
      bitsRemainning -= bits;
      result |= (pBitBuffer->buffer[pBitBuffer->bytePosition] >> bitsRemainning) & mask(bits);
      printf("result:0x%x\n",result);
      bits = 0;
    }
    else {
      result <<= bitsRemainning;
      result |= pBitBuffer->buffer[pBitBuffer->bytePosition] & mask(bitsRemainning);
      printf("result:0x%x\n",result);
      bits -= bitsRemainning;
      pBitBuffer->bitPosition += bitsRemainning;
    }
    if (pBitBuffer->bitPosition == 8) {
      pBitBuffer->bitPosition = 0;
      bitsRemainning = 8;
      pBitBuffer->bytePosition++;
    }
  }
  return result;
}

//顺序向bitBuffer写bits位,其值为value

int bitBuffer_writeBits(tBitBuffer *pBitBuffer,unsigned int bits,unsigned int value) {

  unsigned int bitsRemainning = 8 - pBitBuffer->wBitPosition;
  while (bits != 0) {
    printf("bits:%d,bitPositon:%d, bitsRemainning:%d\n", bits, pBitBuffer->wBitPosition, bitsRemainning);
    if (bitsRemainning >= bits) {
      value <<= bitsRemainning - bits;
      pBitBuffer->buffer[pBitBuffer->wBytePosition] |= value;
      pBitBuffer->wBitPosition += bits;
      bitsRemainning -= bits;
      bits = 0;
      printf("L%d,value:0x%x, bits:%d, buffer[%d, 0x%x] \n",__LINE__, value, bits, pBitBuffer->wBytePosition, pBitBuffer->buffer[pBitBuffer->wBytePosition]);
    }
    else {
      pBitBuffer->buffer[pBitBuffer->wBytePosition] <<= bitsRemainning;
      pBitBuffer->buffer[pBitBuffer->wBytePosition] |= value >>(bits - bitsRemainning);
      value = value & mask(bits-bitsRemainning);
      bits -= bitsRemainning;
      pBitBuffer->wBitPosition += bitsRemainning;
      printf("L%d,value:%d, bits:%d, buffer[%d, 0x%x] \n",__LINE__, value, bits, pBitBuffer->wBytePosition, pBitBuffer->buffer[pBitBuffer->wBytePosition]);
    }
    if (pBitBuffer->wBitPosition == 8) {
      pBitBuffer->wBitPosition = 0;
      bitsRemainning = 8;
      pBitBuffer->wBytePosition++;
    }
  }
  printf("L%d,wBitPos:%d, wBytePos:%d \n",__LINE__, pBitBuffer->wBitPosition, pBitBuffer->wBytePosition);
  return 0;
}

//左移或右移bits位

int bitBuffer_shiftBits(tBitBuffer *pBitBuffer, int bits) {
  int absBits = bits > 0 ? bits : -bits;
  int shiftBytes = absBits / 8;
  int shiftBits = absBits % 8;
  int flag = bits > 0 ? 1 : 0;
  if ( flag ) {
    if (pBitBuffer->bitPosition + shiftBits > 8) {
      pBitBuffer->bytePosition += shiftBytes + 1;
      pBitBuffer->bitPosition += shiftBits -8;
    }
    else {
      pBitBuffer->bytePosition += shiftBytes ;
      pBitBuffer->bitPosition += shiftBits;
    }
  }
  else {
    if (pBitBuffer->bitPosition - shiftBits < 0) {
      pBitBuffer->bytePosition -= shiftBytes -1;
      pBitBuffer->bitPosition -= shiftBits -8;
    }
    else {
      pBitBuffer->bytePosition = shiftBytes ;
      pBitBuffer->bitPosition -= shiftBits ;

    }

  }
  if (pBitBuffer->bytePosition < 0 || pBitBuffer->bytePosition > 1024) {
    pBitBuffer->bytePosition = 0;
    pBitBuffer->bitPosition = 0;
    return -1;
  }
  else{
    return 0;
  }

}

//读取了多少位

int bitBuffer_getReadBits(tBitBuffer *pBitBuffer) {
  return 8 * pBitBuffer->bytePosition + pBitBuffer->bitPosition;
}

int bitBuffer_writeByte(tBitBuffer *pBitBuffer, unsigned char byte){
  pBitBuffer->buffer[pBitBuffer->wBytePosition ++] = byte;
  pBitBuffer->byteSize ++;
}

void main(void) {
  

  tBitBuffer *bitBuffer = (tBitBuffer*)malloc(sizeof(tBitBuffer));
  memset(bitBuffer, 0, sizeof(tBitBuffer));
  // bitBuffer_writeByte(bitBuffer, 0x56);
  // bitBuffer_writeByte(bitBuffer, 0xe2);
  bitBuffer_writeBits(bitBuffer, 11, 0x2b7);
  bitBuffer_writeBits(bitBuffer, 5, 0x2);

  unsigned long result = 0;

  bitBuffer_shiftBits(bitBuffer, 3);
  result = bitBuffer_readBits(bitBuffer, 6);
  int readBits = bitBuffer_getReadBits(bitBuffer);
  printf("result:0x%x, %d, bitPostion:%d, bytePosition:%d,byteSize:%d, wBytePosition:%d, readBits:%d\n", result,result, bitBuffer->bitPosition, bitBuffer->bytePosition, bitBuffer->byteSize, bitBuffer->wBytePosition,readBits );

  #if 0
  result = bitBuffer_readBits(&bitBuffer, 3);
  printf("result:0x%x, %d, bitPostion:%d, bytePosition:%d,byteSize:%d, wBytePosition:%d\n", result,result, bitBuffer.bitPosition, bitBuffer.bytePosition, bitBuffer.byteSize,   bitBuffer.wBytePosition);
  result = bitBuffer_readBits(&bitBuffer, 6);
  printf("result:0x%x, %d, bitPostion:%d, bytePosition:%d,byteSize:%d, wBytePosition:%d\n", result,result, bitBuffer.bitPosition, bitBuffer.bytePosition, bitBuffer.byteSize,   bitBuffer.wBytePosition);
  #endif
}

bit Buffer的更多相关文章

  1. Node.js:Buffer浅谈

    Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...

  2. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  3. 一点公益商城开发系统模式Ring Buffer+

    一个队列如果只生产不消费肯定不行的,那么如何及时消费Ring Buffer的数据呢?简单的方案就是当Ring Buffer"写满"的时候一次性将数据"消费"掉. ...

  4. CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总

    CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...

  5. golang bytes.Buffer Reset

    func t() { a := []'} buf := new(bytes.Buffer) buf.Write(a) b := buf.Bytes() fmt.Println(b) buf.Reset ...

  6. 使用Ring Buffer构建高性能的文件写入程序

    最近常收到SOD框架的朋友报告的SOD的SQL日志功能报错:文件句柄丢失.经过分析得知,这些朋友使用SOD框架开发了访问量比较大的系统,由于忘记关闭SQL日志功能所以出现了很高频率的日志写入操作,从而 ...

  7. directx12中vetex buffer、index buffer和constant buffer绑定piple line的时机

    类别 时机 函数 建Heap vetex buffer 在Draw函数中 ID3D12GraphicsCommandList::IASetVertexBuffer 否 index buffer 在Dr ...

  8. JAVA NIO Buffer

    所谓的输入,输出,就是把数据移除或移入缓冲区.   硬件不能直接访问用户控件(JVM). 基于存储的硬件设备操控的是固定大小的数据块儿,用户请求的是任意大小的或非对齐的数据块儿.   虚拟内存:使用虚 ...

  9. Circular Buffer

    From:http://bradforj287.blogspot.com/2010/11/efficient-circular-buffer-in-java.html import java.util ...

  10. Buffer类

    输入流中可以通过缓冲区来加大读取的效率,sun公司感觉可以加快执行效率,他就为我们提供了一个类来操作缓存区. Buffer来头的类:所有缓冲流都是以Buffer开头的: 学习缓冲流的作用: Buffe ...

随机推荐

  1. 回形数字矩阵(Java)

    将矩阵从里到外分为多层,每一层都是一个口字型数字序列,方向都是顺时针/逆时针,由此我们可以将问题分解为相同的子问题来解决 回形矩阵概述 ☃ 回形矩阵有n行n列 ☃ 数字按顺时针或者逆时针递增 **使用 ...

  2. Git学习笔记-上传一个新的项目到GitHub上

    前提: 已有Github账号,已在Github上建立了仓库,已在Github上配置了SSH,已上传过一些项目到Github上 目标: 目前有一个新的项目,需要上传到github上 我的做法记录: 1. ...

  3. JS图片轮换

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. Qt程序异常结束,The process was ended forcefully....

    我用的Qt版本是5.9.6,运行了好几次程序都妥妥当当的,然后就被安排上了...出现如下错误: 也是刚入手Qt不久,出现这样的错误我以为是代码的问题,然后撤销一些代码发现还是这样的错,索性就关闭Qt然 ...

  5. 解决报错Failed to start LSB: Bring up/down networking:MAC地址导致

    1.场景描述,我在电脑里装好的虚拟机,今天突然就网络无法打开,并出现如下报错: [root@ansible-control ~]# systemctl start networkJob for net ...

  6. SDF数据库

    一.SDF数据库初探 SDF是一个标准缩略数据库格式.这个数据库包含扩展名为.sdf的文件并且以结构化文件格式进行数据存储.这些SDF文件通常用于在不同数据库应用之间移动数据.它允许一个用户将一个软件 ...

  7. 【NOI2002】银河英雄传说

    [NOI2002]银河英雄传说 这道题暴力模拟会TLE,因为它是并查集的一个应用…… #include<bits/stdc++.h> using namespace std; ],q[], ...

  8. Codeforces Hello2020 A-E简要题解

    contest链接:https://codeforces.com/contest/1284 A. New Year and Naming 思路:签到,字符串存一下,取余拼接. #include< ...

  9. [C语言学习笔记四]变量与系统的交互

    使用 const 创建常量和使用 volatie 优化变量 C语言中使用 const 定义常量. 例如: const INT a = 10; 此处如果添加a = 20;,编辑器则会报错,因为此处 a ...

  10. web前端基础-css-尺寸边框

    尺寸和边框: 一.尺寸 行内元素是不能设置宽和高的,其高度是由元素里面的内容的高度撑起来的: 行内块元素可以设置宽和高,当行内块元素没有设置宽高的时候,行内块元素的宽高是其默认的宽高: 块级元素:可以 ...