#include #include #define TRACE() fprintf(stderr, "%s @ %s:%d\n", __FUNCTION__, __FILE__, __LINE__) #define UNUSED_ARGS(args) do {} while ((args) && !(args)) typedef struct { snd_pcm_ioplug_t io; // state } snd_pcm_sigma_t; static void snd_pcm_sigma_free(snd_pcm_sigma_t *sigma) { if (sigma) { free(sigma); } } static int snd_pcm_sigma_close(snd_pcm_ioplug_t *io) { snd_pcm_sigma_t *sigma; TRACE(); sigma = io->private_data; snd_pcm_sigma_free(sigma); return 0; } static snd_pcm_sframes_t snd_pcm_sigma_pointer(snd_pcm_ioplug_t *io) { UNUSED_ARGS(io); TRACE(); return 0; } static int snd_pcm_sigma_prepare(snd_pcm_ioplug_t *io) { UNUSED_ARGS(io); TRACE(); return 0; } static int snd_pcm_sigma_start(snd_pcm_ioplug_t *io) { UNUSED_ARGS(io); TRACE(); return 0; } static int snd_pcm_sigma_stop(snd_pcm_ioplug_t *io) { UNUSED_ARGS(io); TRACE(); return 0; } static snd_pcm_sframes_t snd_pcm_sigma_transfer(snd_pcm_ioplug_t *io, const snd_pcm_channel_area_t *areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { UNUSED_ARGS(io && areas && offset && size); TRACE(); return 0; } static snd_pcm_ioplug_callback_t sigma_pcm_callback = { .close = snd_pcm_sigma_close, .start = snd_pcm_sigma_start, .stop = snd_pcm_sigma_stop, .pointer = snd_pcm_sigma_pointer, .prepare = snd_pcm_sigma_prepare, .transfer = snd_pcm_sigma_transfer }; static int snd_pcm_sigma_open(snd_pcm_t **pcmp, const char *name, snd_config_t *playback_conf, snd_config_t *capture_conf, snd_pcm_stream_t stream, int mode) { int err; snd_pcm_sigma_t *sigma; TRACE(); UNUSED_ARGS(pcmp && playback_conf && capture_conf); sigma = calloc(1, sizeof(*sigma)); if (!sigma) return -ENOMEM; sigma->io.version = SND_PCM_IOPLUG_VERSION; sigma->io.name = "ALSA <-> SIGMA PCM I/O Plugin"; sigma->io.callback = &sigma_pcm_callback; sigma->io.private_data = sigma; err = snd_pcm_ioplug_create(&sigma->io, name, stream, mode); if (err < 0) { snd_pcm_sigma_free(sigma); return err; } *pcmp = sigma->io.pcm; return 0; } SND_PCM_PLUGIN_DEFINE_FUNC(sigma) { snd_config_iterator_t i, next; snd_config_t *playback_conf = NULL; snd_config_t *capture_conf = NULL; int err; UNUSED_ARGS(root); TRACE(); snd_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); const char *id; if (snd_config_get_id(n, &id) < 0) continue; if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0) continue; /* if (strcmp(id, "playback_ports") == 0) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) { SNDERR("Invalid type for %s", id); return -EINVAL; } playback_conf = n; continue; } if (strcmp(id, "capture_ports") == 0) { if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) { SNDERR("Invalid type for %s", id); return -EINVAL; } capture_conf = n; continue; } */ SNDERR("Unknown field %s", id); return -EINVAL; } err = snd_pcm_sigma_open(pcmp, name, playback_conf, capture_conf, stream, mode); return err; } SND_PCM_PLUGIN_SYMBOL(sigma);