【蓝牙sbc协议】sbc源码阅读笔记(二)——sbc_struct详解(上)[通俗易懂]

【蓝牙sbc协议】sbc源码阅读笔记(二)——sbc_struct详解(上)[通俗易懂]sbc_struct结构详解sbc_struct结构的定义://sbc.hstructsbc_struct{ unsignedlongflags; uint8_tfrequency; uint8_tblocks; uint8_tsubbands; uint8_tmode; uint8_tallocation; uint8_tbitpool; uint8_tendian; void*priv; void*priv_alloc_base;};typ

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

sbc_struct结构详解


sbc_struct结构的定义:
// sbc.h
struct sbc_struct { 
   
	unsigned long flags;

	uint8_t frequency;
	uint8_t blocks;
	uint8_t subbands;
	uint8_t mode;
	uint8_t allocation;
	uint8_t bitpool;
	uint8_t endian;

	void *priv;
	void *priv_alloc_base;
};
typedef struct sbc_struct sbc_t;
  1. flags

    unsigned long类型。在调用sbc_init(&sbc, 0L);sbc_init_msbc(&sbc, 0);的时候作为第二个参数传入,并在函数中,继续传递给sbc_set_defaults函数,在sbc_set_defaults中赋值给sbc->flags

    待补充:作用

    /* sbcenc.c */
    // !msbc
    sbc_init(&sbc, 0L);
    // msbc
    sbc_init_msbc(&sbc, 0);
    
    /* sbc.c */
    // sbc_init()与sbc_init_msbc()均调用此方法
    sbc_set_defaults(sbc, flags);	
    // sbc_set_defaults()
    static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
    { 
         
    	···
    	sbc->flags = flags;
    	···
    }
    
  2. frequency

    uint8_t类型,用来表示采样率,取值有16k,32k,44.1k,48k。

    /* sbc.h */
    /* sampling frequency */
    #define SBC_FREQ_16000 0x00
    #define SBC_FREQ_32000 0x01
    #define SBC_FREQ_44100 0x02
    #define SBC_FREQ_48000 0x03
    

    sbc_init()中默认值为44.1k,在sbc_init_msbc()中默认值为16k。

    /* sbc.c */
    // sbc
    static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
    { 
         
    	···
    	sbc->frequency = SBC_FREQ_44100;
    	···
    }
    // msbc
    ···
    sbc_set_defaults(sbc, flags);		// 先调用了sbc_set_defaults
    sbc->frequency = SBC_FREQ_16000;// 随后修改默认值为16k
    ···
    

    encode()中,sbc编码可以根据文件采样率对frequency赋值,msbc只能使用16k。

    /* sbcenc.c */
    // msbc必须为16k
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
    
    		switch (BE_INT(au_hdr.sample_rate)) { 
         
    		case 16000:
    			sbc.frequency = SBC_FREQ_16000;
    			break;
    		case 32000:
    			sbc.frequency = SBC_FREQ_32000;
    			break;
    		case 44100:
    			sbc.frequency = SBC_FREQ_44100;
    			break;
    		case 48000:
    			sbc.frequency = SBC_FREQ_48000;
    			break;
    		}
        ···
      } else { 
         
        if (BE_INT(au_hdr.sample_rate) != 16000 ||
    				BE_INT(au_hdr.channels) != 1 ||
    				BE_INT(au_hdr.channels) != 1) { 
         
    			fprintf(stderr, "mSBC requires 16 bits, 16kHz, mono "
    								"input\n");
    			goto done;
    		}
        ···
      }
      ···
    }
    
  3. blocks

    类型为uint8_t,sbc编码的取值有4,8,12,16,msbc为15。

    待补充:作用

    /* sbc.h */
    /* blocks */
    #define SBC_BLK_4 0x00
    #define SBC_BLK_8 0x01
    #define SBC_BLK_12 0x02
    #define SBC_BLK_16 0x03
    /* sbc.c */
    #define MSBC_BLOCKS 15
    

    sbc_set_defaults()中默认设置为16,msbc则修改为15。

    /* sbc.c */
    // sbc
    static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
    { 
         
    	···
    	sbc->blocks = SBC_BLK_16;
    	···
    }
    // msbc
    ···
    sbc_set_defaults(sbc, flags);		// 先调用了sbc_set_defaults
    sbc->blocks = MSBC_BLOCKS;			// 随后修改为15
    ···
    

    encode()中进行赋值。

    /* sbcenc.c */
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
        ···
        sbc.blocks = blocks == 4 ? SBC_BLK_4 :
    						blocks == 8 ? SBC_BLK_8 :
    							blocks == 12 ? SBC_BLK_12 : SBC_BLK_16;
      } else { 
         
        ···
        sbc_init_msbc(&sbc, 0);		// 设置为15
        ···
      }
      ···
    }
    
  4. subbands

    uint8_t类型,表示子带数量,取值范围为4,8。

    /* sbc.h */
    /* subbands */
    #define SBC_SB_4 0x00
    #define SBC_SB_8 0x01
    

    sbc_set_defaults()中默认设置为8。

    encode()中进行赋值。

    /* sbcenc.c */
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
        ···
        sbc.subbands = subbands == 4 ? SBC_SB_4 : SBC_SB_8;
        ···
      } else { 
         
        ···
        sbc_init_msbc(&sbc, 0);		// 默认8
        ···
      }
      ···
    }
    
  5. mode

    uint8_t类型,表示声道模式,支持单声道、双声道、立体声和联合立体声。

    /* sbc.h */
    /* channel mode */
    #define SBC_MODE_MONO 0x00
    #define SBC_MODE_DUAL_CHANNEL 0x01
    #define SBC_MODE_STEREO 0x02
    #define SBC_MODE_JOINT_STEREO 0x03
    

    sbc_set_defaults()中默认设置为立体声,msbc编码则默认是单声道。

    encode()中进行赋值。

    /* sbcenc.c */
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
        ···
        if (BE_INT(au_hdr.channels) == 1) { 
         
    			sbc.mode = SBC_MODE_MONO;	// 单声道
          // 音频为单声道但指定了联合或双声道模式
    			if (joint || dualchannel) { 
         
    				fprintf(stderr, "Audio is mono but joint or "
    					"dualchannel mode has been specified\n");
    				goto done;
    			}
    		} else if (joint && !dualchannel)
    			sbc.mode = SBC_MODE_JOINT_STEREO;	// 立体声
    		else if (!joint && dualchannel)
    			sbc.mode = SBC_MODE_DUAL_CHANNEL;	// 双声道
    		else if (!joint && !dualchannel)
    			sbc.mode = SBC_MODE_STEREO;				// 联合立体声
    		else { 
         
    			fprintf(stderr, "Both joint and dualchannel "
    						"mode have been specified\n");
    			goto done;
    		}
        ···
      } else { 
         
        ···
        sbc_init_msbc(&sbc, 0);		// msbc默认单声道
        ···
      }
      ···
    }
    
  6. allocation

    uint8_t类型,表示每个子频段幅值比特数的分配方法,有响度和信噪比。

    /* sbc.h */
    /* allocation method */
    #define SBC_AM_LOUDNESS 0x00
    #define SBC_AM_SNR 0x01
    

    默认为SBC_AM_LOUDNESS,在encode()中赋值。

    /* sbcenc.c */
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
        ···
        sbc.allocation = snr ? SBC_AM_SNR : SBC_AM_LOUDNESS;
        ···
      } else { 
         
        ···
        sbc_init_msbc(&sbc, 0);		// msbc默认SBC_AM_LOUDNESS
        ···
      }
      ···
    }
    
  7. bitpool

    uint8_t类型,表示幅值的比特数,默认为32,msbc默认为26。

    /* sbcenc.c */
    static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
    { 
         
      ···
      if (!msbc) { 
         
    		sbc_init(&sbc, 0L);
        ···
        sbc.bitpool = bitpool;		// sbc默认32
        ···
      } else { 
         
        ···
        sbc_init_msbc(&sbc, 0);		// msbc默认26
        ···
      }
      ···
    }
    
  8. endian

    uint8_t类型,用来表示主机字节序(大端、小端),默认为大端。

    /* sbc.h */
    /* data endianess */
    #define SBC_LE 0x00
    #define SBC_BE 0x01
    

    sbc_set_defaults()中判断并赋值。

    /* sbc.c */
    // sbc_set_defaults()
    static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
    { 
         
    	···
    #if __BYTE_ORDER == __LITTLE_ENDIAN
    	sbc->endian = SBC_LE;
    #elif __BYTE_ORDER == __BIG_ENDIAN
    	sbc->endian = SBC_BE;
    #else
    #error "Unknown byte order"
    #endif
    }
    

    待补充:sbc与msbc执行sbc_set_defaults()后,都又将endian赋值为SBC_BE


