【发布时间】:2015-10-29 00:39:29
【问题描述】:
我完全不了解与编程音频处理相关的主题,但我想将 PCM 音频数据转换为 MP3。
我的音频是PCM格式,频率为8kHz,位宽为8,字节类型为无符号,声道为单声道。
我正在使用 liblamemp3,通过执行以下命令行,我找到了 lame.exe 前端的方法:
$ ./lame -r -s 8 --bitwidth 8 --unsigned -m m ../../../../voice8K16bitmono.pcm output.mp3
结果是一个我听得很清楚的.mp3。 (经过一些尝试)。
问题是我想即时完成,所以我尝试编写一些源代码来完成它而不调用前端。
我的源代码是:
#include <stdio.h>
#include <lame/lame.h>
int main(int argc, char *argv[])
{
int read, write;
FILE *pcm = fopen(argv[1], "rb");
FILE *mp3 = fopen("file.mp3", "wb");
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
unsigned short pcm_buffer;
unsigned short pcm_buffer_le;
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_num_samples(lame, 8000);
lame_set_in_samplerate(lame, 8000);
lame_set_out_samplerate(lame, 8000);
lame_set_num_channels(lame, 1);
lame_set_mode(lame, 3);
lame_init_params(lame);
lame_print_config(lame);
//framesize is bits / channels = 8.
do {
read = fread(&pcm_buffer, sizeof(short), 1, pcm);
pcm_buffer = (pcm_buffer>>8) | (pcm_buffer<<8);
if (read == 0) {
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, sizeof(char), write, mp3);
break;
}
//pcm_buffer_le[0] = (pcm_buffer[0]>>8) | (pcm_buffer[0]<<8);
write = lame_encode_buffer_interleaved(lame, &pcm_buffer, sizeof(short), mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, sizeof(char), write, mp3);
} while (1);
lame_close(lame);
fclose(mp3);
fclose(pcm);
return 0;
}
我从一个示例中获取它,并尝试应用我需要的设置。但是生成的 .mp3 听起来像一个反应堆,听起来不太好。所以我错过了一些/很多代码。
我想做,有谁能帮忙吗?
提前致谢。
【问题讨论】:
-
也许你的字节序是倒序的?
-
哦,谢谢。所以我必须从 PCM 缓冲区的末尾开始?
-
不不不不。每个 PCM 样本中的字节顺序。一些系统(x86、ARM)是小端,而其他系统(PPC、网络等)是大端是一个常见的问题。您正在阅读的 PCM 数据可能是大端,而图书馆期待小端。或者,也许您实际上不是在读取 PCM 数据,而是在读取一个 wav 文件头,加上 PCM 等。
-
好的。如果我没记错的话,每个 PCM 样本是 8 个字节(4 个短裤)。我是否应该将每个短帧的顺序和 8 字节大小的传递帧交换到 lame_encode_buffer_interleaved(),但之前已交换?抱歉,我对音频一无所知...
-
.pcm 文件也没有标题。这只是 RAW PCM 音频数据。