你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STF103VE CUBE IAR opus codec 移植

[复制链接]
迷雾向前 发布时间:2017-1-18 16:21
本帖最后由 迷雾向前 于 2017-1-20 11:22 编辑

计划在机器上STF103VE  跑opus codec 进行编解码,中途停了,写一下做个记录。


首先用CUBE 快速生成代码。
Clock 配置如下,我用的是内部时钟(应该没连接外部晶振):

clock 配置

clock 配置


Enable FreeRTOS ,heap 配置为 20K,enc 结构需要13k Ram。

FreeRTOS config

FreeRTOS config

用于编解码的Task 的Stack 改为1024Word,即4K(小了会reset)

Task Stack

Task Stack


系统heap 需要改大,

System Heap

System Heap


将OPUS 代码copy 到工程里面,将如下文件加入到编译(没权限添加更多图片,只能用文字描述了)

opus-1.1.3/silk/ana_filt_bank_1.c
opus-1.1.3/silk/bwexpander.c
opus-1.1.3/silk/control_audio_bandwidth.c
opus-1.1.3/silk/code_signs.c
opus-1.1.3/silk/CNG.c
opus-1.1.3/silk/fixed/schur64_FIX.c
opus-1.1.3/silk/control_codec.c
opus-1.1.3/silk/debug.c
opus-1.1.3/silk/control_SNR.c
opus-1.1.3/silk/fixed/residual_energy16_FIX.c
opus-1.1.3/silk/fixed/residual_energy_FIX.c
opus-1.1.3/silk/fixed/warped_autocorrelation_FIX.c
opus-1.1.3/silk/biquad_alt.c
opus-1.1.3/silk/bwexpander_32.c
opus-1.1.3/silk/check_control_input.c
opus-1.1.3/silk/A2NLSF.c
opus-1.1.3/silk/fixed/schur_FIX.c
opus-1.1.3/silk/fixed/solve_LS_FIX.c
opus-1.1.3/silk/fixed/vector_ops_FIX.c
opus-1.1.3/silk/encode_pulses.c
opus-1.1.3/silk/log2lin.c
opus-1.1.3/silk/enc_API.c
opus-1.1.3/silk/HP_variable_cutoff.c
opus-1.1.3/silk/init_decoder.c
opus-1.1.3/silk/init_encoder.c
opus-1.1.3/silk/decode_indices.c
opus-1.1.3/silk/inner_prod_aligned.c
opus-1.1.3/silk/decode_frame.c
opus-1.1.3/silk/decode_pulses.c
opus-1.1.3/silk/gain_quant.c
opus-1.1.3/silk/interpolate.c
opus-1.1.3/silk/lin2log.c
opus-1.1.3/silk/decode_parameters.c
opus-1.1.3/silk/dec_API.c
opus-1.1.3/silk/decode_core.c
opus-1.1.3/silk/decode_pitch.c
opus-1.1.3/silk/decoder_set_fs.c
opus-1.1.3/silk/encode_indices.c
opus-1.1.3/silk/quant_LTP_gains.c
opus-1.1.3/silk/NSQ.c
opus-1.1.3/silk/resampler.c
opus-1.1.3/silk/NLSF_del_dec_quant.c
opus-1.1.3/silk/NLSF2A.c
opus-1.1.3/silk/NLSF_stabilize.c
opus-1.1.3/silk/NLSF_unpack.c
opus-1.1.3/silk/NLSF_VQ.c
opus-1.1.3/silk/LPC_inv_pred_gain.c
opus-1.1.3/silk/NLSF_VQ_weights_laroia.c
opus-1.1.3/silk/pitch_est_tables.c
opus-1.1.3/silk/NSQ_del_dec.c
opus-1.1.3/silk/PLC.c
opus-1.1.3/silk/NLSF_decode.c
opus-1.1.3/silk/NLSF_encode.c
opus-1.1.3/silk/LP_variable_cutoff.c
opus-1.1.3/silk/LPC_analysis_filter.c
opus-1.1.3/silk/process_NLSFs.c
opus-1.1.3/silk/stereo_find_predictor.c
opus-1.1.3/silk/stereo_MS_to_LR.c
opus-1.1.3/silk/resampler_private_AR2.c
opus-1.1.3/silk/resampler_down2_3.c
opus-1.1.3/silk/stereo_LR_to_MS.c
opus-1.1.3/silk/stereo_encode_pred.c
opus-1.1.3/silk/resampler_down2.c
opus-1.1.3/silk/sigm_Q15.c
opus-1.1.3/silk/resampler_rom.c
opus-1.1.3/silk/sort.c
opus-1.1.3/silk/resampler_private_down_FIR.c
opus-1.1.3/silk/resampler_private_up2_HQ.c
opus-1.1.3/silk/stereo_decode_pred.c
opus-1.1.3/silk/shell_coder.c
opus-1.1.3/silk/resampler_private_IIR_FIR.c
opus-1.1.3/src/repacketizer.c
opus-1.1.3/silk/sum_sqr_shift.c
opus-1.1.3/silk/table_LSF_cos.c
opus-1.1.3/silk/tables_NLSF_CB_WB.c
opus-1.1.3/silk/stereo_quant_pred.c
opus-1.1.3/silk/VAD.c
opus-1.1.3/silk/tables_gain.c
opus-1.1.3/silk/tables_pulses_per_block.c
#opus-1.1.3/stm32_m3/opus_main.c
opus-1.1.3/src/opus_encoder.c
opus-1.1.3/silk/tables_NLSF_CB_NB_MB.c
opus-1.1.3/silk/tables_other.c
opus-1.1.3/src/opus.c
opus-1.1.3/silk/tables_pitch_lag.c
opus-1.1.3/src/opus_decoder.c
opus-1.1.3/silk/VQ_WMat_EC.c
opus-1.1.3/silk/tables_LTP.c

