diff --git a/pinos/gst/gstpinosformat.c b/pinos/gst/gstpinosformat.c index e75293484..6c9cb696f 100644 --- a/pinos/gst/gstpinosformat.c +++ b/pinos/gst/gstpinosformat.c @@ -157,13 +157,13 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } @@ -207,16 +207,16 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; ri++; - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } } pi++; @@ -264,16 +264,16 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; ri++; - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } @@ -294,13 +294,13 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } @@ -321,13 +321,13 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } @@ -344,13 +344,13 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } @@ -367,13 +367,13 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs) p = ++sv; } else if (G_VALUE_TYPE (val) == GST_TYPE_LIST) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else if (G_VALUE_TYPE (val) == GST_TYPE_ARRAY) { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } else { fprintf (stderr, "implement me\n"); - f->props.unset_mask |= (1u << pi); + SPA_PROPS_INDEX_UNSET (&f->props, pi); } pi++; } diff --git a/pinos/tests/alsa-utils.c b/pinos/tests/alsa-utils.c deleted file mode 100644 index 8479d0bd3..000000000 --- a/pinos/tests/alsa-utils.c +++ /dev/null @@ -1,361 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static int verbose = 0; /* verbose flag */ - -#define CHECK(s,msg) if ((err = (s)) < 0) { printf (msg ": %s\n", snd_strerror(err)); return err; } - -static snd_pcm_format_t -spi_alsa_format_to_alsa (const char *format) -{ - if (strcmp (format, "S8") == 0) - return SND_PCM_FORMAT_S8; - if (strcmp (format, "U8") == 0) - return SND_PCM_FORMAT_U8; - /* 16 bit */ - if (strcmp (format, "S16LE") == 0) - return SND_PCM_FORMAT_S16_LE; - if (strcmp (format, "S16BE") == 0) - return SND_PCM_FORMAT_S16_BE; - if (strcmp (format, "U16LE") == 0) - return SND_PCM_FORMAT_U16_LE; - if (strcmp (format, "U16BE") == 0) - return SND_PCM_FORMAT_U16_BE; - /* 24 bit in low 3 bytes of 32 bits */ - if (strcmp (format, "S24_32LE") == 0) - return SND_PCM_FORMAT_S24_LE; - if (strcmp (format, "S24_32BE") == 0) - return SND_PCM_FORMAT_S24_BE; - if (strcmp (format, "U24_32LE") == 0) - return SND_PCM_FORMAT_U24_LE; - if (strcmp (format, "U24_32BE") == 0) - return SND_PCM_FORMAT_U24_BE; - /* 24 bit in 3 bytes */ - if (strcmp (format, "S24LE") == 0) - return SND_PCM_FORMAT_S24_3LE; - if (strcmp (format, "S24BE") == 0) - return SND_PCM_FORMAT_S24_3BE; - if (strcmp (format, "U24LE") == 0) - return SND_PCM_FORMAT_U24_3LE; - if (strcmp (format, "U24BE") == 0) - return SND_PCM_FORMAT_U24_3BE; - /* 32 bit */ - if (strcmp (format, "S32LE") == 0) - return SND_PCM_FORMAT_S32_LE; - if (strcmp (format, "S32BE") == 0) - return SND_PCM_FORMAT_S32_BE; - if (strcmp (format, "U32LE") == 0) - return SND_PCM_FORMAT_U32_LE; - if (strcmp (format, "U32BE") == 0) - return SND_PCM_FORMAT_U32_BE; - - return SND_PCM_FORMAT_UNKNOWN; -} - -static int -set_hwparams (SpiALSASink *this) -{ - unsigned int rrate; - snd_pcm_uframes_t size; - int err, dir; - snd_pcm_hw_params_t *params; - snd_pcm_format_t format; - SpiALSAState *state = &this->state; - SpiALSASinkFormat *fmt = &this->current_format; - snd_pcm_t *handle = state->handle; - unsigned int buffer_time; - unsigned int period_time; - - snd_pcm_hw_params_alloca (¶ms); - /* choose all parameters */ - CHECK (snd_pcm_hw_params_any (handle, params), "Broken configuration for playback: no configurations available"); - /* set hardware resampling */ - CHECK (snd_pcm_hw_params_set_rate_resample (handle, params, 0), "set_rate_resample"); - /* set the interleaved read/write format */ - CHECK (snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_MMAP_INTERLEAVED), "set_access"); - - /* set the sample format */ - format = spi_alsa_format_to_alsa (fmt->format); - printf ("Stream parameters are %iHz, %s, %i channels\n", fmt->samplerate, snd_pcm_format_name(format), fmt->channels); - CHECK (snd_pcm_hw_params_set_format (handle, params, format), "set_format"); - /* set the count of channels */ - CHECK (snd_pcm_hw_params_set_channels (handle, params, fmt->channels), "set_channels"); - /* set the stream rate */ - rrate = fmt->samplerate; - CHECK (snd_pcm_hw_params_set_rate_near (handle, params, &rrate, 0), "set_rate_near"); - if (rrate != fmt->samplerate) { - printf("Rate doesn't match (requested %iHz, get %iHz)\n", fmt->samplerate, rrate); - return -EINVAL; - } - /* set the buffer time */ - buffer_time = this->params.buffer_time; - CHECK (snd_pcm_hw_params_set_buffer_time_near (handle, params, &buffer_time, &dir), "set_buffer_time_near"); - CHECK (snd_pcm_hw_params_get_buffer_size (params, &size), "get_buffer_size"); - state->buffer_size = size; - - /* set the period time */ - period_time = this->params.period_time; - CHECK (snd_pcm_hw_params_set_period_time_near (handle, params, &period_time, &dir), "set_period_time_near"); - CHECK (snd_pcm_hw_params_get_period_size (params, &size, &dir), "get_period_size"); - state->period_size = size; - - /* write the parameters to device */ - CHECK (snd_pcm_hw_params (handle, params), "set_hw_params"); - - return 0; -} - -static int -set_swparams (SpiALSASink *this) -{ - SpiALSAState *state = &this->state; - snd_pcm_t *handle = state->handle; - int err = 0; - snd_pcm_sw_params_t *params; - - snd_pcm_sw_params_alloca (¶ms); - - /* get the current params */ - CHECK (snd_pcm_sw_params_current (handle, params), "sw_params_current"); - /* start the transfer when the buffer is almost full: */ - /* (buffer_size / avail_min) * avail_min */ - CHECK (snd_pcm_sw_params_set_start_threshold (handle, params, - (state->buffer_size / state->period_size) * state->period_size), "set_start_threshold"); - - /* allow the transfer when at least period_size samples can be processed */ - /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */ - CHECK (snd_pcm_sw_params_set_avail_min (handle, params, - this->params.period_event ? state->buffer_size : state->period_size), "set_avail_min"); - /* enable period events when requested */ - if (this->params.period_event) { - CHECK (snd_pcm_sw_params_set_period_event (handle, params, 1), "set_period_event"); - } - /* write the parameters to the playback device */ - CHECK (snd_pcm_sw_params (handle, params), "sw_params"); - - return 0; -} - -/* - * Underrun and suspend recovery - */ -static int -xrun_recovery (snd_pcm_t *handle, int err) -{ - if (verbose) - printf("stream recovery\n"); - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); - return 0; - } else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(handle)) == -EAGAIN) - sleep(1); /* wait until the suspend flag is released */ - if (err < 0) { - err = snd_pcm_prepare(handle); - if (err < 0) - printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); - } - return 0; - } - return err; -} - -/* - * Transfer method - direct write only - */ -static void * -direct_loop (void *user_data) -{ - SpiALSASink *this = user_data; - SpiALSAState *state = &this->state; - snd_pcm_t *handle = state->handle; - const snd_pcm_channel_area_t *my_areas; - snd_pcm_uframes_t offset, frames, size; - snd_pcm_sframes_t avail, commitres; - snd_pcm_state_t st; - int err, first = 1; - - while (state->running) { - st = snd_pcm_state(handle); - if (st == SND_PCM_STATE_XRUN) { - err = xrun_recovery(handle, -EPIPE); - if (err < 0) { - printf("XRUN recovery failed: %s\n", snd_strerror(err)); - return NULL; - } - first = 1; - } else if (st == SND_PCM_STATE_SUSPENDED) { - err = xrun_recovery(handle, -ESTRPIPE); - if (err < 0) { - printf("SUSPEND recovery failed: %s\n", snd_strerror(err)); - return NULL; - } - } - avail = snd_pcm_avail_update(handle); - if (avail < 0) { - err = xrun_recovery(handle, avail); - if (err < 0) { - printf("avail update failed: %s\n", snd_strerror(err)); - return NULL; - } - first = 1; - continue; - } - if (avail < state->period_size) { - if (first) { - first = 0; - err = snd_pcm_start(handle); - if (err < 0) { - printf("Start error: %s\n", snd_strerror(err)); - exit(EXIT_FAILURE); - } - } else { - err = snd_pcm_wait(handle, -1); - if (err < 0) { - if ((err = xrun_recovery(handle, err)) < 0) { - printf("snd_pcm_wait error: %s\n", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - } - continue; - } - size = state->period_size; - while (size > 0) { - frames = size; - err = snd_pcm_mmap_begin(handle, &my_areas, &offset, &frames); - if (err < 0) { - if ((err = xrun_recovery(handle, err)) < 0) { - printf("MMAP begin avail error: %s\n", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - - { - SpiEvent event; - ALSABuffer *buffer = &this->buffer; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_PULL_INPUT; - event.port_id = 0; - event.data = buffer; - - buffer->buffer.refcount = 1; - buffer->buffer.notify = NULL; - buffer->buffer.size = sizeof (ALSABuffer); - buffer->buffer.n_metas = 1; - buffer->buffer.metas = buffer->meta; - buffer->buffer.n_datas = 1; - buffer->buffer.datas = buffer->data; - - buffer->header.flags = 0; - buffer->header.seq = 0; - buffer->header.pts = 0; - buffer->header.dts_offset = 0; - - buffer->meta[0].type = SPI_META_TYPE_HEADER; - buffer->meta[0].data = &buffer->header; - buffer->meta[0].size = sizeof (buffer->header); - - buffer->data[0].type = SPI_DATA_TYPE_MEMPTR; - buffer->data[0].data = (uint8_t *)my_areas[0].addr + (offset * sizeof (uint16_t) * 2); - buffer->data[0].size = frames * sizeof (uint16_t) * 2; - - this->event_cb (&this->handle, &event,this->user_data); - - spi_buffer_unref ((SpiBuffer *)event.data); - } - if (this->input_buffer) { - if (this->input_buffer != &this->buffer.buffer) { - /* FIXME, copy input */ - } - spi_buffer_unref (this->input_buffer); - this->input_buffer = NULL; - } - - commitres = snd_pcm_mmap_commit(handle, offset, frames); - if (commitres < 0 || (snd_pcm_uframes_t)commitres != frames) { - if ((err = xrun_recovery(handle, commitres >= 0 ? -EPIPE : commitres)) < 0) { - printf("MMAP commit error: %s\n", snd_strerror(err)); - exit(EXIT_FAILURE); - } - first = 1; - } - size -= frames; - } - } - return NULL; -} - -static int -spi_alsa_open (SpiALSASink *this) -{ - SpiALSAState *state = &this->state; - int err; - - CHECK (snd_output_stdio_attach (&state->output, stdout, 0), "attach failed"); - - printf ("Playback device is '%s'\n", this->params.device); - CHECK (snd_pcm_open (&state->handle, - this->params.device, - SND_PCM_STREAM_PLAYBACK, - SND_PCM_NONBLOCK | - SND_PCM_NO_AUTO_RESAMPLE | - SND_PCM_NO_AUTO_CHANNELS | - SND_PCM_NO_AUTO_FORMAT), "open failed"); - - return 0; -} - -static int -spi_alsa_start (SpiALSASink *this) -{ - SpiALSAState *state = &this->state; - int err; - - CHECK (set_hwparams (this), "hwparams"); - CHECK (set_swparams (this), "swparams"); - - snd_pcm_dump (this->state.handle, this->state.output); - - state->running = true; - if ((err = pthread_create (&state->thread, NULL, direct_loop, this)) != 0) { - printf ("can't create thread: %d", err); - state->running = false; - } - return err; -} - -static int -spi_alsa_stop (SpiALSASink *this) -{ - SpiALSAState *state = &this->state; - - if (state->running) { - state->running = false; - pthread_join (state->thread, NULL); - } - return 0; -} - -static int -spi_alsa_close (SpiALSASink *this) -{ - SpiALSAState *state = &this->state; - int err = 0; - - CHECK (snd_pcm_close (state->handle), "close failed"); - - return err; -} diff --git a/pinos/tests/spi-alsa-sink.c b/pinos/tests/spi-alsa-sink.c deleted file mode 100644 index 2c56bea92..000000000 --- a/pinos/tests/spi-alsa-sink.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* Spi ALSA Sink - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include - -#include "spi-plugins.h" - -typedef struct _SpiALSASink SpiALSASink; - - -static const char default_device[] = "default"; -static const uint32_t default_buffer_time = 10000; -static const uint32_t default_period_time = 5000; -static const bool default_period_event = 0; - -typedef struct { - SpiParams param; - char device[64]; - char device_name[128]; - char card_name[128]; - uint32_t buffer_time; - uint32_t period_time; - bool period_event; -} SpiALSASinkParams; - -static void -reset_alsa_sink_params (SpiALSASinkParams *params) -{ - strncpy (params->device, default_device, 64); - params->buffer_time = default_buffer_time; - params->period_time = default_period_time; - params->period_event = default_period_event; -} - -typedef struct { - SpiParams param; - char media_type[32]; - uint32_t unset_mask; - char format[16]; - uint32_t layout; - uint32_t samplerate; - uint32_t channels; - uint32_t position[16]; - uint32_t mpegversion; - uint32_t mpegaudioversion; - bool parsed; -} SpiALSASinkFormat; - -typedef struct { - snd_pcm_t *handle; - snd_output_t *output; - snd_pcm_sframes_t buffer_size; - snd_pcm_sframes_t period_size; - snd_pcm_channel_area_t areas[16]; - pthread_t thread; - bool running; -} SpiALSAState; - - -typedef struct _ALSABuffer ALSABuffer; - -struct _ALSABuffer { - SpiBuffer buffer; - SpiMeta meta[1]; - SpiMetaHeader header; - SpiData data[1]; - ALSABuffer *next; -}; - -struct _SpiALSASink { - SpiHandle handle; - SpiNode node; - - SpiALSASinkParams params; - - bool activated; - - SpiEventCallback event_cb; - void *user_data; - - int have_format; - SpiALSASinkFormat current_format; - - SpiALSAState state; - - SpiBuffer *input_buffer; - - ALSABuffer buffer; -}; - -#include "alsa-utils.c" - -static const uint32_t default_samplerate = 44100; -static const uint32_t min_samplerate = 1; -static const uint32_t max_samplerate = UINT32_MAX; - -static const SpiParamRangeInfo int32_range[] = { - { "min", "Minimum value", 4, &min_samplerate }, - { "max", "Maximum value", 4, &max_samplerate }, - { NULL, NULL, 0, NULL } -}; - -enum { - PARAM_ID_DEVICE, - PARAM_ID_DEVICE_NAME, - PARAM_ID_CARD_NAME, - PARAM_ID_BUFFER_TIME, - PARAM_ID_PERIOD_TIME, - PARAM_ID_PERIOD_EVENT, - PARAM_ID_LAST, -}; - -static const SpiParamInfo param_info[] = -{ - { PARAM_ID_DEVICE, "device", "ALSA device, as defined in an asound configuration file", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_STRING, 63, - strlen (default_device)+1, default_device, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { PARAM_ID_DEVICE_NAME, "device-name", "Human-readable name of the sound device", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 127, - 0, NULL, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { PARAM_ID_CARD_NAME, "card-name", "Human-readable name of the sound card", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 127, - 0, NULL, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { PARAM_ID_BUFFER_TIME, "buffer-time", "The total size of the buffer in time", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &default_buffer_time, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, - { PARAM_ID_PERIOD_TIME, "period-time", "The size of a period in time", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &default_period_time, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, - { PARAM_ID_PERIOD_EVENT, "period-event", "Generate an event each period", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_BOOL, sizeof (bool), - sizeof (bool), &default_period_event, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, -}; - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define CHECK_SIZE(size,expected) if (size != expected) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_RANGE(size,minsize,maxsize) if (size > maxsize || size < minsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_MAX(size,maxsize) if (size > maxsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_UNSET(mask,index) if (mask & (1 << index)) return SPI_RESULT_PARAM_UNSET; - -static SpiResult -enum_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= PARAM_ID_LAST) - return SPI_RESULT_ENUM_END; - *info = ¶m_info[index]; - return SPI_RESULT_OK; -} - -static SpiResult -set_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiResult res = SPI_RESULT_OK; - SpiALSASinkParams *p = (SpiALSASinkParams *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_DEVICE: - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 64); - strncpy (p->device, value, 64); - break; - case PARAM_ID_BUFFER_TIME: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->buffer_time, value, size); - break; - case PARAM_ID_PERIOD_TIME: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->period_time, value, size); - break; - case PARAM_ID_PERIOD_EVENT: - CHECK_TYPE (type, SPI_PARAM_TYPE_BOOL); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->period_event, value, size); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - -static SpiResult -get_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiResult res = SPI_RESULT_OK; - SpiALSASinkParams *p = (SpiALSASinkParams *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_DEVICE: - *type = SPI_PARAM_TYPE_STRING; - *value = p->device; - *size = strlen (p->device)+1; - break; - case PARAM_ID_DEVICE_NAME: - *type = SPI_PARAM_TYPE_STRING; - *value = p->device_name; - *size = strlen (p->device_name)+1; - break; - case PARAM_ID_CARD_NAME: - *type = SPI_PARAM_TYPE_STRING; - *value = p->card_name; - *size = strlen (p->card_name)+1; - break; - case PARAM_ID_BUFFER_TIME: - *type = SPI_PARAM_TYPE_UINT32; - *value = &p->buffer_time; - *size = sizeof (uint32_t); - break; - case PARAM_ID_PERIOD_TIME: - *type = SPI_PARAM_TYPE_UINT32; - *value = &p->period_time; - *size = sizeof (uint32_t); - break; - case PARAM_ID_PERIOD_EVENT: - *type = SPI_PARAM_TYPE_BOOL; - *value = &p->period_event; - *size = sizeof (bool); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - - -static SpiResult -spi_alsa_sink_node_get_params (SpiHandle *node, - SpiParams **params) -{ - static SpiALSASinkParams p; - SpiALSASink *this = (SpiALSASink *) node; - - if (node == NULL || params == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - memcpy (&p, &this->params, sizeof (p)); - *params = &p.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_set_params (SpiHandle *node, - const SpiParams *params) -{ - SpiALSASink *this = (SpiALSASink *) node; - SpiALSASinkParams *p = &this->params; - SpiParamType type; - size_t size; - const void *value; - - if (node == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (params == NULL) { - reset_alsa_sink_params (p); - return SPI_RESULT_OK; - } - - if (params->get_param (params, PARAM_ID_DEVICE, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 64); - strncpy (p->device, value, 64); - } - if (params->get_param (params, PARAM_ID_BUFFER_TIME, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->buffer_time, value, size); - } - if (params->get_param (params, PARAM_ID_PERIOD_TIME, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->period_time, value, size); - } - if (params->get_param (params, PARAM_ID_PERIOD_EVENT, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_BOOL); - CHECK_SIZE (size, sizeof (bool)); - memcpy (&p->period_event, value, size); - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_send_command (SpiHandle *node, - SpiCommand *command) -{ - SpiALSASink *this = (SpiALSASink *) node; - - if (node == NULL || command == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (command->type) { - case SPI_COMMAND_INVALID: - return SPI_RESULT_INVALID_COMMAND; - - case SPI_COMMAND_ACTIVATE: - if (!this->activated) { - spi_alsa_open (this); - this->activated = true; - } - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_ACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (node, &event, this->user_data); - } - break; - case SPI_COMMAND_DEACTIVATE: - if (this->activated) { - spi_alsa_close (this); - this->activated = false; - } - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_DEACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (node, &event, this->user_data); - } - break; - case SPI_COMMAND_START: - spi_alsa_start (this); - break; - case SPI_COMMAND_STOP: - spi_alsa_stop (this); - break; - case SPI_COMMAND_FLUSH: - case SPI_COMMAND_DRAIN: - case SPI_COMMAND_MARKER: - return SPI_RESULT_NOT_IMPLEMENTED; - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_set_event_callback (SpiHandle *node, - SpiEventCallback event, - void *user_data) -{ - SpiALSASink *this = (SpiALSASink *) node; - - if (node == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - this->event_cb = event; - this->user_data = user_data; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_get_n_ports (SpiHandle *node, - unsigned int *n_input_ports, - unsigned int *max_input_ports, - unsigned int *n_output_ports, - unsigned int *max_output_ports) -{ - if (node == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_input_ports) - *n_input_ports = 1; - if (n_output_ports) - *n_output_ports = 0; - if (max_input_ports) - *max_input_ports = 1; - if (max_output_ports) - *max_output_ports = 0; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_get_port_ids (SpiHandle *node, - unsigned int n_input_ports, - uint32_t *input_ids, - unsigned int n_output_ports, - uint32_t *output_ids) -{ - if (node == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_input_ports > 0) - input_ids[0] = 0; - - return SPI_RESULT_OK; -} - - -static SpiResult -spi_alsa_sink_node_add_port (SpiHandle *node, - SpiDirection direction, - uint32_t *port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_alsa_sink_node_remove_port (SpiHandle *node, - uint32_t port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static const SpiParamRangeInfo format_format_range[] = { - { "S8", "S8", 2, "S8" }, - { "U8", "U8", 2, "U8" }, - { "S16LE", "S16LE", 5, "S16LE" }, - { "S16BE", "S16BE", 5, "S16BE" }, - { "U16LE", "U16LE", 5, "U16LE" }, - { "U16BE", "U16BE", 5, "U16BE" }, - { "S24_32LE", "S24_32LE", 8, "S24_32LE" }, - { "S24_32BE", "S24_32BE", 8, "S24_32BE" }, - { "U24_32LE", "U24_32LE", 8, "U24_32LE" }, - { "U24_32BE", "U24_32BE", 8, "U24_32BE" }, - { "S32LE", "S32LE", 5, "S32LE" }, - { "S32BE", "S32BE", 5, "S32BE" }, - { "U32LE", "U32LE", 5, "U32LE" }, - { "U32BE", "U32BE", 5, "U32BE" }, - { "S24LE", "S24LE", 5, "S24LE" }, - { "S24BE", "S24BE", 5, "S24BE" }, - { "U24LE", "U24LE", 5, "U24LE" }, - { "U24BE", "U24BE", 5, "U24BE" }, - { "S20LE", "S20LE", 5, "S20LE" }, - { "S20BE", "S20BE", 5, "S20BE" }, - { "U20LE", "U20LE", 5, "U20LE" }, - { "U20BE", "U20BE", 5, "U20BE" }, - { "S18LE", "S18LE", 5, "S18LE" }, - { "S18BE", "S18BE", 5, "S18BE" }, - { "U18LE", "U18LE", 5, "U18LE" }, - { "U18BE", "U18BE", 5, "U18BE" }, - { "F32LE", "F32LE", 5, "F32LE" }, - { "F32BE", "F32BE", 5, "F32BE" }, - { "F64LE", "F64LE", 5, "F64LE" }, - { "F64BE", "F64BE", 5, "F64BE" }, - { NULL, NULL, 0, NULL } -}; - -enum { - SPI_PARAM_ID_MEDIA_TYPE, - SPI_PARAM_ID_FORMAT, - SPI_PARAM_ID_LAYOUT, - SPI_PARAM_ID_SAMPLERATE, - SPI_PARAM_ID_CHANNELS, - SPI_PARAM_ID_MPEG_VERSION, - SPI_PARAM_ID_MPEG_AUDIO_VERSION, - SPI_PARAM_ID_PARSED, -}; - -static const int32_t format_default_layout = 1; - -static const SpiParamInfo raw_format_param_info[] = -{ - { SPI_PARAM_ID_MEDIA_TYPE, "media-type", "The media type", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 32, - strlen ("audio/x-raw")+1, "audio/x-raw", - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_FORMAT, "format", "The media format", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_STRING, 16, - 0, NULL, - SPI_PARAM_RANGE_TYPE_ENUM, format_format_range, - NULL, - NULL }, - { SPI_PARAM_ID_LAYOUT, "layout", "Sample Layout", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &format_default_layout, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_SAMPLERATE, "rate", "Audio sample rate", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, - { SPI_PARAM_ID_CHANNELS, "channels", "Audio channels", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, -}; - -static SpiResult -enum_raw_format_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= 5) - return SPI_RESULT_ENUM_END; - *info = &raw_format_param_info[index]; - return SPI_RESULT_OK; -} - -static const uint32_t default_mpeg_version = 1; -static const uint32_t min_mpeg_audio_version = 1; -static const uint32_t max_mpeg_audio_version = 2; -static const bool default_parsed = 1; - -static const SpiParamRangeInfo mpeg_audio_version_range[] = { - { "min", "Minimum value", 4, &min_mpeg_audio_version }, - { "max", "Maximum value", 4, &max_mpeg_audio_version }, - { NULL, NULL, 0, NULL } -}; - -static const SpiParamInfo mpeg_format_param_info[] = -{ - { SPI_PARAM_ID_MEDIA_TYPE, "media-type", "The media type", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 32, - strlen ("audio/mpeg")+1, "audio/mpeg", - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_MPEG_VERSION, "mpegversion", "The MPEG version", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &default_mpeg_version, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_MPEG_AUDIO_VERSION, "mpegaudioversion", "The MPEG audio version", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, mpeg_audio_version_range, - NULL, - NULL }, - { SPI_PARAM_ID_PARSED, "parsed", "Parsed input", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_BOOL, sizeof (bool), - sizeof (bool), &default_parsed, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, -}; - -static SpiResult -enum_mpeg_format_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= 4) - return SPI_RESULT_ENUM_END; - *info = &mpeg_format_param_info[index]; - return SPI_RESULT_OK; -} - - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define MARK_SET(mask,index) (mask &= ~(1 << index)) - -static SpiResult -set_format_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiALSASinkFormat *f = (SpiALSASinkFormat *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_FORMAT: - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - strncpy (f->format, value, 16); - MARK_SET (f->unset_mask, 1); - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->layout, value, size); - MARK_SET (f->unset_mask, 2); - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->samplerate, value, size); - MARK_SET (f->unset_mask, 3); - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->channels, value, size); - MARK_SET (f->unset_mask, 4); - break; - case SPI_PARAM_ID_MPEG_AUDIO_VERSION: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->mpegaudioversion, value, size); - MARK_SET (f->unset_mask, 6); - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - - return SPI_RESULT_OK; -} - -static SpiResult -get_format_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiALSASinkFormat *f = (SpiALSASinkFormat *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_MEDIA_TYPE: - CHECK_UNSET (f->unset_mask, 0); - *type = SPI_PARAM_TYPE_STRING; - *value = f->media_type; - *size = strlen (f->media_type)+1; - break; - case SPI_PARAM_ID_FORMAT: - CHECK_UNSET (f->unset_mask, 1); - *type = SPI_PARAM_TYPE_STRING; - *value = f->format; - *size = strlen (f->format)+1; - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_UNSET (f->unset_mask, 2); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->layout; - *size = sizeof (uint32_t); - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_UNSET (f->unset_mask, 3); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->samplerate; - *size = sizeof (uint32_t); - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_UNSET (f->unset_mask, 4); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->channels; - *size = sizeof (uint32_t); - break; - case SPI_PARAM_ID_MPEG_VERSION: - CHECK_UNSET (f->unset_mask, 5); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->mpegversion; - *size = sizeof (uint32_t); - break; - case SPI_PARAM_ID_MPEG_AUDIO_VERSION: - CHECK_UNSET (f->unset_mask, 6); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->mpegaudioversion; - *size = sizeof (uint32_t); - break; - case SPI_PARAM_ID_PARSED: - CHECK_UNSET (f->unset_mask, 7); - *type = SPI_PARAM_TYPE_BOOL; - *value = &f->parsed; - *size = sizeof (bool); - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - return SPI_RESULT_OK; -} - - -static SpiResult -spi_alsa_sink_node_enum_port_formats (SpiHandle *node, - uint32_t port_id, - unsigned int index, - SpiParams **format) -{ - static SpiALSASinkFormat fmt; - - if (node == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - switch (index) { - case 0: - strcpy (fmt.media_type, "audio/x-raw"); - fmt.unset_mask = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4); - fmt.param.enum_param_info = enum_raw_format_param_info; - fmt.param.set_param = set_format_param; - fmt.param.get_param = get_format_param; - break; - case 1: - strcpy (fmt.media_type, "audio/mpeg"); - fmt.mpegversion = 1; - fmt.parsed = 1; - fmt.unset_mask = (1 << 6); - fmt.param.enum_param_info = enum_mpeg_format_param_info; - fmt.param.set_param = set_format_param; - fmt.param.get_param = get_format_param; - break; - default: - return SPI_RESULT_ENUM_END; - } - *format = &fmt.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_set_port_format (SpiHandle *node, - uint32_t port_id, - int test_only, - const SpiParams *format) -{ - SpiALSASink *this = (SpiALSASink *) node; - SpiParamType type; - size_t size; - const void *value; - SpiALSASinkFormat *fmt; - - if (node == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - fmt = &this->current_format; - - if (format == NULL) { - fmt->param.get_param = NULL; - this->have_format = 0; - return SPI_RESULT_OK; - } - - if (format->get_param (format, - SPI_PARAM_ID_MEDIA_TYPE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_MEDIA_TYPE; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 32); - strncpy (fmt->media_type, value, 32); - - if (format->get_param (format, - SPI_PARAM_ID_FORMAT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - strncpy (fmt->format, value, 16); - - if (format->get_param (format, - SPI_PARAM_ID_LAYOUT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->layout, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_SAMPLERATE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->samplerate, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_CHANNELS, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->channels, value, size); - - fmt->param.enum_param_info = enum_raw_format_param_info; - fmt->param.set_param = NULL; - fmt->param.get_param = get_format_param; - this->have_format = 1; - - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_get_port_format (SpiHandle *node, - uint32_t port_id, - const SpiParams **format) -{ - SpiALSASink *this = (SpiALSASink *) node; - - if (node == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - *format = &this->current_format.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_get_port_info (SpiHandle *node, - uint32_t port_id, - SpiPortInfo *info) -{ - if (node == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - info->flags = SPI_PORT_INFO_FLAG_NONE; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_get_port_params (SpiHandle *node, - uint32_t port_id, - SpiParams **params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_alsa_sink_node_set_port_params (SpiHandle *node, - uint32_t port_id, - const SpiParams *params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_alsa_sink_node_get_port_status (SpiHandle *node, - uint32_t port_id, - SpiPortStatus *status) -{ - if (node == NULL || status == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - status->flags = SPI_PORT_STATUS_FLAG_NEED_INPUT; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_push_port_input (SpiHandle *node, - unsigned int n_info, - SpiInputInfo *info) -{ - SpiALSASink *this = (SpiALSASink *) node; - unsigned int i; - bool have_error = false, have_enough = false; - - if (node == NULL || n_info == 0 || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - for (i = 0; i < n_info; i++) { - if (info[i].port_id != 0) { - info[i].status = SPI_RESULT_INVALID_PORT; - have_error = true; - continue; - } - - if (info[i].buffer != NULL) { - if (!this->have_format) { - info[i].status = SPI_RESULT_NO_FORMAT; - have_error = true; - continue; - } - - if (this->input_buffer != NULL) { - info[i].status = SPI_RESULT_HAVE_ENOUGH_INPUT; - have_enough = true; - continue; - } - this->input_buffer = spi_buffer_ref (info[i].buffer); - } - info[i].status = SPI_RESULT_OK; - } - if (have_error) - return SPI_RESULT_ERROR; - if (have_enough) - return SPI_RESULT_HAVE_ENOUGH_INPUT; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_alsa_sink_node_pull_port_output (SpiHandle *node, - unsigned int n_info, - SpiOutputInfo *info) -{ - return SPI_RESULT_INVALID_PORT; -} - -static SpiResult -spi_alsa_sink_get_interface (SpiHandle *handle, - uint32_t interface_id, - void **interface) -{ - SpiALSASink *this = (SpiALSASink *) handle; - - if (handle == NULL || interface == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (interface_id) { - case SPI_INTERFACE_ID_NODE: - *interface = &this->node; - break; - default: - return SPI_RESULT_UNKNOWN_INTERFACE; - } - return SPI_RESULT_OK; -} - - -SpiHandle * -spi_alsa_sink_new (void) -{ - SpiHandle *handle; - SpiNode *node; - SpiALSASink *this; - - handle = calloc (1, sizeof (SpiALSASink)); - handle->get_interface = spi_alsa_sink_get_interface; - - this = (SpiALSASink *) handle; - this->params.param.enum_param_info = enum_param_info; - this->params.param.set_param = set_param; - this->params.param.get_param = get_param; - reset_alsa_sink_params (&this->params); - - node = &this->node; - node->get_params = spi_alsa_sink_node_get_params; - node->set_params = spi_alsa_sink_node_set_params; - node->send_command = spi_alsa_sink_node_send_command; - node->set_event_callback = spi_alsa_sink_node_set_event_callback; - node->get_n_ports = spi_alsa_sink_node_get_n_ports; - node->get_port_ids = spi_alsa_sink_node_get_port_ids; - node->add_port = spi_alsa_sink_node_add_port; - node->remove_port = spi_alsa_sink_node_remove_port; - node->enum_port_formats = spi_alsa_sink_node_enum_port_formats; - node->set_port_format = spi_alsa_sink_node_set_port_format; - node->get_port_format = spi_alsa_sink_node_get_port_format; - node->get_port_info = spi_alsa_sink_node_get_port_info; - node->get_port_params = spi_alsa_sink_node_get_port_params; - node->set_port_params = spi_alsa_sink_node_set_port_params; - node->get_port_status = spi_alsa_sink_node_get_port_status; - node->push_port_input = spi_alsa_sink_node_push_port_input; - node->pull_port_output = spi_alsa_sink_node_pull_port_output; - - return handle; -} diff --git a/pinos/tests/spi-audiotestsrc.c b/pinos/tests/spi-audiotestsrc.c deleted file mode 100644 index b27e30558..000000000 --- a/pinos/tests/spi-audiotestsrc.c +++ /dev/null @@ -1,894 +0,0 @@ -/* Spi - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include - -#include -#include "spi-plugins.h" - -typedef struct _SpiAudioTestSrc SpiAudioTestSrc; - -typedef struct { - SpiParams param; - uint32_t wave; - double freq; - double volume; -} SpiAudioTestSrcParams; - -typedef struct { - SpiParams param; - char media_type[32]; - uint32_t unset_mask; - char format[16]; - int32_t layout; - int32_t samplerate; - int32_t channels; - int32_t position[16]; -} SpiAudioTestSrcFormat; - -struct _SpiAudioTestSrc { - SpiHandle handle; - SpiNode node; - - SpiAudioTestSrcParams params; - SpiAudioTestSrcParams tmp_params; - - SpiEventCallback event_cb; - void *user_data; - - bool have_format; - SpiAudioTestSrcFormat current_format; - - bool have_input; - SpiBuffer *input_buffer; - - SpiData data; -}; - -static const uint32_t default_wave = 1.0; -static const double default_volume = 1.0; -static const double min_volume = 0.0; -static const double max_volume = 10.0; -static const double default_freq = 440.0; -static const double min_freq = 0.0; -static const double max_freq = 50000000.0; - -static const SpiParamRangeInfo volume_range[] = { - { "min", "Minimum value", sizeof (double), &min_volume }, - { "max", "Maximum value", sizeof (double), &max_volume }, - { NULL, NULL, 0, NULL } -}; - -static const uint32_t wave_val_sine = 0; -static const uint32_t wave_val_square = 1; - -static const SpiParamRangeInfo wave_range[] = { - { "sine", "Sine", sizeof (uint32_t), &wave_val_sine }, - { "square", "Square", sizeof (uint32_t), &wave_val_square }, - { NULL, NULL, 0, NULL } -}; - -static const SpiParamRangeInfo freq_range[] = { - { "min", "Minimum value", sizeof (double), &min_freq }, - { "max", "Maximum value", sizeof (double), &max_freq }, - { NULL, NULL, 0, NULL } -}; - -enum { - PARAM_ID_WAVE, - PARAM_ID_FREQ, - PARAM_ID_VOLUME, - PARAM_ID_LAST, -}; - -static const SpiParamInfo param_info[] = -{ - { PARAM_ID_WAVE, "wave", "Oscillator waveform", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &default_wave, - SPI_PARAM_RANGE_TYPE_ENUM, wave_range, - NULL, - NULL }, - { PARAM_ID_FREQ, "freq", "Frequency of test signal. The sample rate needs to be at least 4 times higher", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_DOUBLE, sizeof (double), - sizeof (double), &default_freq, - SPI_PARAM_RANGE_TYPE_MIN_MAX, freq_range, - NULL, - NULL }, - { PARAM_ID_VOLUME, "volume", "The Volume factor", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_DOUBLE, sizeof (double), - sizeof (double), &default_volume, - SPI_PARAM_RANGE_TYPE_MIN_MAX, volume_range, - NULL, - NULL }, -}; - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define CHECK_SIZE(size,expected) if (size != expected) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_RANGE(size,minsize,maxsize) if (size > maxsize || size < minsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_MAX(size,maxsize) if (size > maxsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_UNSET(mask,index) if (mask & (1 << index)) return SPI_RESULT_PARAM_UNSET; - -static SpiResult -enum_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (index >= PARAM_ID_LAST) - return SPI_RESULT_ENUM_END; - *info = ¶m_info[index]; - return SPI_RESULT_OK; -} - -static SpiResult -set_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiResult res = SPI_RESULT_OK; - SpiAudioTestSrcParams *p = (SpiAudioTestSrcParams *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_WAVE: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->wave, value, size); - break; - case PARAM_ID_FREQ: - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->freq, value, size); - break; - case PARAM_ID_VOLUME: - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->volume, value, size); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - -static SpiResult -get_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiResult res = SPI_RESULT_OK; - SpiAudioTestSrcParams *p = (SpiAudioTestSrcParams *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_WAVE: - *type = SPI_PARAM_TYPE_UINT32; - *value = &p->wave; - *size = sizeof (uint32_t); - break; - case PARAM_ID_FREQ: - *type = SPI_PARAM_TYPE_DOUBLE; - *value = &p->freq; - *size = sizeof (double); - break; - case PARAM_ID_VOLUME: - *type = SPI_PARAM_TYPE_DOUBLE; - *value = &p->volume; - *size = sizeof (double); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - -static void -reset_audiotestsrc_params (SpiAudioTestSrcParams *params) -{ - params->wave = default_wave; - params->freq = default_freq; - params->volume = default_volume; -} - -static SpiResult -spi_audiotestsrc_node_get_params (SpiHandle *handle, - SpiParams **params) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL || params == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - memcpy (&this->tmp_params, &this->params, sizeof (this->tmp_params)); - *params = &this->tmp_params.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_set_params (SpiHandle *handle, - const SpiParams *params) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - SpiAudioTestSrcParams *p = &this->params; - SpiParamType type; - size_t size; - const void *value; - - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (params == NULL) { - reset_audiotestsrc_params (p); - return SPI_RESULT_OK; - } - - if (params->get_param (params, PARAM_ID_WAVE, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&p->wave, value, size); - } - if (params->get_param (params, PARAM_ID_FREQ, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->freq, value, size); - } - if (params->get_param (params, PARAM_ID_VOLUME, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->volume, value, size); - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_send_command (SpiHandle *handle, - SpiCommand *command) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL || command == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (command->type) { - case SPI_COMMAND_INVALID: - return SPI_RESULT_INVALID_COMMAND; - - case SPI_COMMAND_ACTIVATE: - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_ACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (handle, &event, this->user_data); - } - break; - - case SPI_COMMAND_DEACTIVATE: - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_DEACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (handle, &event, this->user_data); - } - break; - - case SPI_COMMAND_START: - case SPI_COMMAND_STOP: - case SPI_COMMAND_FLUSH: - case SPI_COMMAND_DRAIN: - case SPI_COMMAND_MARKER: - return SPI_RESULT_NOT_IMPLEMENTED; - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_set_event_callback (SpiHandle *handle, - SpiEventCallback event, - void *user_data) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - this->event_cb = event; - this->user_data = user_data; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_get_n_ports (SpiHandle *handle, - unsigned int *n_input_ports, - unsigned int *max_input_ports, - unsigned int *n_output_ports, - unsigned int *max_output_ports) -{ - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_input_ports) - *n_input_ports = 0; - if (n_output_ports) - *n_output_ports = 1; - if (max_input_ports) - *max_input_ports = 0; - if (max_output_ports) - *max_output_ports = 1; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_get_port_ids (SpiHandle *handle, - unsigned int n_input_ports, - uint32_t *input_ids, - unsigned int n_output_ports, - uint32_t *output_ids) -{ - if (handle == NULL || input_ids == NULL || output_ids == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_output_ports > 0) - output_ids[0] = 0; - - return SPI_RESULT_OK; -} - - -static SpiResult -spi_audiotestsrc_node_add_port (SpiHandle *handle, - SpiDirection direction, - uint32_t *port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_audiotestsrc_node_remove_port (SpiHandle *handle, - uint32_t port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static const SpiParamRangeInfo format_format_range[] = { - { "S8", "S8", 2, "S8" }, - { "U8", "U8", 2, "U8" }, - { "S16LE", "S16LE", 5, "S16LE" }, - { "S16BE", "S16BE", 5, "S16BE" }, - { "U16LE", "U16LE", 5, "U16LE" }, - { "U16BE", "U16BE", 5, "U16BE" }, - { "S24_32LE", "S24_32LE", 8, "S24_32LE" }, - { "S24_32BE", "S24_32BE", 8, "S24_32BE" }, - { "U24_32LE", "U24_32LE", 8, "U24_32LE" }, - { "U24_32BE", "U24_32BE", 8, "U24_32BE" }, - { "S32LE", "S32LE", 5, "S32LE" }, - { "S32BE", "S32BE", 5, "S32BE" }, - { "U32LE", "U32LE", 5, "U32LE" }, - { "U32BE", "U32BE", 5, "U32BE" }, - { "S24LE", "S24LE", 5, "S24LE" }, - { "S24BE", "S24BE", 5, "S24BE" }, - { "U24LE", "U24LE", 5, "U24LE" }, - { "U24BE", "U24BE", 5, "U24BE" }, - { "S20LE", "S20LE", 5, "S20LE" }, - { "S20BE", "S20BE", 5, "S20BE" }, - { "U20LE", "U20LE", 5, "U20LE" }, - { "U20BE", "U20BE", 5, "U20BE" }, - { "S18LE", "S18LE", 5, "S18LE" }, - { "S18BE", "S18BE", 5, "S18BE" }, - { "U18LE", "U18LE", 5, "U18LE" }, - { "U18BE", "U18BE", 5, "U18BE" }, - { "F32LE", "F32LE", 5, "F32LE" }, - { "F32BE", "F32BE", 5, "F32BE" }, - { "F64LE", "F64LE", 5, "F64LE" }, - { "F64BE", "F64BE", 5, "F64BE" }, - { NULL, NULL, 0, NULL } -}; - -static const uint32_t min_uint32 = 1; -static const uint32_t max_uint32 = UINT32_MAX; - -static const SpiParamRangeInfo uint32_range[] = { - { "min", "Minimum value", sizeof (uint32_t), &min_uint32 }, - { "max", "Maximum value", sizeof (uint32_t), &max_uint32 }, - { NULL, NULL, 0, NULL } -}; - -enum { - SPI_PARAM_ID_MEDIA_TYPE, - SPI_PARAM_ID_FORMAT, - SPI_PARAM_ID_LAYOUT, - SPI_PARAM_ID_SAMPLERATE, - SPI_PARAM_ID_CHANNELS, - SPI_PARAM_ID_LAST, -}; - -static const int32_t format_default_layout = 1; - -static const SpiParamInfo raw_format_param_info[] = -{ - { SPI_PARAM_ID_MEDIA_TYPE, "media-type", "The media type", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 32, - strlen ("audio/x-raw")+1, "audio/x-raw", - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_FORMAT, "format", "The media format", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_STRING, 16, - 0, NULL, - SPI_PARAM_RANGE_TYPE_ENUM, format_format_range, - NULL, - NULL }, - { SPI_PARAM_ID_LAYOUT, "layout", "Sample Layout", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &format_default_layout, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_SAMPLERATE, "rate", "Audio sample rate", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, uint32_range, - NULL, - NULL }, - { SPI_PARAM_ID_CHANNELS, "channels", "Audio channels", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, uint32_range, - NULL, - NULL }, -}; - -static SpiResult -enum_raw_format_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= SPI_PARAM_ID_LAST) - return SPI_RESULT_ENUM_END; - - *info = &raw_format_param_info[index]; - - return SPI_RESULT_OK; -} - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define MARK_SET(mask,index) (mask &= ~(1 << index)) - -static SpiResult -set_format_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiAudioTestSrcFormat *f = (SpiAudioTestSrcFormat *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_FORMAT: - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - memcpy (f->format, value, size); - MARK_SET (f->unset_mask, 1); - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->layout, value, size); - MARK_SET (f->unset_mask, 2); - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->samplerate, value, size); - MARK_SET (f->unset_mask, 3); - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->channels, value, size); - MARK_SET (f->unset_mask, 4); - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - - return SPI_RESULT_OK; -} - - - -static SpiResult -get_format_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiAudioTestSrcFormat *f = (SpiAudioTestSrcFormat *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_MEDIA_TYPE: - CHECK_UNSET (f->unset_mask, 0); - *type = SPI_PARAM_TYPE_STRING; - *value = f->media_type; - *size = strlen (f->media_type); - break; - case SPI_PARAM_ID_FORMAT: - CHECK_UNSET (f->unset_mask, 1); - *type = SPI_PARAM_TYPE_STRING; - *value = f->format; - *size = strlen (f->format); - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_UNSET (f->unset_mask, 2); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->layout; - *size = 4; - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_UNSET (f->unset_mask, 3); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->samplerate; - *size = 4; - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_UNSET (f->unset_mask, 4); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->channels; - *size = 4; - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - return SPI_RESULT_OK; -} - - -static SpiResult -spi_audiotestsrc_node_enum_port_formats (SpiHandle *handle, - uint32_t port_id, - unsigned int index, - SpiParams **format) -{ - static SpiAudioTestSrcFormat fmt; - - if (handle == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - switch (index) { - case 0: - strcpy (fmt.media_type, "audio/x-raw"); - fmt.unset_mask = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4); - fmt.param.enum_param_info = enum_raw_format_param_info; - fmt.param.set_param = set_format_param; - fmt.param.get_param = get_format_param; - break; - default: - return SPI_RESULT_ENUM_END; - } - *format = &fmt.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_set_port_format (SpiHandle *handle, - uint32_t port_id, - int test_only, - const SpiParams *format) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - SpiParamType type; - size_t size; - const void *value; - SpiAudioTestSrcFormat *fmt; - - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - fmt = &this->current_format; - - if (format == NULL) { - fmt->param.get_param = NULL; - this->have_format = false; - return SPI_RESULT_OK; - } - - if (format->get_param (format, - SPI_PARAM_ID_MEDIA_TYPE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_MEDIA_TYPE; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 32); - memcpy (fmt->media_type, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_FORMAT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - memcpy (fmt->format, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_LAYOUT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->layout, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_SAMPLERATE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->samplerate, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_CHANNELS, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->channels, value, size); - - fmt->param.enum_param_info = enum_raw_format_param_info; - fmt->param.set_param = NULL; - fmt->param.get_param = get_format_param; - this->have_format = true; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_get_port_format (SpiHandle *handle, - uint32_t port_id, - const SpiParams **format) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - *format = &this->current_format.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_get_port_info (SpiHandle *handle, - uint32_t port_id, - SpiPortInfo *info) -{ - if (handle == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - info->flags = SPI_PORT_INFO_FLAG_CAN_USE_BUFFER | - SPI_PORT_INFO_FLAG_NO_REF; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_get_port_params (SpiHandle *handle, - uint32_t port_id, - SpiParams **params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_audiotestsrc_node_set_port_params (SpiHandle *handle, - uint32_t port_id, - const SpiParams *params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_audiotestsrc_node_get_port_status (SpiHandle *handle, - uint32_t port_id, - SpiPortStatus *status) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL || status == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - status->flags = SPI_PORT_STATUS_FLAG_HAVE_OUTPUT; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_node_push_port_input (SpiHandle *handle, - unsigned int n_info, - SpiInputInfo *info) -{ - return SPI_RESULT_INVALID_PORT; -} - -static SpiResult -spi_audiotestsrc_node_pull_port_output (SpiHandle *handle, - unsigned int n_info, - SpiOutputInfo *info) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - size_t j, size; - uint8_t *ptr; - unsigned int i; - bool have_error = false; - - if (handle == NULL || n_info == 0 || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - for (i = 0; i < n_info; i++) { - if (info[i].port_id != 0) { - info[i].status = SPI_RESULT_INVALID_PORT; - have_error = true; - continue; - } - - if (!this->have_format) { - info[i].status = SPI_RESULT_NO_FORMAT; - have_error = true; - continue; - } - - if (info[i].buffer == NULL || info[i].buffer->n_datas == 0) { - info[i].status = SPI_RESULT_INVALID_ARGUMENTS; - have_error = true; - continue; - } - - ptr = info[i].buffer->datas[0].data; - size = info[i].buffer->datas[0].size; - - for (j = 0; j < size; j++) - ptr[j] = rand(); - - info[i].status = SPI_RESULT_OK; - } - if (have_error) - return SPI_RESULT_ERROR; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_audiotestsrc_get_interface (SpiHandle *handle, - uint32_t interface_id, - void **interface) -{ - SpiAudioTestSrc *this = (SpiAudioTestSrc *) handle; - - if (handle == NULL || interface == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (interface_id) { - case SPI_INTERFACE_ID_NODE: - *interface = &this->node; - break; - default: - return SPI_RESULT_UNKNOWN_INTERFACE; - } - return SPI_RESULT_NOT_IMPLEMENTED; -} - -SpiHandle * -spi_audiotestsrc_new (void) -{ - SpiHandle *handle; - SpiNode *node; - SpiAudioTestSrc *this; - - handle = calloc (1, sizeof (SpiAudioTestSrc)); - handle->get_interface = spi_audiotestsrc_get_interface; - - this = (SpiAudioTestSrc *) handle; - this->params.param.enum_param_info = enum_param_info; - this->params.param.set_param = set_param; - this->params.param.get_param = get_param; - reset_audiotestsrc_params (&this->params); - - node = &this->node; - node->get_params = spi_audiotestsrc_node_get_params; - node->set_params = spi_audiotestsrc_node_set_params; - node->send_command = spi_audiotestsrc_node_send_command; - node->set_event_callback = spi_audiotestsrc_node_set_event_callback; - node->get_n_ports = spi_audiotestsrc_node_get_n_ports; - node->get_port_ids = spi_audiotestsrc_node_get_port_ids; - node->add_port = spi_audiotestsrc_node_add_port; - node->remove_port = spi_audiotestsrc_node_remove_port; - node->enum_port_formats = spi_audiotestsrc_node_enum_port_formats; - node->set_port_format = spi_audiotestsrc_node_set_port_format; - node->get_port_format = spi_audiotestsrc_node_get_port_format; - node->get_port_info = spi_audiotestsrc_node_get_port_info; - node->get_port_params = spi_audiotestsrc_node_get_port_params; - node->set_port_params = spi_audiotestsrc_node_set_port_params; - node->get_port_status = spi_audiotestsrc_node_get_port_status; - node->push_port_input = spi_audiotestsrc_node_push_port_input; - node->pull_port_output = spi_audiotestsrc_node_pull_port_output; - - return handle; -} diff --git a/pinos/tests/spi-plugins.h b/pinos/tests/spi-plugins.h deleted file mode 100644 index 534cf9c29..000000000 --- a/pinos/tests/spi-plugins.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Spi - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include - -SpiHandle * spi_volume_new (void); -SpiHandle * spi_audiotestsrc_new (void); -SpiHandle * spi_alsa_sink_new (void); diff --git a/pinos/tests/spi-volume.c b/pinos/tests/spi-volume.c deleted file mode 100644 index 4f4c3729a..000000000 --- a/pinos/tests/spi-volume.c +++ /dev/null @@ -1,963 +0,0 @@ -/* Spi - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include - -#include - -#include "spi-plugins.h" - -typedef struct _SpiVolume SpiVolume; - -typedef struct { - SpiParams param; - double volume; - bool mute; -} SpiVolumeParams; - -typedef struct { - SpiParams param; - char media_type[32]; - uint32_t unset_mask; - char format[16]; - int32_t layout; - int32_t samplerate; - int32_t channels; - int32_t position[16]; -} SpiVolumeFormat; - -struct _SpiVolume { - SpiHandle handle; - SpiNode node; - - SpiVolumeParams params; - SpiVolumeParams tmp_params; - - SpiEventCallback event_cb; - void *user_data; - - bool have_format; - SpiVolumeFormat current_format; - - bool have_input; - SpiBuffer *input_buffer; - - SpiData data; -}; - -static const double default_volume = 1.0; -static const double min_volume = 0.0; -static const double max_volume = 10.0; -static const bool default_mute = false; - -static const SpiParamRangeInfo volume_range[] = { - { "min", "Minimum value", sizeof (double), &min_volume }, - { "max", "Maximum value", sizeof (double), &max_volume }, - { NULL, NULL, 0, NULL } -}; - -enum { - PARAM_ID_VOLUME, - PARAM_ID_MUTE, - PARAM_ID_LAST, -}; - -static const SpiParamInfo param_info[] = -{ - { PARAM_ID_VOLUME, "volume", "The Volume factor", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_DOUBLE, sizeof (double), - sizeof (double), &default_volume, - SPI_PARAM_RANGE_TYPE_MIN_MAX, volume_range, - NULL, - NULL }, - { PARAM_ID_MUTE, "mute", "Mute", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_BOOL, sizeof (bool), - sizeof (bool), &default_mute, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, -}; - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define CHECK_SIZE(size,expected) if (size != expected) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_RANGE(size,minsize,maxsize) if (size > maxsize || size < minsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_SIZE_MAX(size,maxsize) if (size > maxsize) return SPI_RESULT_WRONG_PARAM_SIZE; -#define CHECK_UNSET(mask,index) if (mask & (1 << index)) return SPI_RESULT_PARAM_UNSET; - -static SpiResult -enum_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= PARAM_ID_LAST) - return SPI_RESULT_ENUM_END; - - *info = ¶m_info[index]; - - return SPI_RESULT_OK; -} - -static SpiResult -set_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiResult res = SPI_RESULT_OK; - SpiVolumeParams *p = (SpiVolumeParams *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_VOLUME: - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->volume, value, size); - break; - case PARAM_ID_MUTE: - CHECK_TYPE (type, SPI_PARAM_TYPE_BOOL); - CHECK_SIZE (size, sizeof (bool)); - memcpy (&p->mute, value, size); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - -static SpiResult -get_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiResult res = SPI_RESULT_OK; - SpiVolumeParams *p = (SpiVolumeParams *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case PARAM_ID_VOLUME: - *type = SPI_PARAM_TYPE_DOUBLE; - *value = &p->volume; - *size = sizeof (double); - break; - case PARAM_ID_MUTE: - *type = SPI_PARAM_TYPE_BOOL; - *value = &p->mute; - *size = sizeof (bool); - break; - default: - res = SPI_RESULT_INVALID_PARAM_ID; - break; - } - return res; -} - -static void -reset_volume_params (SpiVolumeParams *params) -{ - params->volume = default_volume; - params->mute = default_mute; -} - -static SpiResult -spi_volume_node_get_params (SpiHandle *handle, - SpiParams **params) -{ - SpiVolume *this = (SpiVolume *) handle; - - if (handle == NULL || params == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - memcpy (&this->tmp_params, &this->params, sizeof (this->tmp_params)); - *params = &this->tmp_params.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_set_params (SpiHandle *handle, - const SpiParams *params) -{ - SpiVolume *this = (SpiVolume *) handle; - SpiVolumeParams *p = &this->params; - SpiParamType type; - size_t size; - const void *value; - - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (params == NULL) { - reset_volume_params (p); - return SPI_RESULT_OK; - } - - if (params->get_param (params, 0, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_DOUBLE); - CHECK_SIZE (size, sizeof (double)); - memcpy (&p->volume, value, size); - } - if (params->get_param (params, 1, &type, &size, &value) == 0) { - CHECK_TYPE (type, SPI_PARAM_TYPE_BOOL); - CHECK_SIZE (size, sizeof (bool)); - memcpy (&p->mute, value, size); - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_send_command (SpiHandle *handle, - SpiCommand *command) -{ - SpiVolume *this = (SpiVolume *) handle; - - if (handle == NULL || command == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (command->type) { - case SPI_COMMAND_INVALID: - return SPI_RESULT_INVALID_COMMAND; - - case SPI_COMMAND_ACTIVATE: - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_ACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (handle, &event, this->user_data); - } - break; - - case SPI_COMMAND_DEACTIVATE: - if (this->event_cb) { - SpiEvent event; - - event.refcount = 1; - event.notify = NULL; - event.type = SPI_EVENT_TYPE_DEACTIVATED; - event.port_id = -1; - event.data = NULL; - event.size = 0; - - this->event_cb (handle, &event, this->user_data); - } - break; - - case SPI_COMMAND_START: - case SPI_COMMAND_STOP: - case SPI_COMMAND_FLUSH: - case SPI_COMMAND_DRAIN: - case SPI_COMMAND_MARKER: - return SPI_RESULT_NOT_IMPLEMENTED; - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_set_event_callback (SpiHandle *handle, - SpiEventCallback event, - void *user_data) -{ - SpiVolume *this = (SpiVolume *) handle; - - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - this->event_cb = event; - this->user_data = user_data; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_get_n_ports (SpiHandle *handle, - unsigned int *n_input_ports, - unsigned int *max_input_ports, - unsigned int *n_output_ports, - unsigned int *max_output_ports) -{ - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_input_ports) - *n_input_ports = 1; - if (n_output_ports) - *n_output_ports = 1; - if (max_input_ports) - *max_input_ports = 1; - if (max_output_ports) - *max_output_ports = 1; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_get_port_ids (SpiHandle *handle, - unsigned int n_input_ports, - uint32_t *input_ids, - unsigned int n_output_ports, - uint32_t *output_ids) -{ - if (handle == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (n_input_ports > 0 && input_ids) - input_ids[0] = 0; - if (n_output_ports > 0 && output_ids) - output_ids[0] = 1; - - return SPI_RESULT_OK; -} - - -static SpiResult -spi_volume_node_add_port (SpiHandle *handle, - SpiDirection direction, - uint32_t *port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_volume_node_remove_port (SpiHandle *handle, - uint32_t port_id) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static const SpiParamRangeInfo format_format_range[] = { - { "S8", "S8", 2, "S8" }, - { "U8", "U8", 2, "U8" }, - { "S16LE", "S16LE", 5, "S16LE" }, - { "S16BE", "S16BE", 5, "S16BE" }, - { "U16LE", "U16LE", 5, "U16LE" }, - { "U16BE", "U16BE", 5, "U16BE" }, - { "S24_32LE", "S24_32LE", 8, "S24_32LE" }, - { "S24_32BE", "S24_32BE", 8, "S24_32BE" }, - { "U24_32LE", "U24_32LE", 8, "U24_32LE" }, - { "U24_32BE", "U24_32BE", 8, "U24_32BE" }, - { "S32LE", "S32LE", 5, "S32LE" }, - { "S32BE", "S32BE", 5, "S32BE" }, - { "U32LE", "U32LE", 5, "U32LE" }, - { "U32BE", "U32BE", 5, "U32BE" }, - { "S24LE", "S24LE", 5, "S24LE" }, - { "S24BE", "S24BE", 5, "S24BE" }, - { "U24LE", "U24LE", 5, "U24LE" }, - { "U24BE", "U24BE", 5, "U24BE" }, - { "S20LE", "S20LE", 5, "S20LE" }, - { "S20BE", "S20BE", 5, "S20BE" }, - { "U20LE", "U20LE", 5, "U20LE" }, - { "U20BE", "U20BE", 5, "U20BE" }, - { "S18LE", "S18LE", 5, "S18LE" }, - { "S18BE", "S18BE", 5, "S18BE" }, - { "U18LE", "U18LE", 5, "U18LE" }, - { "U18BE", "U18BE", 5, "U18BE" }, - { "F32LE", "F32LE", 5, "F32LE" }, - { "F32BE", "F32BE", 5, "F32BE" }, - { "F64LE", "F64LE", 5, "F64LE" }, - { "F64BE", "F64BE", 5, "F64BE" }, - { NULL, NULL, 0, NULL } -}; - -static const uint32_t min_uint32 = 1; -static const uint32_t max_uint32 = UINT32_MAX; - -static const SpiParamRangeInfo int32_range[] = { - { "min", "Minimum value", 4, &min_uint32 }, - { "max", "Maximum value", 4, &max_uint32 }, - { NULL, NULL, 0, NULL } -}; - -enum { - SPI_PARAM_ID_INVALID, - SPI_PARAM_ID_MEDIA_TYPE, - SPI_PARAM_ID_FORMAT, - SPI_PARAM_ID_LAYOUT, - SPI_PARAM_ID_SAMPLERATE, - SPI_PARAM_ID_CHANNELS, -}; - -static const int32_t format_default_layout = 1; - -static const SpiParamInfo raw_format_param_info[] = -{ - { SPI_PARAM_ID_MEDIA_TYPE, "media-type", "The media type", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_STRING, 32, - 12, "audio/x-raw", - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_FORMAT, "format", "The media format", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_STRING, 16, - 0, NULL, - SPI_PARAM_RANGE_TYPE_ENUM, format_format_range, - NULL, - NULL }, - { SPI_PARAM_ID_LAYOUT, "layout", "Sample Layout", - SPI_PARAM_FLAG_READABLE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - sizeof (uint32_t), &format_default_layout, - SPI_PARAM_RANGE_TYPE_NONE, NULL, - NULL, - NULL }, - { SPI_PARAM_ID_SAMPLERATE, "rate", "Audio sample rate", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, - { SPI_PARAM_ID_CHANNELS, "channels", "Audio channels", - SPI_PARAM_FLAG_READWRITE, - SPI_PARAM_TYPE_UINT32, sizeof (uint32_t), - 0, NULL, - SPI_PARAM_RANGE_TYPE_MIN_MAX, int32_range, - NULL, - NULL }, -}; - -static SpiResult -enum_raw_format_param_info (const SpiParams *params, - unsigned int index, - const SpiParamInfo **info) -{ - if (params == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (index >= 4) - return SPI_RESULT_ENUM_END; - - *info = &raw_format_param_info[index]; - - return SPI_RESULT_OK; -} - -#define CHECK_TYPE(type,expected) if (type != expected) return SPI_RESULT_WRONG_PARAM_TYPE; -#define MARK_SET(mask,index) (mask &= ~(1 << index)) - -static SpiResult -set_format_param (SpiParams *params, - uint32_t id, - SpiParamType type, - size_t size, - const void *value) -{ - SpiVolumeFormat *f = (SpiVolumeFormat *) params; - - if (params == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_FORMAT: - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - memcpy (f->format, value, size); - MARK_SET (f->unset_mask, 1); - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->layout, value, size); - MARK_SET (f->unset_mask, 2); - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->samplerate, value, size); - MARK_SET (f->unset_mask, 3); - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&f->channels, value, size); - MARK_SET (f->unset_mask, 4); - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - - return SPI_RESULT_OK; -} - - - -static SpiResult -get_format_param (const SpiParams *params, - uint32_t id, - SpiParamType *type, - size_t *size, - const void **value) -{ - SpiVolumeFormat *f = (SpiVolumeFormat *) params; - - if (params == NULL || type == NULL || size == NULL || value == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (id) { - case SPI_PARAM_ID_MEDIA_TYPE: - CHECK_UNSET (f->unset_mask, 0); - *type = SPI_PARAM_TYPE_STRING; - *value = f->media_type; - *size = strlen (f->media_type); - break; - case SPI_PARAM_ID_FORMAT: - CHECK_UNSET (f->unset_mask, 1); - *type = SPI_PARAM_TYPE_STRING; - *value = f->format; - *size = strlen (f->format); - break; - case SPI_PARAM_ID_LAYOUT: - CHECK_UNSET (f->unset_mask, 2); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->layout; - *size = 4; - break; - case SPI_PARAM_ID_SAMPLERATE: - CHECK_UNSET (f->unset_mask, 3); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->samplerate; - *size = 4; - break; - case SPI_PARAM_ID_CHANNELS: - CHECK_UNSET (f->unset_mask, 4); - *type = SPI_PARAM_TYPE_UINT32; - *value = &f->channels; - *size = 4; - break; - default: - return SPI_RESULT_INVALID_PARAM_ID; - } - return SPI_RESULT_OK; -} - - -static SpiResult -spi_volume_node_enum_port_formats (SpiHandle *handle, - uint32_t port_id, - unsigned int index, - SpiParams **format) -{ - static SpiVolumeFormat fmt; - - if (handle == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - switch (index) { - case 0: - strcpy (fmt.media_type, "audio/x-raw"); - fmt.unset_mask = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4); - fmt.param.enum_param_info = enum_raw_format_param_info; - fmt.param.set_param = set_format_param; - fmt.param.get_param = get_format_param; - break; - default: - return SPI_RESULT_ENUM_END; - } - *format = &fmt.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_set_port_format (SpiHandle *handle, - uint32_t port_id, - int test_only, - const SpiParams *format) -{ - SpiVolume *this = (SpiVolume *) handle; - SpiParamType type; - size_t size; - const void *value; - SpiVolumeFormat *fmt; - - if (handle == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - fmt = &this->current_format; - - if (format == NULL) { - fmt->param.get_param = NULL; - this->have_format = false; - return SPI_RESULT_OK; - } - - if (format->get_param (format, - SPI_PARAM_ID_MEDIA_TYPE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_MEDIA_TYPE; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 32); - memcpy (fmt->media_type, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_FORMAT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_STRING); - CHECK_SIZE_MAX (size, 16); - memcpy (fmt->format, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_LAYOUT, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->layout, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_SAMPLERATE, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->samplerate, value, size); - - if (format->get_param (format, - SPI_PARAM_ID_CHANNELS, - &type, &size, &value) < 0) - return SPI_RESULT_INVALID_FORMAT_PARAMS; - CHECK_TYPE (type, SPI_PARAM_TYPE_UINT32); - CHECK_SIZE (size, sizeof (uint32_t)); - memcpy (&fmt->channels, value, size); - - fmt->param.enum_param_info = enum_raw_format_param_info; - fmt->param.set_param = NULL; - fmt->param.get_param = get_format_param; - this->have_format = true; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_get_port_format (SpiHandle *handle, - uint32_t port_id, - const SpiParams **format) -{ - SpiVolume *this = (SpiVolume *) handle; - - if (handle == NULL || format == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (port_id != 0) - return SPI_RESULT_INVALID_PORT; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - *format = &this->current_format.param; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_get_port_info (SpiHandle *handle, - uint32_t port_id, - SpiPortInfo *info) -{ - if (handle == NULL || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (port_id) { - case 0: - info->flags = SPI_PORT_INFO_FLAG_CAN_USE_BUFFER | - SPI_PORT_INFO_FLAG_IN_PLACE; - break; - case 1: - info->flags = SPI_PORT_INFO_FLAG_CAN_GIVE_BUFFER | - SPI_PORT_INFO_FLAG_CAN_USE_BUFFER | - SPI_PORT_INFO_FLAG_NO_REF; - break; - default: - return SPI_RESULT_INVALID_PORT; - } - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_get_port_params (SpiHandle *handle, - uint32_t port_id, - SpiParams **params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_volume_node_set_port_params (SpiHandle *handle, - uint32_t port_id, - const SpiParams *params) -{ - return SPI_RESULT_NOT_IMPLEMENTED; -} - -static SpiResult -spi_volume_node_get_port_status (SpiHandle *handle, - uint32_t port_id, - SpiPortStatus *status) -{ - SpiVolume *this = (SpiVolume *) handle; - SpiPortStatusFlags flags = 0; - - if (handle == NULL || status == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - switch (port_id) { - case 0: - if (this->input_buffer == NULL) - flags |= SPI_PORT_STATUS_FLAG_NEED_INPUT; - break; - case 1: - if (this->input_buffer != NULL) - flags |= SPI_PORT_STATUS_FLAG_HAVE_OUTPUT; - break; - default: - return SPI_RESULT_INVALID_PORT; - } - status->flags = flags; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_node_push_port_input (SpiHandle *handle, - unsigned int n_info, - SpiInputInfo *info) -{ - SpiVolume *this = (SpiVolume *) handle; - SpiBuffer *buffer; - SpiEvent *event; - unsigned int i; - bool have_error = false; - bool have_enough = false; - - if (handle == NULL || n_info == 0 || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - for (i = 0; i < n_info; i++) { - if (info[i].port_id != 0) { - info[i].status = SPI_RESULT_INVALID_PORT; - have_error = true; - continue; - } - - event = info[i].event; - buffer = info[i].buffer; - - if (buffer == NULL && event == NULL) { - info[i].status = SPI_RESULT_INVALID_ARGUMENTS; - have_error = true; - continue; - } - - if (buffer) { - if (!this->have_format) { - info[i].status = SPI_RESULT_NO_FORMAT; - have_error = true; - continue; - } - - if (this->input_buffer != NULL) { - info[i].status = SPI_RESULT_HAVE_ENOUGH_INPUT; - have_enough = true; - continue; - } - this->input_buffer = spi_buffer_ref (buffer); - } - if (event) { - switch (event->type) { - default: - break; - } - } - info[i].status = SPI_RESULT_OK; - } - if (have_error) - return SPI_RESULT_ERROR; - if (have_enough) - return SPI_RESULT_HAVE_ENOUGH_INPUT; - - return SPI_RESULT_OK; -} - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -static SpiResult -spi_volume_node_pull_port_output (SpiHandle *handle, - unsigned int n_info, - SpiOutputInfo *info) -{ - SpiVolume *this = (SpiVolume *) handle; - unsigned int si, di, i, n_samples, n_bytes, soff, doff ; - SpiBuffer *sbuf, *dbuf; - SpiData *sd, *dd; - uint16_t *src, *dst; - double volume; - - if (handle == NULL || n_info == 0 || info == NULL) - return SPI_RESULT_INVALID_ARGUMENTS; - - if (info->port_id != 1) - return SPI_RESULT_INVALID_PORT; - - if (!this->have_format) - return SPI_RESULT_NO_FORMAT; - - if (this->input_buffer == NULL) - return SPI_RESULT_NEED_MORE_INPUT; - - volume = this->params.volume; - - sbuf = this->input_buffer; - dbuf = info->buffer ? info->buffer : this->input_buffer; - - si = di = 0; - soff = doff = 0; - - while (true) { - if (si == sbuf->n_datas || di == dbuf->n_datas) - break; - - sd = &sbuf->datas[si]; - dd = &dbuf->datas[di]; - - if (sd->type != SPI_DATA_TYPE_MEMPTR) { - si++; - continue; - } - if (dd->type != SPI_DATA_TYPE_MEMPTR) { - di++; - continue; - } - src = (uint16_t*) ((uint8_t*)sd->data + soff); - dst = (uint16_t*) ((uint8_t*)dd->data + doff); - - n_bytes = MIN (sd->size - soff, dd->size - doff); - n_samples = n_bytes / sizeof (uint16_t); - - for (i = 0; i < n_samples; i++) - *src++ = *dst++ * volume; - - soff += n_bytes; - doff += n_bytes; - - if (soff >= sd->size) { - si++; - soff = 0; - } - if (doff >= dd->size) { - di++; - doff = 0; - } - } - - if (sbuf != dbuf) - spi_buffer_unref (sbuf); - - this->input_buffer = NULL; - info->buffer = dbuf; - - return SPI_RESULT_OK; -} - -static SpiResult -spi_volume_get_interface (SpiHandle *handle, - uint32_t interface_id, - void **interface) -{ - SpiVolume *this = (SpiVolume *) handle; - - if (handle == NULL || interface == 0) - return SPI_RESULT_INVALID_ARGUMENTS; - - switch (interface_id) { - case SPI_INTERFACE_ID_NODE: - *interface = &this->node; - break; - default: - return SPI_RESULT_UNKNOWN_INTERFACE; - - } - return SPI_RESULT_OK; -} - -SpiHandle * -spi_volume_new (void) -{ - SpiHandle *handle; - SpiNode *node; - SpiVolume *this; - - handle = calloc (1, sizeof (SpiVolume)); - handle->get_interface = spi_volume_get_interface; - - this = (SpiVolume *) handle; - this->params.param.enum_param_info = enum_param_info; - this->params.param.set_param = set_param; - this->params.param.get_param = get_param; - reset_volume_params (&this->params); - - node = &this->node; - node->get_params = spi_volume_node_get_params; - node->set_params = spi_volume_node_set_params; - node->send_command = spi_volume_node_send_command; - node->set_event_callback = spi_volume_node_set_event_callback; - node->get_n_ports = spi_volume_node_get_n_ports; - node->get_port_ids = spi_volume_node_get_port_ids; - node->add_port = spi_volume_node_add_port; - node->remove_port = spi_volume_node_remove_port; - node->enum_port_formats = spi_volume_node_enum_port_formats; - node->set_port_format = spi_volume_node_set_port_format; - node->get_port_format = spi_volume_node_get_port_format; - node->get_port_info = spi_volume_node_get_port_info; - node->get_port_params = spi_volume_node_get_port_params; - node->set_port_params = spi_volume_node_set_port_params; - node->get_port_status = spi_volume_node_get_port_status; - node->push_port_input = spi_volume_node_push_port_input; - node->pull_port_output = spi_volume_node_pull_port_output; - - return handle; -} diff --git a/spa/lib/format.c b/spa/lib/format.c index e8e08cfac..647817a45 100644 --- a/spa/lib/format.c +++ b/spa/lib/format.c @@ -62,7 +62,7 @@ spa_format_fixate (SpaFormat *format) for (j = 0; j < pi->n_range_values; j++) { const SpaPropRangeInfo *ri = &pi->range_values[j]; memcpy (SPA_MEMBER (props, pi->offset, void), ri->value, ri->size); - props->unset_mask &= ~(1 << i); + SPA_PROPS_INDEX_SET (props, i); break; } break; diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 2ae7a75b4..839cad647 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -452,7 +452,7 @@ again: if (i == 1) { fmt->framerate = fmt->framerates[0]; } else { - fmt->fmt.props.unset_mask |= 1 << pi; + SPA_PROPS_INDEX_UNSET (&fmt->fmt.props, pi); } pi = ++fmt->fmt.props.n_prop_info;