开源LC3编解码器测试Demo
本文开源LC3编解码器实现来自于Zephyr项目下的一个模块,github仓库:https://github.com/zephyrproject-rtos/liblc3codec使用本demo只需复制test.c和Makefile到clone下来的文件夹内,使用的测试文件名为test_48K_16.pcm,编码后的文件名为encodedata,解码后的文件名为decode.pcm音频测试文件格式为
1.介绍
本文开源LC3编解码器实现来自于Zephyr项目下的一个模块,github仓库:
https://github.com/zephyrproject-rtos/liblc3codec
2.使用
使用本demo只需复制test.c和Makefile到clone下来的文件夹内,使用的测试文件名为test_48K_16.pcm,编码后的文件名为encodedata,解码后的文件名为decode.pcm
音频测试文件格式为:
如果你想使用自己的音频文件测试,请根据实际文件修改代码。
3.修改配置
3.1PCM格式
本库LC3支持两种格式:
16bit格式
LC3_PCM_FORMAT_S16
24bit格式
LC3_PCM_FORMAT_S24
16bit格式下每个采样占用2个字节,24bit没使用过,但是每个采样应该占用4个字节。
3.2帧长
通常单帧音频长10ms,也支持7.5ms(应该是为了兼容经典蓝牙音频)
3.3采样率
采样率支持 8000, 16000, 24000, 32000, 48000。正常LC3应该还支持44.1KHz的采样率,但是笔者发现官方测试demo中把44100注释掉了,不知是否本库还未支持,建议先不要用44100测试。
3.4编码输出字节
范围是20~400,但是BAP其实规定了一些固定规格,如下图所示:
本demo中使用120字节,也就是单帧被编码为120字节。
4.代码
4.1test.c
#include "include/lc3.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
//PCM格式
enum lc3_pcm_format pcmFormat = LC3_PCM_FORMAT_S16;
//帧长10ms
int dtUs = 10000;
//采样率48K
int srHz =48000;
//单帧编码后输出字节数
uint16_t output_byte_count = 120;
//编码器需占用缓存大小
unsigned encodeSize = lc3_encoder_size(dtUs, srHz);
//解码器需占用缓存大小
unsigned decodeSize = lc3_decoder_size(dtUs, srHz);
//单帧的采样数
uint16_t sampleOfFrames = lc3_frame_samples(dtUs, srHz);
//单帧字节数,一个采样占用两个字节
uint16_t bytesOfFrames = sampleOfFrames*2;
//编码器缓存
void* encMem = NULL;
//解码器缓存
void* decMem = NULL;
//输入文件的文件描述符
int inFd = -1;
//输出文件的文件描述符
int outFd = -1;
//输入帧缓冲
unsigned char *inBuf = (unsigned char *)malloc(bytesOfFrames);
//输出帧缓冲
unsigned char *outBuf = (unsigned char *)malloc(bytesOfFrames);
encMem = malloc(encodeSize);
/* 编码 */
lc3_encoder_t lc3_encoder = lc3_setup_encoder(dtUs, srHz, 0, encMem);
if((inFd = open("./test_48K_16.pcm", O_RDONLY))<=0)
{
printf("encode open inFd err\n");
return -1;
}
if((outFd = open("./encodedata", O_CREAT|O_WRONLY|O_TRUNC, 0666))<=0)
{
printf("encode open outFd err\n");
return -1;
}
while(read(inFd,inBuf,bytesOfFrames)==bytesOfFrames)
{
lc3_encode(lc3_encoder, pcmFormat, (const int16_t*)inBuf, 1,output_byte_count, outBuf);
// memcpy(outBuf,inBuf,bytesOfFrames);
if(write(outFd,outBuf,output_byte_count)!=output_byte_count)
{
printf("encode write err\n");
break;
}
memset(inBuf,0,bytesOfFrames);
memset(outBuf,0,bytesOfFrames);
}
free(encMem);
encMem = NULL;
close(inFd);
close(outFd);
/* 解码 */
decMem = malloc(decodeSize);
lc3_decoder_t lc3_decoder = lc3_setup_decoder(dtUs, srHz, 0, decMem);
if((inFd = open("./encodedata", O_RDONLY))<=0)
{
printf("decode open inFd err\n");
return -1;
}
if((outFd = open("./decode.pcm", O_CREAT|O_WRONLY|O_TRUNC, 0666))<=0)
{
printf("decode open outFd err\n");
return -1;
}
while(read(inFd,inBuf,output_byte_count)==output_byte_count)
{
lc3_decode(lc3_decoder, inBuf, output_byte_count, pcmFormat,outBuf, 1);
if(write(outFd,outBuf,bytesOfFrames)!=bytesOfFrames)
{
printf("decode write err\n");
break;
}
memset(inBuf,0,bytesOfFrames);
memset(outBuf,0,bytesOfFrames);
}
free(decMem);
close(inFd);
close(outFd);
free(inBuf);
free(outBuf);
inBuf = NULL;
outBuf = NULL;
return 0;
}
4.2Makefile
TARGET = test
BUILD_DIR = build
CC = gcc
CFLAGS = $(INCLUDES)
OFLAGS = -lm
SOURCES = \
test.c \
$(wildcard ./src/*.c)
INCLUDES = \
-Iinclude/ \
-Isrc/
FILE_PATH = \
./ \
./src/
TEST_OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES:.c=.o)))
vpath %.c $(FILE_PATH)
all: $(TARGET)
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) $< -o $@
$(TARGET) : $(TEST_OBJECTS)
$(CC) $(CFLAGS) $(TEST_OBJECTS) $(OFLAGS) -o $@
$(BUILD_DIR):
mkdir $@
clean:
rm -rf $(BUILD_DIR)
rm $(TARGET)
懒人专用链接:
https://github.com/CXsCode/lc3test
附
官方LC3文档:
Low Complexity Communication Codec 1.0 – Bluetooth® Technology Website
ETSI提供的开源LC3plus实现:
https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.03.01_60/ts_103634v010301p0.zip
实现方案:
https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.03.01_60/ts_103634v010301p.pdf
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)