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);
    }
    
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 硬盘数据恢复的方法_固态硬盘覆盖数据恢复吗

    硬盘数据恢复的方法_固态硬盘覆盖数据恢复吗想必许多朋友在硬盘数据遭到损坏时,第一反应就是拿到外面的电脑店去找专业的人士帮忙修复,这虽然也是一个可行的方法,但同时小编也觉得大可不必浪费这些时间专门跑到外面,且有可能要付出高昂的修复费用。那么,当硬盘损坏时,我们应如何第一时间恢复数据呢?答案就是用专业的数据恢复软件扫描恢复。所以在这里教大家如何用数据恢复软件来找回硬盘数据,不限制时间和地点,随时随地就能修复。操作也很简单,让我们来看看详细的步骤。1.在超级兔子官网下载软件后打开至主界面,在场景模式下选择U盘/内存卡恢复。2.点.

  • Android程序员的进阶之路

    Android程序员的进阶之路本文主要论述的是android程序员的进阶之路,博主本人就是一名android开发攻城狮,所以这里讲述的大多数是android开发攻城狮的技术进阶之路,如有问题请多指正。大家都知道程序员之中有有菜鸟程序员和大神之分,这里我这暂时把android程序员分为几个层次:android初级程序员、android中级程序员、android高级程序员、android技术专家、CTO等等,不同的级别掌握的能力不

  • 密码加密方式

    密码加密方式密码加密方式

  • 以管理员身份修改hosts文件_如何修改hosts文件权限

    以管理员身份修改hosts文件_如何修改hosts文件权限第一步先在目录C:\Windows\System32\drivers\etc下找到host文件。右键点开属性,取消勾选只读。进入“安全”点击编辑选择允许修改。以管理员身份运行powershell,输入指令cddrivers\etc跳转到该目录下,再输入指令notepadhosts回车弹出host文件窗…

    2022年10月12日
  • 学java用什么编译器_学习Java用什么编译软件好

    学java用什么编译器_学习Java用什么编译软件好在线的java编译器和在线运行帮助我们轻松编译代码直接在浏览器上显示。java编译器网络版成为有用的在许多情况下。例如,假设你正在编写一个java代码,但不在自己的计算机上,减少时间的浪费,可以无需下载和安装任何软件,使用免费的在线工具运行代码。也就很有帮助,如果不需要编写java代码而定期一周甚至一天几次。增加电脑的速度,减少从您的计算机未使用的软件数量。但如果不想错过它,可以尝试免费的在线编译…

  • Python如何将字符串分割成单个字符,并形成一个list?

    Python如何将字符串分割成单个字符,并形成一个list?一个字符串可以看做是一个list具体操作如下&gt;&gt;&gt;a="这是一段话"&gt;&gt;&gt;a[0]’这’&gt;&gt;&gt;list(a)[‘这’,’是’,’一’,’段’,’话’]&gt;&gt;&gt;forxina: print(x) 这是一段话&gt;&gt;&gt;所以

发表回复

您的电子邮箱地址不会被公开。

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