大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
sbcenc.c
-
main(int argc, char *argv[])
首先设定 option 的默认值,然后根据用户命令设定 option 相关参数。
对指定文件进行编码(执行encode函数)
-
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) -
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
类型的变量encoded
和len
,实际是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
- 初始化
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 }
- 设置采样率、子带数量等参数。
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
- 初始化
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账号...