Я пытаюсь написать программу C (на Linux), которая воспроизводит синусоидальную волну от динамиков, используя интерфейс ядра ALSA (минимальный воспроизводимый пример). < /p>
Я открываю FD, как это: < /p>
int controlfd = open("/dev/snd/controlC0",O_RDWR);
int subdev = 0;
ioctl(controlfd,SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE,&subdev)
close(controlfd);
int fd = open("/dev/snd/pcmC0D0p", O_RDWR | __O_CLOEXEC);
< /code>
Моя конфигурация выглядит следующим образом: < /p>
set_param(params,SNDRV_PCM_HW_PARAM_ACCESS,SNDRV_PCM_ACCESS_RW_INTERLEAVED);
set_param(params,SNDRV_PCM_HW_PARAM_FORMAT,SNDRV_PCM_FORMAT_S16_LE);
set_param(params,SNDRV_PCM_HW_PARAM_CHANNELS,2);
set_param(params,SNDRV_PCM_HW_PARAM_RATE,48000);
...
get_param_int(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,&period_size)
sparams->tstamp_mode = SNDRV_PCM_TSTAMP_ENABLE;
sparams->period_step = 1;
sparams->avail_min = period_size;
sparams->start_threshold = ALSA_BUFFER_SIZE - period_size;
sparams->stop_threshold = ALSA_BUFFER_SIZE;
sparams->xfer_align = period_size / 2;
< /code>
И я пытаюсь воспроизводить звук здесь: < /p>
unsigned int numframes=48000;
short* samples = calloc(numframes,sizeof(short));
// generate frames
for (int i = 0; i < numframes; i++) {
samples[i] = 30000 * sinf(2 * M_PI * 200 *((float)i / numframes));
}
unsigned char *data = (unsigned char*)samples;
struct snd_xferi xfer = { 0 };
int ret, avail, s = sample_size * channels;
if (ioctl(fd,SNDRV_PCM_IOCTL_PREPARE) < 0) pexit("ioctl SNDRV_PCM_IOCTL_PREPARE");
// play the frames
int correct_count = 0;
do {
xfer.buf = data;
xfer.frames = numframes > period_size ? period_size : numframes;
xfer.result = 0;
if(!(ret = ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xfer))) {
avail = mmap_status->hw_ptr + ALSA_BUFFER_SIZE - mmap_control->appl_ptr;
if(avail < 0) avail += boundary; else
if((unsigned int)avail >= boundary) avail -= boundary;
numframes -= xfer.result;
data += xfer.result * s;
++correct_count;
} else if (errno == EPIPE) {
if (ioctl(fd,SNDRV_PCM_IOCTL_PREPARE) < 0) pexit("ioctl SNDRV_PCM_IOCTL_PREPARE");
} else {
ioctl(fd, SNDRV_PCM_IOCTL_DRAIN);
close(fd);
fprintf(stderr,"ioctl SNDRV_PCM_IOCTL_WRITEI_FRAMES failed after successfully sending %d frames: ",correct_count);
pexit("");
}
} while(numframes > 0);
и после нескольких итераций цикла, программа всегда выходит с ioctl sndrv_pcm_ioctl_writei_frames после успешной отправки 32 кадров: ввод/вывод ошибка , без какого -либо звука. Fedora Quemu VM без PulseAudio, Jack или даже Asoundlib, и я проверил, этот звук работает в виртуальной машине.
Я пытаюсь написать программу C (на Linux), которая воспроизводит синусоидальную волну от динамиков, используя интерфейс ядра ALSA (минимальный воспроизводимый пример). < /p> Я открываю FD, как это: < /p> [code] int controlfd = open("/dev/snd/controlC0",O_RDWR); int subdev = 0; ioctl(controlfd,SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE,&subdev) close(controlfd); int fd = open("/dev/snd/pcmC0D0p", O_RDWR | __O_CLOEXEC); < /code> Моя конфигурация выглядит следующим образом: < /p> set_param(params,SNDRV_PCM_HW_PARAM_ACCESS,SNDRV_PCM_ACCESS_RW_INTERLEAVED); set_param(params,SNDRV_PCM_HW_PARAM_FORMAT,SNDRV_PCM_FORMAT_S16_LE); set_param(params,SNDRV_PCM_HW_PARAM_CHANNELS,2); set_param(params,SNDRV_PCM_HW_PARAM_RATE,48000); ... get_param_int(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,&period_size)
sparams->tstamp_mode = SNDRV_PCM_TSTAMP_ENABLE; sparams->period_step = 1; sparams->avail_min = period_size; sparams->start_threshold = ALSA_BUFFER_SIZE - period_size; sparams->stop_threshold = ALSA_BUFFER_SIZE; sparams->xfer_align = period_size / 2; < /code> И я пытаюсь воспроизводить звук здесь: < /p> unsigned int numframes=48000; short* samples = calloc(numframes,sizeof(short));
// generate frames for (int i = 0; i < numframes; i++) { samples[i] = 30000 * sinf(2 * M_PI * 200 *((float)i / numframes)); }
if (ioctl(fd,SNDRV_PCM_IOCTL_PREPARE) < 0) pexit("ioctl SNDRV_PCM_IOCTL_PREPARE");
// play the frames int correct_count = 0; do { xfer.buf = data; xfer.frames = numframes > period_size ? period_size : numframes; xfer.result = 0; if(!(ret = ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xfer))) { avail = mmap_status->hw_ptr + ALSA_BUFFER_SIZE - mmap_control->appl_ptr; if(avail < 0) avail += boundary; else if((unsigned int)avail >= boundary) avail -= boundary; numframes -= xfer.result; data += xfer.result * s; ++correct_count; } else if (errno == EPIPE) { if (ioctl(fd,SNDRV_PCM_IOCTL_PREPARE) < 0) pexit("ioctl SNDRV_PCM_IOCTL_PREPARE"); } else { ioctl(fd, SNDRV_PCM_IOCTL_DRAIN); close(fd); fprintf(stderr,"ioctl SNDRV_PCM_IOCTL_WRITEI_FRAMES failed after successfully sending %d frames: ",correct_count); pexit(""); } } while(numframes > 0); [/code] и после нескольких итераций цикла, программа всегда выходит с ioctl sndrv_pcm_ioctl_writei_frames после успешной отправки 32 кадров: ввод/вывод ошибка , без какого -либо звука. Fedora Quemu VM без PulseAudio, Jack или даже Asoundlib, и я проверил, этот звук работает в виртуальной машине.