SBC协议_蓝牙耳机sbc怎么改

SBC协议_蓝牙耳机sbc怎么改sbcenc.c*main(intargc,charargv[])首先设定option的默认值,然后根据用户命令设定option相关参数。对指定文件进行编码(执行encode函数)usage(void)打印相关option:OptionOption打印帮助信息hhelp打印帮助信息vverbose详细模式mmsbcmSBC编解码器ssubbands子带数量(4/8)bbitpoolBitpoolvalue

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

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

sbcenc.c

  1. main(int argc, char *argv[])

    首先设定 option 的默认值,然后根据用户命令设定 option 相关参数。

    对指定文件进行编码(执行encode函数)

  2. usage(void)

    打印相关option:

    Option Option 打印帮助信息
    h help 打印帮助信息
    v verbose 详细模式
    m msbc mSBC编解码器
    s subbands 子带数量(4/8)
    b bitpool Bitpool value
    j joint 联合立体声
    d dualchannel 双声道
    S snr 信噪比模式(default/loudness)
    B blocks block数量(4/8/12/16)
  3. encode(char *filename, int subbands, int bitpool, int joint, int dualchannel, int snr, int blocks, bool msbc)

    定义一个 au_header类型的变量au_hdr

    // formats.h
    struct au_header {
    	uint32_t magic;		/* '.snd' */
    	uint32_t hdr_size;	/* size of header (min 24) */
    	uint32_t data_size;	/* size of data */
    	uint32_t encoding;	/* see to AU_FMT_XXXX */
    	uint32_t sample_rate;	/* sample rate */
    	uint32_t channels;	/* number of channels (voices) */
    };
    

    定义一个sbc_t类型的变量sbc

    // 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;
    

    定义ssize_t类型的变量encodedlen,实际是ssize_t就是long类型。

    // _types.h
    typedef long __darwin_ssize_t; /* byte count or error */
    // _ssize_t.h
    typedef __darwin_ssize_t ssize_t;
    

    检测au_hdr的长度是否是24。

    if (sizeof(au_hdr) != 24) { 
         
    		/* Sanity check just in case */
    		fprintf(stderr, "FIXME: sizeof(au_hdr) != 24\n");
    		return;
    }
    

    确定指定文件合法性并打开文件。

    if (strcmp(filename, "-")) { 
         
    		fd = open(filename, O_RDONLY);
    		if (fd < 0) { 
         
    			fprintf(stderr, "Can't open file %s: %s\n",
    						filename, strerror(errno));
    			return;
    		}
    } else
    		fd = fileno(stdin);
    

    将文件中头部数据读入au_hdr,并确定是否读取成功。

    len = read(fd, &au_hdr, sizeof(au_hdr));
    if (len < (ssize_t) sizeof(au_hdr)) { 
         
    	if (fd > fileno(stderr))
    		fprintf(stderr, "Can't read header from file %s: %s\n",
    				filename, strerror(errno));
    	else
    		perror("Can't read audio header");
    	goto done;
    }
    

    确定文件的格式是否符合Sun/NeXT audio S16_BE格式。

    if (au_hdr.magic != AU_MAGIC ||
    			BE_INT(au_hdr.hdr_size) > 128 ||
    			BE_INT(au_hdr.hdr_size) < sizeof(au_hdr) ||
    			BE_INT(au_hdr.encoding) != AU_FMT_LIN16) { 
         
    		fprintf(stderr, "Not in Sun/NeXT audio S16_BE format\n");
    		goto done;
    }
    

    判断使用sbc编码还是msbc编码。

    sbc

    1. 初始化sbc
    // sbc.c
    // sbc_init()
    SBC_EXPORT int sbc_init(sbc_t *sbc, unsigned long flags)
    { 
          
    	if (!sbc)
    		return -EIO;
    
    	memset(sbc, 0, sizeof(sbc_t));
    
    	sbc->priv_alloc_base = malloc(sizeof(struct sbc_priv) + SBC_ALIGN_MASK);
    	if (!sbc->priv_alloc_base)
    		return -ENOMEM;
    
    	sbc->priv = (void *) (((uintptr_t) sbc->priv_alloc_base +
    			SBC_ALIGN_MASK) & ~((uintptr_t) SBC_ALIGN_MASK));
    
    	memset(sbc->priv, 0, sizeof(struct sbc_priv));
    
    	sbc_set_defaults(sbc, flags);
    
    	return 0;
    }
    
    // sbc_set_defaults()
    static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
    { 
          
    	struct sbc_priv *priv = sbc->priv;
    
    	if (priv->msbc) { 
          
    		priv->pack_frame = msbc_pack_frame;
    		priv->unpack_frame = msbc_unpack_frame;
    	} else { 
          
    		priv->pack_frame = sbc_pack_frame;
    		priv->unpack_frame = sbc_unpack_frame;
    	}
    
    	sbc->flags = flags;
    	sbc->frequency = SBC_FREQ_44100;
    	sbc->mode = SBC_MODE_STEREO;
    	sbc->subbands = SBC_SB_8;
    	sbc->blocks = SBC_BLK_16;
    	sbc->bitpool = 32;
    #if __BYTE_ORDER == __LITTLE_ENDIAN
    	sbc->endian = SBC_LE;
    #elif __BYTE_ORDER == __BIG_ENDIAN
    	sbc->endian = SBC_BE;
    #else
    #error "Unknown byte order"
    #endif
    }
    
    1. 设置采样率、子带数量等参数。
    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;
    		}
    
    		srate = BE_INT(au_hdr.sample_rate);
    
    		sbc.subbands = subbands == 4 ? SBC_SB_4 : SBC_SB_8;
    
    		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;
    		}
    
    		sbc.endian = SBC_BE;
    		sbc.bitpool = bitpool;
    		sbc.allocation = snr ? SBC_AM_SNR : SBC_AM_LOUDNESS;
    		sbc.blocks = blocks == 4 ? SBC_BLK_4 :
    				blocks == 8 ? SBC_BLK_8 :
    					blocks == 12 ? SBC_BLK_12 : SBC_BLK_16;
    

    mSBC

    1. 初始化sbc
    // sbc.c
    SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags)
    { 
          
    	struct sbc_priv *priv;
    
    	if (!sbc)
    		return -EIO;
    
    	memset(sbc, 0, sizeof(sbc_t));
    
    	sbc->priv_alloc_base = malloc(sizeof(struct sbc_priv) + SBC_ALIGN_MASK);
    	if (!sbc->priv_alloc_base)
    		return -ENOMEM;
    
    	sbc->priv = (void *) (((uintptr_t) sbc->priv_alloc_base +
    			SBC_ALIGN_MASK) & ~((uintptr_t) SBC_ALIGN_MASK));
    
    	memset(sbc->priv, 0, sizeof(struct sbc_priv));
    
    	priv = sbc->priv;
    	priv->msbc = true;
    
    	sbc_set_defaults(sbc, flags);
    
    	sbc->frequency = SBC_FREQ_16000;
    	sbc->blocks = MSBC_BLOCKS;
    	sbc->subbands = SBC_SB_8;
    	sbc->mode = SBC_MODE_MONO;
    	sbc->allocation = SBC_AM_LOUDNESS;
    	sbc->bitpool = 26;
    
    	return 0;
    }
    

    读入文件数据,并显示详细信息

    /* Skip extra bytes of the header if any */
    if (read(fd, input, BE_INT(au_hdr.hdr_size) - len) < 0)
    	goto done;
    
    if (verbose) { 
         
    	fprintf(stderr, "encoding %s with rate %d, %d blocks, "
    		"%d subbands, %d bits, allocation method %s, "
    						"and mode %s\n",
    		filename, srate, blocks, subbands, bitpool,
    		sbc.allocation == SBC_AM_SNR ? "SNR" : "LOUDNESS",
    		sbc.mode == SBC_MODE_MONO ? "MONO" :
    				sbc.mode == SBC_MODE_STEREO ?
    					"STEREO" : "JOINTSTEREO");
    }
    

    获取编码长度codesize及帧数nframes

    codesize = sbc_get_codesize(&sbc);
    nframes = sizeof(input) / 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;
    		else
    			blocks = 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;
    }
    

    编码。

    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.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)
    { 
          
    	struct sbc_priv *priv;
    	int samples;
    	ssize_t framelen;
    	int (*sbc_enc_process_input)(int position,
    			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
    			int nsamples, int nchannels);
    
    	if (!sbc || !input)
    		return -EIO;
    
    	priv = sbc->priv;
    
    	if (written)
    		*written = 0;
    
    	if (!priv->init) { 
          
    		priv->frame.frequency = sbc->frequency;
    		priv->frame.mode = sbc->mode;
    		priv->frame.channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
    		priv->frame.allocation = sbc->allocation;
    		priv->frame.subband_mode = sbc->subbands;
    		priv->frame.subbands = sbc->subbands ? 8 : 4;
    		priv->frame.block_mode = sbc->blocks;
    		if (priv->msbc)
    			priv->frame.blocks = MSBC_BLOCKS;
    		else
    			priv->frame.blocks = 4 + (sbc->blocks * 4);
    		priv->frame.bitpool = sbc->bitpool;
    		priv->frame.codesize = sbc_get_codesize(sbc);
    		priv->frame.length = sbc_get_frame_length(sbc);
    
    		sbc_encoder_init(priv->msbc, &priv->enc_state, &priv->frame);
    		priv->init = true;
    	} else if (priv->frame.bitpool != sbc->bitpool) { 
          
    		priv->frame.length = sbc_get_frame_length(sbc);
    		priv->frame.bitpool = sbc->bitpool;
    	}
    
    	/* input must be large enough to encode a complete frame */
    	if (input_len < priv->frame.codesize)
    		return 0;
    
    	/* output must be large enough to receive the encoded frame */
    	if (!output || output_len < priv->frame.length)
    		return -ENOSPC;
    
    	/* Select the needed input data processing function and call it */
    	if (priv->frame.subbands == 8) { 
          
    		if (sbc->endian == SBC_BE)
    			sbc_enc_process_input =
    				priv->enc_state.sbc_enc_process_input_8s_be;
    		else
    			sbc_enc_process_input =
    				priv->enc_state.sbc_enc_process_input_8s_le;
    	} else { 
          
    		if (sbc->endian == SBC_BE)
    			sbc_enc_process_input =
    				priv->enc_state.sbc_enc_process_input_4s_be;
    		else
    			sbc_enc_process_input =
    				priv->enc_state.sbc_enc_process_input_4s_le;
    	}
    
    	priv->enc_state.position = sbc_enc_process_input(
    		priv->enc_state.position, (const uint8_t *) input,
    		priv->enc_state.X, priv->frame.subbands * priv->frame.blocks,
    		priv->frame.channels);
    
    	samples = sbc_analyze_audio(&priv->enc_state, &priv->frame);
    
    	if (priv->frame.mode == JOINT_STEREO) { 
          
    		int j = priv->enc_state.sbc_calc_scalefactors_j(
    			priv->frame.sb_sample_f, priv->frame.scale_factor,
    			priv->frame.blocks, priv->frame.subbands);
    		framelen = priv->pack_frame(output,
    				&priv->frame, output_len, j);
    	} else { 
          
    		priv->enc_state.sbc_calc_scalefactors(
    			priv->frame.sb_sample_f, priv->frame.scale_factor,
    			priv->frame.blocks, priv->frame.channels,
    			priv->frame.subbands);
    		framelen = priv->pack_frame(output,
    				&priv->frame, output_len, 0);
    	}
    
    	if (written)
    		*written = framelen;
    
    	return samples * priv->frame.channels * 2;
    }
    
    SBC_EXPORT void sbc_finish(sbc_t *sbc)
    { 
          
    	if (!sbc)
    		return;
    
    	free(sbc->priv_alloc_base);
    
    	memset(sbc, 0, sizeof(sbc_t));
    }
    

    关闭文件。

    done:
    	if (fd > fileno(stderr))
    		close(fd);
    }
    
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • 记一次固态硬盘数据恢复

    记一次固态硬盘数据恢复背景15年初的时候买过一个128G的固态硬盘,在自己的笔记本电脑上组了一个双硬盘(ssd+hdd),ssd作为系统盘。到今年也已经用了三年了。昨天上午的时候,电脑突然蓝屏报错,本来以为是一次简单的蓝屏故障,但是发现电脑重启之后,电脑报错找不到硬盘。当时心里一凉,难道硬盘寿终就寝了,但是硬盘坏了不重要,里面的数据还没有备份会比较可怕。赶快用一个winpe系统把电脑开起来,想看看数据是否还在。然…

    2022年9月20日
    1
  • es6set和map区别_list和map的区别面试

    es6set和map区别_list和map的区别面试转自https://blog.csdn.net/terence1212/article/details/52487656set是一种关联式容器,其特性如下:set以RBTree作为底层容器所得元素的只有key没有value,value就是key不允许出现键值重复所有的元素都会被自动排序不能通过迭代器来改变set的值,因为set的值就是键map和set一样是关联式容器,它们的底层容器都是红黑树,区别…

    2022年9月7日
    2
  • laravel 5.6接入微信第三方授权登陆的主要步骤

    laravel 5.6接入微信第三方授权登陆的主要步骤

    2021年10月25日
    43
  • Ubuntu下Redis密码设置问题及其解决方案[通俗易懂]

    Ubuntu下Redis密码设置问题及其解决方案[通俗易懂]Ubuntu下Redis密码设置问题及其解决方案一、Redis设置密码1.命令行设置密码。2.配置文件设置密码二、遇到问题&解决问题1.无法打开配置文件:2.配置文件密码修改成功点击保存但是却gedit警告:3.gedit配置文件修改密码成功但仍CONFIGGET为空4.注意修改配置文件完成后,一定要重启Redis服务器!叮嘟!最近做项目学习用到了Redis,在刚开始的摸索过程踩…

    2025年8月29日
    17
  • c程序中整形变量只能存放整数实型变量只能存放浮点数_c语言合法的实型常量

    c程序中整形变量只能存放整数实型变量只能存放浮点数_c语言合法的实型常量vb中,以下变量类型1,数字型变量(numeric)2,字符串型变量(string)3,日期型变量(date)4,对象型变量(object)5,变体型变量(variant)这几个vb变量类型中,最最主要的就是前面两个,数字型变量和字符串型变量.意思很简单,数字型可以用来存放数字,字符串型存放文本.下面就来详细介绍这几种变量.1.数字型数字型变量有多种类型,在咱们的vb里,有3中数字数据类型1;整形…

    2025年7月24日
    3
  • python hashlib模块安装_python hashlib 模块

    python hashlib模块安装_python hashlib 模块hashlib模块用于加密相关的操作,代替了md5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法。在python3中已经废弃了md5和sha模块什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。摘要算法就是通过摘要函数f()对任意长度的数据data计算出…

    2022年4月30日
    145

发表回复

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

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