ESP32在两种开发环境下运行OPUS
opus是一款优秀的音频编解码算法,具有很高的压缩率,尝试在ESP32平台运行opus
ESP-IDF开发环境运行opus
ESP-IDF开发环境已经有大佬做好了移植,并且制作了makefile文件,做好了第三方的components,下载地址 点击我,我们只用将文件夹下载先来拖放到components文件夹根目录即可,如下图所示
下面我们来创建一个demo用来运行,新建一个hello world工程,在创建工程师选择导入esp-libopus这个库
后续的操作都一样,下面是我编写的demo函数,其中使用时间长度为20ms,采样率为8Khz,使用一个正弦波数组作为模拟压缩的对象,实际测试下在ESP32上压缩这么多数据大概需要1ms,可以说具有较好的实时性。
const int16_t testWavArray[160] = {
0, -517, -999, -1414, -1732, -1931, -2000, -1931, -1732, -1414, -1000, -517,0, 517, 999, 1414, 1732, 1931, 2000, 1931, 1732, 1414, 1000, 517,......
};
uint8_t outputData[100]={0};
int16_t decodeData[200]={0};
typedef struct testOpus
{
opus_int32 sampling_rate;//源数据采样频�???????
int channels;//通道�???????
opus_int32 bitrate_bps;//编码的码�???????
int error;
opus_int16 *srcData;//源数�???????
int srcSize; //源数据大�???????
unsigned char *dstData; //输出数据指针
int dstSize; //输出数据大小
opus_int16 *outData;//解码后的数据大小
opus_int32 max_payload_bytes;
}testOpus;
testOpus myAudioOpus={.sampling_rate=8*1000,
.channels=1,
.bitrate_bps=8*1000,
.error=0,
.srcData=NULL,
.srcSize=160,
.dstData=NULL,
.dstSize=0,
.outData=NULL,
.max_payload_bytes=160*2,
};
void opusDemo()
{
OpusEncoder *enc;
enc = opus_encoder_create(myAudioOpus.sampling_rate, myAudioOpus.channels, OPUS_APPLICATION_AUDIO, &myAudioOpus.error);
opus_encoder_ctl(enc, OPUS_SET_BITRATE(myAudioOpus.bitrate_bps));
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
opus_encoder_ctl(enc, OPUS_SET_VBR(1));
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0));
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(1));
opus_encoder_ctl(enc, OPUS_SET_DTX(1));
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0));
opus_int32 skip = 0;
opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
if(OPUS_OK!=myAudioOpus.error)
{
ESP_LOGI(TAG,"OPUS encoder init failed !");
}
else
{
ESP_LOGI(TAG,"OPUS encoder init success!");
}
ESP_LOGI(TAG,"ESP_LOGI raw data !:%d",myAudioOpus.srcSize);
uint32_t start=xTaskGetTickCount();
ESP_LOGI(TAG,"ready to encode!");
myAudioOpus.dstSize=opus_encode(enc,testWavArray,myAudioOpus.srcSize,outputData,myAudioOpus.max_payload_bytes);
uint32_t end=xTaskGetTickCount();
uint32_t resultTime = end - start ;
ESP_LOGI(TAG,"encode spend :%d ms! ",resultTime);
if(myAudioOpus.dstSize<0)
{
ESP_LOGI(TAG,"OPUS encode failed :%d!",myAudioOpus.dstSize);
}
else
{
ESP_LOGI(TAG,"OPUS encode success! len :%d",myAudioOpus.dstSize);
}
//压缩完成->>>>�???????始解�???????
OpusDecoder *dec;
dec= opus_decoder_create(myAudioOpus.sampling_rate,myAudioOpus.channels,&myAudioOpus.error);
if(OPUS_OK!=myAudioOpus.error)
{
ESP_LOGI(TAG,"OPUS decoder init failed !");
}
else
{
ESP_LOGI(TAG,"OPUS decoder init success!");
}
start=xTaskGetTickCount();
int decodeOutlen=opus_decode(dec,outputData,myAudioOpus.dstSize,decodeData,myAudioOpus.srcSize,0);
end=xTaskGetTickCount();
resultTime = end - start ;
ESP_LOGI(TAG,"decode spend :%d ms! ",resultTime);
if(decodeOutlen<0)
{
ESP_LOGI(TAG,"OPUS decode failed :%d!",decodeOutlen);
}
else
{
ESP_LOGI(TAG,"OPUS decode success! len :%d",decodeOutlen);
}
opus_encoder_destroy(enc);
opus_decoder_destroy(dec);
}
Arduino开发环境运行opus
在库管理器中下载ESP8266Audio这个库,下载安装。
创建一个点灯代码引入以下头文件:
#include "AudioGeneratorOpus.h"
#include "libopus/opus.h"
其他地方可以照抄上面的ESP-IDF代码,printf代码需要修改,在Arduino环境下,编译时非常慢,opus源文件有130+,编译可能长达十分钟!
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
Encoded size: -1
你能提供完整的代码供我们尝试吗?Opus Encode -> -1
我们正在为非洲国家制作esp32 WAN对讲机, 一起努力, 你也可加入吗
我很感兴趣,请邮件联系 15535904190@163.com
Thanks, replied
不是1ms,而是因为设置的RTOS tick是10ms
你好 下载了那个Git的代码 但是 编译源码有错 请问大佬 你出现过这种情况吗