树莓派上的录音和播放在C中使用ALSA

问题描述:

我正在尝试录制声音并将其播放到C程序中。 就像使用这些终端线路:树莓派上的录音和播放在C中使用ALSA

arecord -D plughw:0 -r 16000 sample.wav 

备案,后来就

aplay sample.wav 

播放声音。

我用这个代码:

/* 


This example reads from the default PCM device 
and writes to standard output for 5 seconds of data. 


*/ 


/* Use the newer ALSA API */ 
#define ALSA_PCM_NEW_HW_PARAMS_API 


#include <alsa/asoundlib.h> 


int main() { 
    long loops; 
    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; 


    /* Open PCM device for recording (capture). */ 
    rc = snd_pcm_open(&handle, "default", 
        SND_PCM_STREAM_CAPTURE, 0); 
    if (rc < 0) { 
    fprintf(stderr, 
      "unable to open pcm device: %s\n", 
      snd_strerror(rc)); 
    exit(1); 
    } 


    /* Allocate a hardware parameters object. */ 
    snd_pcm_hw_params_alloca(&params); 


    /* Fill it in with default values. */ 
    snd_pcm_hw_params_any(handle, params); 


    /* Set the desired hardware parameters. */ 


    /* Interleaved mode */ 
    snd_pcm_hw_params_set_access(handle, params, 
         SND_PCM_ACCESS_RW_INTERLEAVED); 


    /* Signed 16-bit little-endian format */ 
    snd_pcm_hw_params_set_format(handle, params, 
           SND_PCM_FORMAT_S16_LE);         


    /* Two channels (stereo) */ 
    snd_pcm_hw_params_set_channels(handle, params, 2);         


    /* 44100 bits/second sampling rate (CD quality) */ 
    val = 44100;              
    snd_pcm_hw_params_set_rate_near(handle, params, 
            &val, &dir); 


    /* Set period size to 32 frames. */ 
    frames = 32; 
    snd_pcm_hw_params_set_period_size_near(handle, 
           params, &frames, &dir); 


    /* Write the parameters to the driver */ 
    rc = snd_pcm_hw_params(handle, params); 
    if (rc < 0) { 
    fprintf(stderr, 
      "unable to set hw parameters: %s\n", 
      snd_strerror(rc)); 
    exit(1); 
    } 


    /* Use a buffer large enough to hold one period */ 
    snd_pcm_hw_params_get_period_size(params, 
             &frames, &dir); 
    size = frames * 4; /* 2 bytes/sample, 2 channels */ 
    buffer = (char *) malloc(size); 


    /* We want to loop for 5 seconds */ 
    snd_pcm_hw_params_get_period_time(params, 
             &val, &dir); 
    loops = 5000000/val; 


    while (loops > 0) { 
    loops--; 
    rc = snd_pcm_readi(handle, buffer, frames); 
    if (rc == -EPIPE) { 
     /* EPIPE means overrun */ 
     fprintf(stderr, "overrun occurred\n"); 
     snd_pcm_prepare(handle); 
    } else if (rc < 0) { 
     fprintf(stderr, 
       "error from read: %s\n", 
       snd_strerror(rc)); 
    } else if (rc != (int)frames) { 
     fprintf(stderr, "short read, read %d frames\n", rc); 
    } 
    rc = write(1, buffer, size); 
    if (rc != size) 
     fprintf(stderr, 
       "short write: wrote %d bytes\n", rc); 
    } 


    snd_pcm_drain(handle); 
    snd_pcm_close(handle); 
    free(buffer); 


    return 0; 
} 

我编译该文件是这样的:

gcc -o recorder -lasound recorder.c 

并运行它:

./recorder < sample.wav 

,如果我尝试用“aplay玩这个sample.wav“这是一个可怕的嘈杂的声音。 但如果我使用“aplay -t raw -f S16_LE -c2 -r44100 sample.wav” 它的效果很好。

我做错了什么,如果有一种简单的方法来捕捉音频并在树莓派上播放它?

谢谢你的时间。

它只是一个基本的东西,当你试图aplay sample.wav"“aplay”将查找波头,而它不在你的文件中。所以它以其他格式播放(采样频率,频道等)。这就是为什么你的音频变得嘈杂。

但在aplay -t raw -f S16_LE -c2 -r44100 sample.wav您提供的所有信息和工作正常。