音视频学习----------Ubutun下使用alsa录音成Pcm文件再使用liblame转码Pcm成mp3文件

源代码实现

#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(&params);

    /*使用默认参数*/
    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
编译成可执行文件

发布了23 篇原创文章 · 获赞 9 · 访问量 1682

猜你喜欢

转载自blog.csdn.net/weixin_42590177/article/details/103812500