linux下lamealsa进行音频流操作(四)alsa+lame将音频流转为MP3
生活随笔
收集整理的這篇文章主要介紹了
linux下lamealsa进行音频流操作(四)alsa+lame将音频流转为MP3
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.linux下使用alsa錄音成pcm文件再使用lame轉碼為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(¶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
2.linux下使用alsa收集音頻流使用lame直接保存為MP3
代碼1:
/*============================================================================= # FileName: pcm_encoder_mp3.c # Desc: use lame encode pcm data to mp3 format, the pcm data # read from alsa # Author: licaibiao # LastChange: 2017-03-27 =============================================================================*/ #define ALSA_PCM_NEW_HW_PARAMS_API #include <alsa/asoundlib.h> #include <stdio.h> #include <stdlib.h> #include <lame/lame.h> #define INBUFSIZE 128 #define MP3BUFSIZE (int) (1.25 * INBUFSIZE) + 7200lame_global_flags *gfp; short *input_buffer; char *mp3_buffer; char *outPath = "out.mp3"; FILE *infp; FILE *outfp;snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames; snd_pcm_t *handle; int size; short *alsa_buffer;void lame_init_set(void) {int ret_code;gfp = lame_init();if (gfp == NULL) {printf("lame_init failed/n");}ret_code = lame_init_params(gfp);if (ret_code < 0){printf("lame_init_params returned %d/n",ret_code);}outfp = fopen(outPath, "wb"); }void lame_alloc_buffer(void) {input_buffer = (short*)malloc(INBUFSIZE*2);mp3_buffer = (char*)malloc(MP3BUFSIZE); }void lame_release(void) {free(mp3_buffer);free(input_buffer);fclose(outfp);lame_close(gfp); }void alsa_init(void){unsigned int val;int dir;int ret;ret = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0);if (ret < 0) {fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(ret));exit(1);}snd_pcm_hw_params_alloca(?ms);snd_pcm_hw_params_any(handle, params);snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);snd_pcm_hw_params_set_channels(handle, params, 2);val = 44100;snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);frames = 32;snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);ret = snd_pcm_hw_params(handle, params);if (ret < 0) {fprintf(stderr,"unable to set hw parameters: %s\n", snd_strerror(ret));exit(1);} }void alsa_alloc_buffer(void){int dir;snd_pcm_hw_params_get_period_size(params, &frames, &dir);size = frames * 4; alsa_buffer = (short *) malloc(size);}void alsa_release(void){snd_pcm_drain(handle);snd_pcm_close(handle);free(alsa_buffer); } void lame_encode(void) {int input_samples;int mp3_bytes;int status = 0;int ret = 0;int loop = 10000;while(loop--){ret = snd_pcm_readi(handle, alsa_buffer, frames);if (ret == -EPIPE){fprintf(stderr, "overrun occurred\n");snd_pcm_prepare(handle);}else if(ret == -EBADFD){printf("PCM is not in the right state \n");}else if(ret == -ESTRPIPE){printf("stream is suspended and waiting for an application recovery \n");}else if (ret < 0){fprintf(stderr, "error from read: %s\n",snd_strerror(ret));}else if (ret != (int)frames){fprintf(stderr, "short read, read %d frames\n", ret);}else if (ret == 0){printf(" pcm read 0 frame deta \n ");}memcpy(input_buffer, alsa_buffer, size);mp3_bytes = lame_encode_buffer_interleaved(gfp, input_buffer, size/4, mp3_buffer, MP3BUFSIZE);if (mp3_bytes < 0) {printf("lame_encode_buffer_interleaved returned %d \n", mp3_bytes);} else if(mp3_bytes > 0) {fwrite(mp3_buffer, 1, mp3_bytes, outfp);}}mp3_bytes = lame_encode_flush(gfp, mp3_buffer, sizeof(mp3_buffer));if (mp3_bytes > 0) {printf("writing %d mp3 bytes\n", mp3_bytes);fwrite(mp3_buffer, 1, mp3_bytes, outfp);} }int main(int argc, char** argv) {lame_init_set();lame_alloc_buffer();alsa_init();alsa_alloc_buffer();lame_encode();lame_release();alsa_release(); }代碼2:
https://github.com/RichardoMrMu/alsa_lame_pcm_2_mp3?organization=RichardoMrMu&organization=RichardoMrMu
總結
以上是生活随笔為你收集整理的linux下lamealsa进行音频流操作(四)alsa+lame将音频流转为MP3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用iperf3网络速度测试工具测试Wi
- 下一篇: 中文词性标注详解