待补充内容:
  • flags 的作用
  • blocks 的作用
  • endian 判断赋值后,又重新赋值为 SBC_BE
  • *priv 与 *priv_alloc_base
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194983.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • turtle模块制作的弹球,面向对象,python海龟可不仅仅是画图「建议收藏」

    turtle模块制作的弹球,面向对象,python海龟可不仅仅是画图「建议收藏」fromturtleimport*fromrandomimportrandints=Screen()s.title("turtle模块制作的弹球_作者:李兴球")s.setup(800,600)s.delay(0)classBall(Turtle):  def__init__(self,x,y):    Turtle.__init__(self)…

    2022年9月2日
    2
  • MQTT服务器搭建和测试[通俗易懂]

    MQTT服务器搭建和测试[通俗易懂]目前MQTT代理的主流平台有下面几个:Mosquitto:https://mosquitto.org/ VerneMQ:https://vernemq.com/ EMQTT:http://emqtt.io/本文将使用Mosquitoo进行测试,进入到安装页面,下载自己电脑的系统所适配的程序注意:安装的目录最好不要带有空格测试第一步:启动brokerwindows下使用命令提示符,进入mosquitto安装目录输入命令:mosquitto-cmosquitto.con

    2022年6月3日
    44
  • 嵌入式实时操作系统UCOSII[通俗易懂]

    嵌入式实时操作系统UCOSII[通俗易懂]何谓操作系统1.什么是操作系统?操作系统是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。介于APP和硬件之间。2. 为什么要用操作系统?1)相比裸机,可以实现更加复杂的功能。2)屏蔽硬件。使得上层应用APP的移植性更好。常见操作系统常见操作系统安卓、IOS、Windows、Linux、塞班、V…

    2022年5月4日
    165
  • 数据预处理无量纲化处理_统计数据的预处理

    数据预处理无量纲化处理_统计数据的预处理1.无量纲化定义无量纲化,也称为数据的规范化,是指不同指标之间由于存在量纲不同致其不具可比性,故首先需将指标进行无量纲化,消除量纲影响后再进行接下来的分析。2.无量纲化方法无量纲化方法有很多,但

    2022年8月5日
    3
  • SQL中SELECT语句详解「建议收藏」

    SQL中SELECT语句详解「建议收藏」本篇文章讲述SQL语句中的SELECT查询语句,以供参考,如有错误或不当之处还望大神们告知。简单查询SELECT-FROM用于无条件查询单张表中的行或列假设有表如图所示查询名字叫‘叶清逸’的记录:select*fromT_USERwhereu_name=’叶清逸’;查询结果:查询一个或多个属性,u_name,u_age,u_scor…

    2022年4月29日
    54
  • C语言的整型溢出问题 int、long、long long取值范围 最大最小值「建议收藏」

    C语言的整型溢出问题 int、long、long long取值范围 最大最小值「建议收藏」溢出和取值范围C语言的整型溢出问题整数溢出int、longint、longlongint占用字节疑问《C和指针》中写过:long与int:标准只规定long不小于int的长度,int不小于short的长度。double与int类型的存储机制不同,longint的8个字节全部都是数据位,而double是以尾数,底数,指数的形式表示的,类似科学计数法,因此double比

    2022年6月3日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号