opus-1.1.3/celt/entdec.c
opus-1.1.3/celt/entenc.c
opus-1.1.3/celt/cwrs.c
opus-1.1.3/celt/mathops.c
opus-1.1.3/celt/kiss_fft.c
opus-1.1.3/celt/celt_lpc.c
opus-1.1.3/celt/mdct.c
opus-1.1.3/celt/modes.c
opus-1.1.3/celt/bands.c
opus-1.1.3/celt/pitch.c
opus-1.1.3/celt/celt_encoder.c
opus-1.1.3/celt/laplace.c
opus-1.1.3/celt/celt_decoder.c
opus-1.1.3/celt/entcode.c
opus-1.1.3/celt/celt.c
opus-1.1.3/silk/fixed/noise_shape_analysis_FIX.c
opus-1.1.3/silk/fixed/process_gains_FIX.c
opus-1.1.3/silk/fixed/regularize_correlations_FIX.c
opus-1.1.3/silk/fixed/autocorr_FIX.c
opus-1.1.3/celt/quant_bands.c
opus-1.1.3/silk/fixed/encode_frame_FIX.c
opus-1.1.3/silk/fixed/corrMatrix_FIX.c
opus-1.1.3/silk/fixed/find_LTP_FIX.c
opus-1.1.3/silk/fixed/pitch_analysis_core_FIX.c
opus-1.1.3/silk/fixed/prefilter_FIX.c
opus-1.1.3/celt/rate.c
opus-1.1.3/silk/fixed/find_pitch_lags_FIX.c
opus-1.1.3/silk/fixed/burg_modified_FIX.c
opus-1.1.3/silk/fixed/LTP_analysis_filter_FIX.c
opus-1.1.3/celt/vq.c
opus-1.1.3/silk/fixed/find_LPC_FIX.c
opus-1.1.3/silk/fixed/find_pred_coefs_FIX.c
opus-1.1.3/silk/fixed/apply_sine_window_FIX.c
opus-1.1.3/silk/fixed/k2a_FIX.c
opus-1.1.3/silk/fixed/LTP_scale_ctrl_FIX.c
opus-1.1.3/silk/fixed/k2a_Q16_FIX.c


