c语言实现录音功能

写了个录音功能的小程序,给大家分享下,测试环境为ubuntu(Linux version 2.6.32-24-generic (buildd@rothera) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #39-Ubuntu SMP Wed Jul 28 06:07:29 UTC 2010)

<main.h>
#ifndef  _MAIN_H_
#define  _MAIN_H_

#include <sys/soundcard.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <linux/soundcard.h>
#include <pthread.h>

#define AUDIO_SAVE_PATH       ("/home/audio.txt")
#define AUDIO_PATH            ("/dev/dsp")


#define LENGTH            (3)        //录音时间
#define RATE              (8000)     //采样频率
#define SIZE              (16)       //量化位数
#define CHANNELS          (2)        //声道数目
#define MAX_BUFF_LEN      (LENGTH*RATE*SIZE*CHANNELS/8)         //保存录音的音频数据

enum
{
    ZJF_AUDIO_NULL = 0,
    ZJF_AUDIO_RECORD,
    ZJF_AUDIO_STOP,
    ZJF_AUDIO_PLAY
};

typedef struct Audio
{
    int Status;
}AudioStatus_t;

extern int ZJF_Audio_SetStatus_API(int status);
extern void ZJF_Audio_RecordPro_API( );
extern void ZJF_Audio_Ctrl_API( );
#endif
<ZJF_Audio_Record.c>

#include "main.h"

AudioStatus_t audio;


int ZJF_Audio_SetStatus_API(int status)
{
    printf("设置状态: %d \n",status);
    audio.Status = status;
    return 0;
}

void ZJF_Audio_RecordPro_API( )
{
    int wfd    = 0;   
    int a_fd   = 0;
    int temp   = 0;
    int status = 0;
    int ret    = 0;
    int sret   = 0;
    char buf[MAX_BUFF_LEN] = { 0 };

    int len = MAX_BUFF_LEN;

    a_fd = open(AUDIO_PATH,O_RDWR);
    if(a_fd < 0)
    {
        printf("open file %s failed !!! \n",AUDIO_PATH);
        goto ERR;
    }
    wfd = open(AUDIO_SAVE_PATH,O_CREAT|O_RDWR);
    if(wfd < 0)
    {
        printf("open file %s failed !!! \n",AUDIO_SAVE_PATH);
        goto ERR;
    }

    //设置采样时的量化位数
    temp = SIZE;
    status = ioctl(a_fd,SOUND_PCM_WRITE_BITS,&temp);
    if(status==-1)
    {
      perror("Cannot set SOUND_PCM_WRITE_BITS ");
      goto ERR;
   }

   //设置采样声道数目
   temp = CHANNELS;
   status=ioctl(a_fd,SOUND_PCM_WRITE_CHANNELS,&temp);
   if(status==-1){
      perror("Cannot set SOUND_PCM_WRITE_CHANNELS");
      goto ERR;
   }

   //设置采样频率
   temp = RATE;  
   status=ioctl(a_fd,SOUND_PCM_WRITE_RATE,&temp);
   if(status==-1)
   {
     perror("Cannot set SOUND_PCM_WRITE_RATE");
     goto ERR;
   }

   memset(&audio,0,sizeof(AudioStatus_t));
   while(1)
   {
       if(audio.Status == ZJF_AUDIO_NULL)
       {
           sleep(1);
           continue;
       }
       else if(audio.Status == ZJF_AUDIO_RECORD)
       {   
           //printf("录音 \n");
           ret = read(a_fd,buf,len);
           if(ret < 0)
           {
               perror("read err:");
               goto ERR;
           }

           if(ret > 0)
           {                           
               if(write(wfd,buf,len) < 0)
               {
                   perror("write err:");
                   goto ERR;
               }                           
           }           
       }
       else if(audio.Status == ZJF_AUDIO_STOP)
       {
           printf("audio stop !!! \n");
           goto ERR;
       }
       else if(audio.Status == ZJF_AUDIO_PLAY)
       {
           ret = read(wfd,buf,len);
           if(ret < 0)
           {
               perror("ZJF_AUDIO_PLAY read err:");
               goto ERR;
           }
           if(ret > 0)
           {
               if(write(a_fd,buf,len) < 0)
               {
                   perror("ZJF_AUDIO_PLAY write err:");
                   goto ERR;
               }
               //ioctl(a_fd,SOUND_PCM_SYNC,0);
           }        
       }
   }

ERR:    
    if(a_fd > 0)
    {
        close(a_fd);
        a_fd = -1;
    }
    if(wfd > 0)
    {
        close(wfd);
        wfd = -1;
    }
    return ;
}

<ZJF_Audio_Ctrl.c>
#include "main.h"


void ZJF_Audio_Ctrl_API( )
{
    int type = 0;

    while(1)
    {
        printf("1: 录音 \n2: 停止 \n3: 播放\n当前状态是:%d\n",type);

        scanf("%d",&type);

        ZJF_Audio_SetStatus_API(type);
        if(ZJF_AUDIO_STOP == type)
        {
            break;
        }
    }

    return ;
}


<main.c>
#include "main.h"


int main()
{
    pthread_t ntid;

    if(pthread_create(&ntid,NULL,(void *)ZJF_Audio_RecordPro_API,NULL))  
    {  
        printf("can't create thread !!! \n");  
        return 1;  
    }

    if(pthread_create(&ntid,NULL,(void *)ZJF_Audio_Ctrl_API,NULL))  
    {  
        printf("can't create thread !!! \n");  
        return 1;  
    }

    while(1)
    {
        sleep(10);
    }
    return 0;
}
  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在C语言中调用ALSA(Advanced Linux Sound Architecture)库来实现录音功能,你可以使用ALSA提供的API来控制音频输入设备并捕获音频数据。以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <alsa/asoundlib.h> #define SAMPLE_RATE 44100 #define NUM_SECONDS 5 #define OUTPUT_FILE "recorded_audio.wav" int main() { int err; int numSamples = NUM_SECONDS * SAMPLE_RATE; short *recordedSamples; recordedSamples = (short *)malloc(sizeof(short) * numSamples); if (recordedSamples == NULL) { printf("Failed to allocate memory.\n"); return 1; } snd_pcm_t *handle; snd_pcm_hw_params_t *params; err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0); if (err < 0) { printf("Failed to open PCM device: %s\n", snd_strerror(err)); return 1; } snd_pcm_hw_params_alloca(&params); err = snd_pcm_hw_params_any(handle, params); if (err < 0) { printf("Failed to initialize PCM device parameters: %s\n", snd_strerror(err)); return 1; } err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { printf("Failed to set PCM device access type: %s\n", snd_strerror(err)); return 1; } err = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (err < 0) { printf("Failed to set PCM device sample format: %s\n", snd_strerror(err)); return 1; } err = snd_pcm_hw_params_set_rate_near(handle, params, &SAMPLE_RATE, 0); if (err < 0) { printf("Failed to set PCM device sample rate: %s\n", snd_strerror(err)); return 1; } err = snd_pcm_hw_params_set_channels(handle, params, 1); if (err < 0) { printf("Failed to set PCM device channel count: %s\n", snd_strerror(err)); return 1; } err = snd_pcm_hw_params(handle, params); if (err < 0) { printf("Failed to set PCM device parameters: %s\n", snd_strerror(err)); return 1; } printf("Recording started. Press Ctrl+C to stop recording.\n"); while (numSamples > 0) { err = snd_pcm_readi(handle, recordedSamples, numSamples); if (err == -EPIPE) { printf("Overrun occurred.\n"); snd_pcm_prepare(handle); } else if (err < 0) { printf("Failed to read from PCM device: %s\n", snd_strerror(err)); return 1; } else { numSamples -= err; recordedSamples += err * snd_pcm_hw_params_get_channels(params); } } err = snd_pcm_close(handle); if (err < 0) { printf("Failed to close PCM device: %s\n", snd_strerror(err)); return 1; } FILE *file = fopen(OUTPUT_FILE, "wb"); if (file == NULL) { printf("Failed to open output file.\n"); return 1; } fwrite(recordedSamples, sizeof(short), numSamples, file); fclose(file); free(recordedSamples); printf("Recording finished. Saved as %s\n", OUTPUT_FILE); return 0; } ``` 这个示例程序使用ALSA库来打开默认的PCM设备,并读取音频数据。它将录制的音频数据存储在一个内存缓冲区中,并将其写入名为"recorded_audio.wav"的文件中。 请确保在编译时链接ALSA库,例如: ```shell gcc -o record_audio record_audio.c -lasound ``` 这只是一个简单的示例,你可以根据自己的需求进行修改和扩展。希望对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿木小呆呆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值