源代码实现
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <alsa/asoundlib.h>
#include <signal.h>
#include <lame/lame.h>
/*PCM文件转码成mp3文件*/
void ConvertPCM2MP3WithPath(const char *inputPath, const char *outputPath)
{
size_t readSize, writeSize;
/*打开pcm文件以及mp3文件*/
FILE *pcmFile = fopen(inputPath, "rb");
if (!pcmFile)
{
fprintf(stderr, "could not open %s\n", inputPath);
return;
}
FILE *mp3File = fopen(outputPath, "wb");
if (!mp3File)
{
fprintf(stderr, "could not open %s\n", outputPath);
return;
}
const int PCM_BUFF_SIZE = 8192;
const int MP3_BUFF_SIZE = 8192;
short int pcm_buffer[PCM_BUFF_SIZE * 2];
unsigned char mp3_buffer[MP3_BUFF_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
do
{
readSize = fread(pcm_buffer, 2 * sizeof(short int), PCM_BUFF_SIZE, pcmFile);
printf("MP3::::::::::::: readSize: %ld \n", readSize);
if (readSize == 0)
{
writeSize = lame_encode_flush(lame, mp3_buffer, MP3_BUFF_SIZE);
}
else
{
writeSize = lame_encode_buffer_interleaved(lame, pcm_buffer, (int)readSize, mp3_buffer, MP3_BUFF_SIZE);
}
fwrite(mp3_buffer, writeSize, 1, mp3File);
} while (readSize != 0);
lame_close(lame);
fclose(mp3File);
fclose(pcmFile);
}
static int recording;
/*CTL+C 取消录音*/
void stop_recording(int param)
{
recording = 0;
}
/*开始录音*/
int StartRecode(const char *PcmFile)
{
FILE *pFile;
pFile = fopen(PcmFile, "wb");
if (pFile == NULL)
{
printf("open Pcmdfile err!\n");
return -1;
}
int rc;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
/*打开PCM capture捕捉设备*/
rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0)
{
printf("can't open pcm devecie\n");
exit(1);
}
/*分配一个硬件参数结构体*/
snd_pcm_hw_params_alloca(¶ms);
/*使用默认参数*/
snd_pcm_hw_params_any(handle, params);
/*Interleaved mode*/
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
/*设置16小端采样精度*/
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
/*双通道*/
snd_pcm_hw_params_set_channels(handle, params, 2);
/*采样率44100 CD级别音质*/
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
/*一个周期32帧*/
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
/*参数生效*/
rc = snd_pcm_hw_params(handle, params);
if (rc < 0)
{
printf("can't set hw params\n");
exit(0);
}
/*得到一个周期的数据大小*/
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
/* 16位采样精度 所以要*4*/
size = frames * 4;
buffer = (char *)malloc(size);
if (buffer == NULL)
{
printf("malloc buffer size err!\n");
return -2;
}
recording = 1;
while (recording)
{
/*捕捉数据*/
rc = snd_pcm_readi(handle, buffer, frames);
if (rc == -EPIPE)
{
printf("over run occured\n");
snd_pcm_prepare(handle);
}
else if (rc < 0)
{
printf("err from read!\n");
}
else if (rc != (int)frames)
{
printf("short read frames\n");
}
rc = fwrite(buffer, sizeof(char), size, pFile);
if (rc != size)
{
printf("short write %d bytes\n", rc);
}
if (signal(SIGINT, stop_recording) == SIG_ERR)
{
printf("signal failed\n");
}
}
/*关闭文件句柄*/
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
fclose(pFile);
}
int main(int argc, char *argv[])
{
StartRecode("test.pcm");
ConvertPCM2MP3WithPath("test.pcm", "Goal.mp3");
const char *cmd = "rm -f test.pcm";
system(cmd);
return 0;
}
gcc RecodePcm2Mp3.c -lasound -lmp3lame
编译成可执行文件