Here's the missing C program.
It turns out clearing the cache does not affect the issue; just my
first few tries showed a correlation. Now it seems to fail always. I
will update this bug report as soon as I know more.
#include <libffado/ffado.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
enum {
MAX_STREAMS = 16,
PERIOD_SIZE = 1024,
NB_BUFFERS = 3,
};
static float buffer[PERIOD_SIZE];
static bool
configure_stream(ffado_device_t *dev, int number)
{
return ffado_streaming_set_playback_stream_buffer(dev, number, (char *)buffer) == 0 &&
ffado_streaming_playback_stream_onoff(dev, number, 1) == 0;
}
int main(int argc, char **argv) {
ffado_device_t *dev;
ffado_device_info_t device_info;
memset(&device_info, 0, sizeof(device_info));
ffado_options_t options;
memset(&options, 0, sizeof(options));
options.sample_rate = 44100;
options.period_size = PERIOD_SIZE;
options.nb_buffers = NB_BUFFERS;
options.verbose = 5;
dev = ffado_streaming_init(device_info, options);
assert(dev != NULL);
ffado_streaming_set_audio_datatype(dev, ffado_audio_datatype_float);
int num_streams = ffado_streaming_get_nb_playback_streams(dev);
assert(num_streams > 0);
int streams[MAX_STREAMS], configured_streams = 0;
for (int i = 0; i < num_streams; ++i) {
char name[256];
ffado_streaming_get_playback_stream_name(dev, i, name,
sizeof(name) - 1);
ffado_streaming_stream_type type =
ffado_streaming_get_playback_stream_type(dev, i);
if (type != ffado_stream_type_audio)
continue;
printf("stream %d name='%s'\n", i, name);
streams[configured_streams++] = i;
configure_stream(dev, i);
}
if (ffado_streaming_prepare(dev) != 0) {
fprintf(stderr, "ffado_streaming_prepare() failed\n");
return 1;
}
if (ffado_streaming_start(dev) != 0) {
fprintf(stderr, "ffado_streaming_start() failed\n");
return 1;
}
while (true) {
switch (ffado_streaming_wait(dev)) {
case ffado_wait_ok:
break;
case ffado_wait_xrun:
printf("xrun\n");
break;
default:
fprintf(stderr, "ffado_streaming_wait() failed");
return 1;
}
if (ffado_streaming_transfer_playback_buffers(dev) != 0) {
fprintf(stderr, "ffado_streaming_transfer_playback_buffers() failed\n");
return 1;
}
printf(".\n");
}
return 0;
}