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)


相关推荐

  • nginx负载均衡原理简介_负载均衡算法有哪些

    nginx负载均衡原理简介_负载均衡算法有哪些前言今天这篇文章介绍了负载均衡的原理以及对应的四种负载均衡算法,当然还有对应的指令及实战,欢迎品尝。有不同意见的朋友可以评论区留言!负载均衡所谓负载均衡,就是Nginx把请求均匀的分摊给上游的应用服务器,这样即使某一个服务器宕机也不会影响请求的处理,或者当应用服务器扛不住了,可以随时进行扩容。Nginx在AKF可扩展立方体上的应用在x轴上,可以通过横向扩展应用服务器集群,Nginx基于Round-Robin或者Least-Connected算法..

  • 常用shell命令_使用shell命令

    常用shell命令_使用shell命令1、目录信息查看命令ls  Shell下文件浏览命令为ls,格式如下:ls[选项][路径]  ls命令主要用于显示指定目录下的内容,列出指定目录下包含的所有的文件以及子目录,它的主要参数有:  -a显示所有的文件以及子目录,包括以“.”开头的隐藏文件。  -l显示文件的详细信息,比如文件的形态、权限、所有者、大小等信息。  -t将文件按照创建时间排序列出。  -A和-a一样,但是不列出“.”(当前目录)和“…”(父目录)。  -R递归列出所有文件,包括子目录中的

  • 查看win11激活状态[通俗易懂]

    查看win11激活状态[通俗易懂](一)命令行查看:slmgr.vbs-dlv如上图所示,windows11已激活。(二)右键计算机属性查看(1)单击系统:(2)单击激活:可以看到已经处于激活状态。

  • LINUX 操作命令题目_linux基本命令的使用

    LINUX 操作命令题目_linux基本命令的使用Linux 操作命令 head

  • 数论基础——群环域

    数论基础——群环域文章目录一、群环域基本概念1.群2.环常见环3.域与椭圆曲线椭圆FpF_pFp​PointadditionAlgebraicsum椭圆曲线群的阶数ScalarmultiplicationandcyclicsubgroupsSubgrouporder子群的阶FindingabasepointDomainparametersECC(EllipticCurveCryptography)EncryptionwithECDHSigningwithECDSA一、群环域基本概念1.群

  • Gamma校正原理及python实现

    Gamma校正原理及python实现Gamma校正原理:  假设图像中有一个像素,值是200,那么对这个像素进行校正必须执行如下步骤:  1.归一化:将像素值转换为0~1之间的实数。算法如下:(i+0.5)/256这里包含1个除法和1个加法操作。对于像素A而言,其对应的归一化值为0.783203。  2.预补偿:根据公式,求出像素归一化后的数…

发表回复

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

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