pcm数据比较大, 存储或传输的效率低,如编码成mp3数据,则数据可压缩到1/10.
本例使用lame库把pcm数据编码成mp3数据.
1). 准备好mp3编码库
下载lame库源码: https://sourceforge.net/projects/lame/files/lame/3.99/
下载后,进入源码目录:
./configure
make && make install
cp /usr/local/lib/libmp3lame.so* /lib64/
2). 了解库的编码流程
参考源码目录里的API文档.
lame_global_flags *gfp;
gfp = lame_init(); // 1. 库初始化功能
// 2. 编码配置的初始化
lame_set_num_channels(gfp,2); //设置pcm数据的声道数
lame_set_in_samplerate(gfp,44100); //采样率
lame_set_brate(gfp,128); // 128kbps 编码率
lame_set_mode(gfp,1); //设置输出的mp3数据的声道, 1==JOINT_STEREO, 3==MONO
lame_set_quality(gfp,2); /* 2=high 5 = medium 7=low */
//3. 用编码配置初始化库
ret_code = lame_init_params(gfp); // ret_code >= 0 表示成功
// 4.编码函数
int lame_encode_buffer(lame_global_flags *gfp, short int leftpcm[], short int rightpcm[], int num_samples,char *mp3buffer,int mp3buffer_size);
leftpcm表示左声道数据缓冲区首地址, rightpcm表示右声道数据缓冲区首地址, num_samples表示一个声道里有多少个采样, mp3buffer表示输出的mp3数据缓冲区首地址, mp3buffer_size表示mp3数据缓冲区的大小。
返回值为编码出来的mp3数据的长度.
lame_encode_buffer函数需要左右声道的数据分开, 而一般情况下声音数据都是左右声道交错地存放,所以用下面这个函数较为合适:
int lame_encode_buffer_interleaved(lame_global_flags *gfp, short int pcm[], int num_samples, char *mp3buffer,int mp3buffer_size)
// 5. 退出编码时,把剩下没编码的pcm数据全部转成mp3数据。返回值为mp3数据的长度.
int lame_encode_flush(lame_global_flags *,char *mp3buffer, int mp3buffer_size);
// 6. 关闭编码库
void lame_close(lame_global_flags *);
3). 把编码库的操作封装成一个类
mp3encoder.h
#ifndef MP3ENCODER_H
#define MP3ENCODER_H
#include
#include
class Mp3Encoder : public QObject
{
Q_OBJECT
public:
explicit Mp3Encoder(int rate, int channels, QObject *parent = 0);
~Mp3Encoder();
int encode(short *pcm_data, int pcmdata_len, char *mp3_data, int mp3data_len); //编码
int getLastMp3Data(char *mp3_data, int mp3data_len); //获取最后的mp3数据
private:
lame_global_flags *gfp;
signals:
public slots:
};
#endif // MP3ENCODER_H
mp3encoder.cpp
#include "mp3encoder.h"
Mp3Encoder::Mp3Encoder(int rate, int channels, QObject *parent) : QObject(parent)
{
gfp = lame_init();
this->channels = channels;
lame_set_num_channels(gfp,channels); //设置pcm数据的声道数
lame_set_in_samplerate(gfp, rate); //采样率
lame_set_brate(gfp,128); // 128kbps 编码率
lame_set_mode(gfp, channels>=2 ? STEREO : MONO); //设置输出的mp3数据的声道, 0==STEREO, 3==MONO
lame_set_quality(gfp,2); /* 2=high 5 = medium 7=low */
lame_init_params(gfp);
}
Mp3Encoder::~Mp3Encoder()
{
lame_close(gfp);
}
int Mp3Encoder::getLastMp3Data(char *mp3_data, int mp3data_len)
{
return lame_encode_flush(gfp, (quint8 *)mp3_data, mp3data_len);
}
int Mp3Encoder::encode(short *pcm_data, int pcmdata_len, char *mp3_data, int mp3data_len)
{
int num_samples = pcmdata_len>>1;
if (channels > 1)
num_samples >>= 1; //双声道的处理
return lame_encode_buffer_interleaved(gfp, pcm_data, num_samples, (unsigned char *)mp3_data, mp3data_len);
}
最后附上一在qt里简单的测试程序, 程序执行时开始录音并编码成mp3存放在”/my.mp3”, 直到程序退出执行.
http://download.csdn.net/detail/jklinux/9856129