我为opus-1.1.3建立了单独的group,并将这个group 的 【Override inherited settings 】勾上

opus config

opus config

在【Proprocessor】里增加如下include 目录
$PROJ_DIR$/../opus-1.1.3/include
$PROJ_DIR$/../opus-1.1.3/celt
$PROJ_DIR$/../opus-1.1.3/silk
$PROJ_DIR$/../opus-1.1.3/silk/fixed
$PROJ_DIR$/../opus-1.1.3/stm32_m3

增加:HAVE_CONFIG_H 到【Defined symbols】
opus include.JPG
将【Language 1 】中的【Allow VLA】勾上,目的是#define VAR_ARRAYS   1 后能便宜通过。

copy opus-1.1.3/win32 到 opus-1.1.3/stm32_m3,建立config.h 和 version.h
config.h:
#ifndef CONFIG_H
#define CONFIG_H

//#define USE_ALLOCA            1
#define VAR_ARRAYS   1
/* Comment out the next line for floating-point code */
/*#define FIXED_POINT           1 */

#define OPUS_BUILD            1
#define DISABLE_FLOAT_API 1
#define FIXED_POINT 1
#define REMOVE_FOR_MALLOC

//以上部分内容为增加部分,其他的与win32下同名文件相同
#endif /* CONFIG_H */

version.h
#ifndef __VERSION_H__
#define __VERSION_H__

#define PACKAGE_VERSION  "1.1.3"
#endif /*__VERSION_H__*/

encode 和decode 代码:

pusDecoder *dec;
  static int offset = 0;
  int size = 0;
  const unsigned char *packet;
  int i = 0;
  int frame_size = 0;
  int max_size = 0;
  char buffer[36];

   
  uint32_t start = osKernelSysTick();
  
  OpusEncoder *enc = NULL;
  static int len = 10;

  
  size = opus_encoder_get_size(channels);
  enc = pvPortMalloc(size);
  error = opus_encoder_init(enc, Fs, channels, OPUS_APPLICATION_RESTRICTED_LOWDELAY);

  opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
  //opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
  opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
  
  len = opus_encode(enc, audio_frame + offset, Fs/50/*20ms*/, opus_buffer, sizeof(opus_buffer));
  offset += Fs/50;
  if(offset >= sizeof(audio_frame)/sizeof(uint16_t))
    offset = 0;
  vPortFree(enc);

  OpusDecoder *st  = (OpusDecoder *)pvPortMalloc(opus_decoder_get_size(channels));
  error = opus_decoder_init(st, Fs, channels);
  

  frame_size = opus_decode(st, opus_buffer, len, pcm, PCM_BUFFER_SIZE, 0);


对了,我改了这两个宏,
#define MAX_FS_KHZ                              8 /*16 --> 8 modify for memory*/
#define MAX_API_FS_KHZ                          8 /*48 --> 8 modify for memory/
原因是,如果不修改opus_encoder_get_size(1); 返回的是27k,改完后还得13k,实在是没有那么多ram
size = opus_encoder_get_size(1);
enc = pvPortMalloc(size);

总结,64k ram 感觉刚刚够,还没有增加其他的功能,解压缩20ms 数据用了6-7ms,编码我忘记了,记得编解码用了33ms,有点高。
声音可以用DAC(PA4)播放出来,需要外加功放,不加功放声音很不好。经过opus 压缩解压后声音损失较大,音乐还能听出来,但很多噪声。

评分

参与人数 1 ST金币 +10 收起 理由
zero99 + 10

查看全部评分

收藏 2 评论4 发布时间:2017-1-18 16:21

举报

4个回答
zero99 回答时间:2017-1-23 13:15:12
谢谢分享
新来的新手 回答时间:2017-5-9 17:34:41
楼主你好,我想问一下STM3VE 用opus编解码效果如何?
mupro 回答时间:2018-1-3 17:34:49
楼主的项目能放出来吗  感觉opus的代码很多,你上面介绍的是很多文件都不需要的
epochal 回答时间:2018-1-3 20:08:03
谢谢分享!

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版