Я открываю 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;
numframes*=4; // (sizeof(int16_t)/sizeof(byte))
struct snd_xferi xfer = { 0 };
int ret, avail;
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 * 4; // 4==channels*(int16_t/byte)
++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 %li bytes in %d portions: ", ((size_t)data-(size_t)samples),correct_count);
pexit("");
}
} while(numframes > 0);
< /code>
и после нескольких итераций цикла while и lecmiting ~ 0,1 секунды (всегда одного и того же) звука на моем ноутбуке, но не в виртуальной машине Qemu, программа всегда выходит с: < /p>
ioctl SNDRV_PCM_IOCTL_WRITEI_FRAMES failed after successfully sending 4096 bytes in 32 portions: Input/output error
(и по какой -то причине 4096 - это то же число, что и Macro ALSA_BUFFER_SIZE
, почему это может произойти (что я делаю неправильно) и как это исправить? Ноутбук с ubuntu gnome x11 и федорой quemu vm без Pulseaudio, Jack или даже Asoundlib, и я проверил, этот звук работает в виртуальной машине.
Подробнее здесь: https://stackoverflow.com/questions/797 ... writing-fr
Мобильная версия