【蓝牙sbc协议】sbc源码阅读笔记(三)——数据读写过程
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源码阅读笔记(三)——数据读写过程相关推荐
- Picasso源码阅读笔记三
Dispatcher负责分发任务,比如提交请求.取消请求.暂停请求.恢复请求等等. DispatcherThread和DispatcherHandler Dispatcher通过DispatcherT ...
- Okio源码阅读笔记(三)ByteString
其实ByteString没什么好看的.看之前以为有重要内容,看完后发现没有,不过既然已经看了,就记录下来吧. ByteString封装了以下几点 1.就是把一些输入类型(字符串/字节数组/ByteBu ...
- [Linux] USB-Storage驱动 源码阅读笔记(一)
USB-Storage驱动 源码阅读笔记--从USB子系统开始 最近在研究U盘的驱动,遇到很多难以理解的问题,虽然之前也参考过一些很不错的书籍如:<USB那些事>,但最终还是觉得下载一份最 ...
- Transformers包tokenizer.encode()方法源码阅读笔记
Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode
- 源码阅读笔记 BiLSTM+CRF做NER任务 流程图
源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...
- 代码分析:NASM源码阅读笔记
NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http:// ...
- Yii源码阅读笔记 - 日志组件
2015-03-09 一 By youngsterxyf 使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category); Yii: ...
- AQS源码阅读笔记(一)
AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node {//表示当前节点以共享模式等待锁static final Node SHA ...
- 【Flink】Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型
1.概述 转载:Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型 相似文章:[Flink]Flink 基于 MailBox 实现的 StreamTask 线程模型 Fl ...
最新文章
- php三年经验 多少工资_二级建造师一个月可以赚多少钱?
- tomcat端口冲突解决 Address already in use: JVM_Bind :8080
- Jstorm+Spring+mybatis整合
- 科研汪的日常--“键皇”,静电容的又一座高峰(REALFORCE RFU联名版开箱)
- 第六天 购车程序
- dubbo常见的一些面试题
- 如何用SQL为每一行均产生一个随机数
- 机械--NX2007(UG)有限元分析教程2--装配体
- c语言程序的执行起点是,c语言试题及答案
- 从0开始的视频特效制作之路
- cavas的验证码效果demo
- 关于粮食浪费问题的调查报告
- 自然语言处理(NLP):命名实体识别-NER
- C#模拟鼠标和键盘操作
- ZT一篇从普华永道离开的人的文章:闲话我在普华永道的岁月
- 用html画动漫人物,画动漫人物的步骤?
- matlab满秩分解函数,matlab满秩分解
- 华为路由器OSPF多区域配置
- 网线连接网络有黄色感叹号
- Robocup 2D新手导读(入门总结)