本文主要是介绍【开源项目】minimp3 MP3解码器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【开源项目】minimp3 MP3解码器
简介
minimp3 是一个极简的MP3解码器,它的特点是小巧(只有单个头文件)、快速(支持SSE和NEON)和准确(符合ISO标准)。
LICENSE:CC0-1.0 License
项目地址:
https://github.com/lieff/minimp3
该项目中提供了在 i7-6700K 上使用 perf
粗略测量的基准测试结果:
Vector | Hz | Samples | Sec | Clockticks | Clockticks per second | PSNR | Max diff |
---|---|---|---|---|---|---|---|
compl.bit | 48000 | 248832 | 5.184 | 14306684 | 2.759M | 124.22 | 1 |
he_32khz.bit | 32000 | 172800 | 5.4 | 8426158 | 1.560M | 139.67 | 1 |
he_44khz.bit | 44100 | 472320 | 10.710 | 21296300 | 1.988M | 144.04 | 1 |
he_48khz.bit | 48000 | 172800 | 3.6 | 8453846 | 2.348M | 139.67 | 1 |
hecommon.bit | 44100 | 69120 | 1.567 | 3169715 | 2.022M | 133.93 | 1 |
he_free.bit | 44100 | 156672 | 3.552 | 5798418 | 1.632M | 137.48 | 1 |
he_mode.bit | 44100 | 262656 | 5.955 | 9882314 | 1.659M | 118.00 | 1 |
si.bit | 44100 | 135936 | 3.082 | 7170520 | 2.326M | 120.30 | 1 |
si_block.bit | 44100 | 73728 | 1.671 | 4233136 | 2.533M | 125.18 | 1 |
si_huff.bit | 44100 | 86400 | 1.959 | 4785322 | 2.442M | 107.98 | 1 |
sin1k0db.bit | 44100 | 725760 | 16.457 | 24842977 | 1.509M | 111.03 | 1 |
使用
minimp3 的使用十分简单,基础解码功能使用的话只需要两个步骤,并且只需要调用以下两个函数就可以完成解码。
void mp3dec_init(mp3dec_t *dec);
int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info);
首先,初始化 minimp3 的解码器结构:
//#define MINIMP3_ONLY_MP3
//#define MINIMP3_ONLY_SIMD
//#define MINIMP3_NO_SIMD
//#define MINIMP3_NONSTANDARD_BUT_LOGICAL
//#define MINIMP3_FLOAT_OUTPUT
#define MINIMP3_IMPLEMENTATION
#include "minimp3.h"
...static mp3dec_t mp3d;mp3dec_init(&mp3d);
注意你必须在一个源文件中定义 MINIMP3_IMPLEMENTATION
。
然后,我们逐帧解码输入的数据流:
/*typedef struct{int frame_bytes;int channels;int hz;int layer;int bitrate_kbps;} mp3dec_frame_info_t;*/mp3dec_frame_info_t info;short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];/*unsigned char *input_buf; - input byte stream*/samples = mp3dec_decode_frame(&mp3d, input_buf, buf_size, pcm, &info);
mp3dec_decode_frame()
函数会从输入缓冲区解码一个完整的MP3帧,所以输出缓冲区必须足够大,可以容纳一个完整的帧。
解码器将分析输入缓冲区以正确地与MP3流同步,输入缓冲区的大小越大,同步过程就越可靠。建议每次在输入缓冲区中有多达 10 个连续的 MP3 帧(~16KB)。
消耗的 MP3 数据的大小在定义的mp3dec_frame_info_t
结构中的frame_bytes
字段中返回,你必须在下一次解码器调用之前从输入缓冲区中删除对应于 frame_bytes
字段的数据。
解码函数返回已解码样本的数量samples。可能出现以下情况:
- 0: 在输入缓冲区中未找到 MP3 数据
- 384: Layer 1
- 576: MPEG 2 Layer 3
- 1152: Otherwise
samples 和 frame_bytes 字段值:
samples > 0
和frame_bytes > 0
: 成功解码samples == 0
和frame_bytes > 0
: 解码器跳过了 ID3 或无效数据samples == 0
和frame_bytes == 0
: 数据不足
minimp3还有提供许多的配置与接口,可以实现更多的功能,详细的请查看该项目的README.md。
测试程序
写一个简单的测试程序进行解码并播放MP3:
unsigned char *input_buf = NULL;
int data_size = 0;
//打开MP3文件
FILE* file=fopen("test.mp3", "r");//获取MP3文件长度
fseek(file, 0, SEEK_END);
data_size = (int)ftell(file);//读取整个MP3文件
fseek(file, 0, SEEK_SET);
input_buf = malloc(data_size);
fread(input_buf, 1, data_size, file);//初始化minimp3的解码器结构
static mp3dec_t mp3d;
mp3dec_init(&mp3d);//定义mp3dec_frame_info_t
mp3dec_frame_info_t info;
short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
int mp3len = 0;//逐帧解码并且播放MP3
int samples = mp3dec_decode_frame(&mp3d, input_buf, data_size, pcm, &info);
while(samples) {play(pcm, samples);mp3len += info.frame_bytes;samples = mp3dec_decode_frame(&mp3d, input_buf + mp3len, data_size - mp3len, pcm, &info);
}free(input_buf);
这样就可以播放整首MP3歌曲了。
本文链接:https://blog.csdn.net/u012028275/article/details/123297598
这篇关于【开源项目】minimp3 MP3解码器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!