2016-07-27 95 views
0

我正在嘗試錄製聲音並將其播放到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」 它的效果很好。

我做錯了什麼,如果有一種簡單的方法來捕捉音頻並在樹莓派上播放它?

謝謝你的時間。

回答

0

它只是一個基本的東西,當你試圖aplay sample.wav"「aplay」將查找波頭,而它不在你的文件中。所以它以其他格式播放(採樣頻率,頻道等)。這就是爲什麼你的音頻變得嘈雜。

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