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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • springboot的启动_springboot启动加载

    springboot的启动_springboot启动加载总括:@SpringBootApplication包含@Configuration所以启动类是一个xml注解除了有标志作用,还需有复杂类的切面作用可以用@import@Import(EnableAutoConfigurationImportSelector.class)将配置中的类ioc实例化到容器,然后创建上下文,将实例化的bean放入上下文正文说springboot的启动流程当然少不了springboot启动入口类@SpringBootApplicationpub..

    2022年8月20日
    4
  • 安装配置 | 用同济邮箱账户下载matlab

    安装配置 | 用同济邮箱账户下载matlabrefer:http://software.tongji.edu.cn/Home#9&1544step1/注册同济邮箱同济大学邮件系统登陆:https://mail.tongji.edu.cn/coremail/index.jspstep2/用同济邮箱注册mathwork账户并关联许可证出现提示时,以1830206@tongji.edu.cn登录…

    2022年7月25日
    12
  • webpack css_webpack打包css文件路径

    webpack css_webpack打包css文件路径css文件处理-准备工作(以下项目配置都是基于上一篇webpack(4)的基础上)在项目开发中,我们必然需要添加很多的样式,而样式我们往往写到一个单独的文件中。这里我们就在src目录中创建一个n

    2022年7月31日
    3
  • 联想笔记本电脑键盘灯怎么开启_联想笔记本电脑的键盘灯怎么开[通俗易懂]

    联想笔记本电脑键盘灯怎么开启_联想笔记本电脑的键盘灯怎么开[通俗易懂]展开全部1、联想笔记本部分型号具备键盘背32313133353236313431303231363533e4b893e5b19e31333431336664光功能,方法通过“FN+空格”打开,支持此功能的机型,键盘上有相应标示。部分早期的Thinkpad笔记本电脑若带有键盘灯,需要通过“Fn+PageUp”组合键开启。发现电脑键盘的“Space(空格键)”按键上有下图所示的标识符号电脑一般带有键…

    2022年9月20日
    0
  • 手把手教你接入支付宝支付

    手把手教你接入支付宝支付前一久做了支付宝支付,分享一下接入的详细步骤吧,移动端和服务端demo源码已上传至GitHub,要下载的移步至文章末尾。先给出支付宝官方文档:https://docs.open.alipay.com/204/105051/适用场景在App内集成支付宝支付。APP调用支付宝提供的SDK,SDK再调用支付宝APP内的支付模块。如果用户已安装支付宝APP,商家APP会跳转到支付宝中完成支付,支付完…

    2022年5月25日
    33
  • python sobel滤波_Sobel滤波器

    python sobel滤波_Sobel滤波器一.sobel滤波器介绍sobel滤波器常用来提取灰度图像的水平边缘(水平特征)和竖直边缘(竖直特征)二.sobel算子纵向算子,提取图像水平边缘↑横向算子,提取图像竖直边缘↑三.实验:python实现sobel算子并将算子作用于图像importcv2importnumpyasnp#GrayscaledefBGR2GRAY(img):b=img[:,:,0].cop…

    2025年7月28日
    0

发表回复

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

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