2017-01-02 2 views
0

Я пытаюсь захватить данные через ALSA API с помощью этого кода на C:программа перестает работать при добавлении нового кода

#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; 
} 

Так что код на самом деле работает, но если добавить еще один цикл в «While (петли> 0)», например:

int i; 
for(i=0;i<128;i++){ 
printf("I: %i \n", i); 
} 

выход программы будет:

unable to set hw parameters: Invalid argument 

Я действительно не понимаю, как простой петле а t конец может повлиять на программу в начале? Кто-нибудь знает, как исправить/предотвратить эту ошибку? Спасибо большое!

+4

Итак, вы показываете нам код, который работает, а не код, который не работает? –

+2

Это похоже на C. Любая причина, по которой вы добавили тег C++? C++ - это другой язык, в общем компилирующий C-код, поскольку C++ - плохая идея. Идентичный синтаксис не подразумевает идентичную семантику! – Olaf

+0

* «Такая же ошибка появляется, если код скомпилирован с g ++, с gcc без проблем». * Компилятор C++, отклоняющий (возможно) действительный код C, не является неожиданностью. – StoryTeller

ответ

0

Ошибка удалось установить параметры оборудования автомобиля: Недопустимый аргумент не из-за ваш дополнительным фрагмент кода. Фактическая причина ошибки неинициализирована dir переменная. Чтобы исправить эту проблему, вам необходимо правильно инициализировать dir или передать 0 или NULL вместо &dir.

Смежные вопросы