sbc_编码过程详解


编码部分源码

// sbcenc.c
static void encode(char *filename, int subbands, int bitpool, int joint,int dualchannel, int snr, int blocks, bool msbc)
{struct au_header au_hdr;sbc_t sbc;int fd, size, srate, codesize, nframes;ssize_t encoded;ssize_t len;// 数据初始化···// codesize = subbands * blocks *channels * 2codesize = sbc_get_codesize(&sbc);// read(fd, input, BE_INT(au_hdr.hdr_size) - len)nframes = sizeof(input) / codesize;while (1) {unsigned char *inp, *outp;/* read data for up to 'nframes' frames of input data */size = read(fd, input, codesize * nframes);if (size < 0) {/* Something really bad happened */perror("Can't read audio data");break;}if (size < codesize) {/* Not enough data for encoding even a single frame */break;}/* encode all the data from the input buffer in a loop */inp = input;outp = output;while (size >= codesize) {len = sbc_encode(&sbc, inp, codesize,outp, sizeof(output) - (outp - output),&encoded);if (len != codesize || encoded <= 0) {fprintf(stderr,"sbc_encode fail, len=%zd, encoded=%lu\n",len, (unsigned long) encoded);break;}size -= len;inp += len;outp += encoded;}len = write(fileno(stdout), output, outp - output);if (len != outp - output) {perror("Can't write SBC output");break;}if (size != 0) {/** sbc_encode failure has been detected earlier or end* of file reached (have trailing partial data which is* insufficient to encode SBC frame)*/break;}}sbc_finish(&sbc);···
}

其中codesize为编码的长度,通过sbc_get_codesize求出,具体过程为:

// sbc.c
SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
{uint16_t subbands, channels, blocks;struct sbc_priv *priv;priv = sbc->priv;if (!priv->init) {subbands = sbc->subbands ? 8 : 4;if (priv->msbc)blocks = MSBC_BLOCKS;elseblocks = 4 + (sbc->blocks * 4);channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;} else {subbands = priv->frame.subbands;blocks = priv->frame.blocks;channels = priv->frame.channels;}return subbands * blocks * channels * 2;
}

然后求出数据帧数nframes,其中input为跳过头部的额外字节:

nframes = sizeof(input) / codesize;// input
#define BUF_SIZE 32768
static unsigned char input[BUF_SIZE];
/* Skip extra bytes of the header if any */
// #define BE_INT(v)        bswap_32(v)
// hdr.size: size of header (min 24)
// len = read(fd, &au_hdr, sizeof(au_hdr));
read(fd, input, BE_INT(au_hdr.hdr_size) - len);

接下来开始进入读取数据部分,读取全部nframe帧的数据:

/* read data for up to 'nframes' frames of input data */
size = read(fd, input, codesize * nframes);

然后在循环中对输入缓冲区内的所有数据进行编码,从下面代码可以看出,对输入的数据进行逐帧编码,将编码后的数据写入output

/* encode all the data from the input buffer in a loop */
inp = input;
outp = output;
while (size >= codesize) {len = sbc_encode(&sbc, inp, codesize,outp, sizeof(output) - (outp - output),&encoded);if (len != codesize || encoded <= 0) {fprintf(stderr,"sbc_encode fail, len=%zd, encoded=%lu\n",len, (unsigned long) encoded);break;}size -= len;inp += len;outp += encoded;
}
len = write(fileno(stdout), output, outp - output);
if (len != outp - output) {perror("Can't write SBC output");break;
}
if (size != 0) {/** sbc_encode failure has been detected earlier or end* of file reached (have trailing partial data which is* insufficient to encode SBC frame)*/break;
}

以上就是编码及写入的整体过程,接下来研究具体的编码过程,也就是sbc_encode()函数。该函数声明如下:

// sbc.c
SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len, void *output, size_t output_len, ssize_t *written)

待补充内容:

  • sbc_encode详解

【蓝牙sbc协议】sbc源码阅读笔记(三)——数据读写过程相关推荐

  1. Picasso源码阅读笔记三

    Dispatcher负责分发任务,比如提交请求.取消请求.暂停请求.恢复请求等等. DispatcherThread和DispatcherHandler Dispatcher通过DispatcherT ...

  2. Okio源码阅读笔记(三)ByteString

    其实ByteString没什么好看的.看之前以为有重要内容,看完后发现没有,不过既然已经看了,就记录下来吧. ByteString封装了以下几点 1.就是把一些输入类型(字符串/字节数组/ByteBu ...

  3. [Linux] USB-Storage驱动 源码阅读笔记(一)

    USB-Storage驱动 源码阅读笔记--从USB子系统开始 最近在研究U盘的驱动,遇到很多难以理解的问题,虽然之前也参考过一些很不错的书籍如:<USB那些事>,但最终还是觉得下载一份最 ...

  4. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  5. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

  6. 代码分析:NASM源码阅读笔记

    NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...

  7. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http:// ...

  8. Yii源码阅读笔记 - 日志组件

    2015-03-09 一 By youngsterxyf 使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category); Yii: ...

  9. AQS源码阅读笔记(一)

    AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node {//表示当前节点以共享模式等待锁static final Node SHA ...

  10. 【Flink】Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型

    1.概述 转载:Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型 相似文章:[Flink]Flink 基于 MailBox 实现的 StreamTask 线程模型 Fl ...

最新文章

  1. php三年经验 多少工资_二级建造师一个月可以赚多少钱?
  2. tomcat端口冲突解决 Address already in use: JVM_Bind :8080
  3. Jstorm+Spring+mybatis整合
  4. 科研汪的日常--“键皇”,静电容的又一座高峰(REALFORCE RFU联名版开箱)
  5. 第六天 购车程序
  6. dubbo常见的一些面试题
  7. 如何用SQL为每一行均产生一个随机数
  8. 机械--NX2007(UG)有限元分析教程2--装配体
  9. c语言程序的执行起点是,c语言试题及答案
  10. 从0开始的视频特效制作之路
  11. cavas的验证码效果demo
  12. 关于粮食浪费问题的调查报告
  13. 自然语言处理(NLP):命名实体识别-NER
  14. C#模拟鼠标和键盘操作
  15. ZT一篇从普华永道离开的人的文章:闲话我在普华永道的岁月
  16. 用html画动漫人物,画动漫人物的步骤?
  17. matlab满秩分解函数,matlab满秩分解
  18. 华为路由器OSPF多区域配置
  19. 网线连接网络有黄色感叹号
  20. Robocup 2D新手导读(入门总结)

热门文章

  1. python全排列,递归
  2. 04 数据控制语言DCL
  3. linux 字符串数组初始化,Linux命令行 – 数组
  4. Fanuc发那科法兰克数据采集实战c#——CNC数控系统数据采集、西门子免授权数据采集方案
  5. 聊一聊KOA的洋葱模型
  6. 【习题】《算法零基础100讲》位与 2
  7. macOS终端颜色的设定方法与说明:CLICOLOR与LSCOLORS
  8. 对话周鸿袆:从程序员创业谈起
  9. 使用Webdriver进行自动化测试--ljw
  10. sql根据指定符号拆分字符串表函数