ctrl->result = snd_pcm_mmap_forward(pcm, ctrl->u.mmap_forward.frames);
ctrl->appl_ptr = *pcm->appl_ptr;
break;
- case SND_PCM_IOCTL_SET_AVAIL_MIN:
- ctrl->result = snd_pcm_set_avail_min(pcm, ctrl->u.set_avail_min.frames);
- break;
case SND_PCM_IOCTL_POLL_DESCRIPTOR:
ctrl->result = 0;
return shm_ack_fd(client, snd_pcm_poll_descriptor(pcm));
#define SND_PCM_IOCTL_ASYNC _IO ('A', 0xf6)
#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xf7)
#define SND_PCM_IOCTL_POLL_DESCRIPTOR _IO ('A', 0xf8)
-#define SND_PCM_IOCTL_SET_AVAIL_MIN _IO ('A', 0xf9)
typedef struct {
long result;
snd_pcm_hw_params_t hw_refine;
snd_pcm_hw_params_t hw_params;
snd_pcm_sw_params_t sw_params;
+ snd_pcm_sw_params_t sw_refine;
snd_pcm_status_t status;
struct {
ssize_t frames;
struct {
ssize_t frames;
} mmap_forward;
- struct {
- ssize_t frames;
- } set_avail_min;
} u;
char data[0];
} snd_pcm_shm_ctrl_t;
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status);
int snd_pcm_prepare(snd_pcm_t *pcm);
int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp);
int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp);
int snd_pcm_dump_setup(snd_pcm_t *pcm, FILE *fp);
-int snd_pcm_dump_hw_params(snd_pcm_hw_params_t *params, FILE *fp);
-int snd_pcm_dump_hw_params_fail(snd_pcm_hw_params_t *params, FILE *fp);
-int snd_pcm_dump_sw_params_fail(snd_pcm_sw_params_t *params, FILE *fp);
int snd_pcm_dump(snd_pcm_t *pcm, FILE *fp);
-int snd_pcm_dump_status(snd_pcm_status_t *status, FILE *fp);
+int snd_pcm_status_dump(snd_pcm_status_t *status, FILE *fp);
int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int snd_pcm_unlink(snd_pcm_t *pcm);
int mask_single(const mask_t *mask);
int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
-int snd_pcm_hw_params_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ unsigned int var);
+int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val);
-int snd_pcm_hw_params_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val);
-int snd_pcm_hw_params_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val);
-int snd_pcm_hw_params_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int min, unsigned int max);
-int snd_pcm_hw_params_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int par);
-int snd_pcm_hw_params_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int par);
-int snd_pcm_hw_params_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val);
-int snd_pcm_hw_params_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, const mask_t *mask);
+int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
+ unsigned int var);
+const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
+ unsigned int var);
+const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
+ unsigned int var);
+unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
+ unsigned int var);
+unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
+ unsigned int var);
+int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *fail,
+ snd_pcm_hw_params_t *success,
+ unsigned int depth,
+ FILE *fp);
+
int snd_pcm_hw_params_info_rate(const snd_pcm_hw_params_t *params,
unsigned int *rate_num,
unsigned int *rate_den);
int snd_pcm_hw_params_info_flags(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_info_fifo_size(const snd_pcm_hw_params_t *params);
int snd_pcm_hw_params_info_dig_groups(const snd_pcm_hw_params_t *params);
-int snd_pcm_hw_params_value(const snd_pcm_hw_params_t *params,
- unsigned int var);
-const mask_t *snd_pcm_hw_params_value_mask(const snd_pcm_hw_params_t *params,
- unsigned int var);
-const interval_t *snd_pcm_hw_params_value_interval(const snd_pcm_hw_params_t *params,
- unsigned int var);
-unsigned int snd_pcm_hw_params_value_min(const snd_pcm_hw_params_t *params,
- unsigned int var);
-unsigned int snd_pcm_hw_params_value_max(const snd_pcm_hw_params_t *params,
- unsigned int var);
-int snd_pcm_hw_params_test(const snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
-int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, FILE *fp);
-typedef struct _snd_pcm_strategy snd_pcm_strategy_t;
+typedef struct _snd_pcm_hw_strategy snd_pcm_hw_strategy_t;
/* choices need to be sorted on ascending badness */
-typedef struct _snd_pcm_strategy_simple_choices_list {
+typedef struct _snd_pcm_hw_strategy_simple_choices_list {
unsigned int value;
unsigned int badness;
-} snd_pcm_strategy_simple_choices_list_t;
-
-int snd_pcm_hw_info_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *info,
- const snd_pcm_strategy_t *strategy);
-
-int snd_pcm_strategy_free(snd_pcm_strategy_t *strategy);
-int snd_pcm_strategy_simple(snd_pcm_strategy_t **strategyp,
- unsigned int badness_min,
- unsigned int badness_max);
-int snd_pcm_strategy_simple_near(snd_pcm_strategy_t *strategy, int order,
- unsigned int param,
- unsigned int best,
- unsigned int mul);
-int snd_pcm_strategy_simple_choices(snd_pcm_strategy_t *strategy, int order,
+} snd_pcm_hw_strategy_simple_choices_list_t;
+
+int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ const snd_pcm_hw_strategy_t *strategy,
+ unsigned int badness_min,
+ unsigned int badness_max);
+
+int snd_pcm_hw_strategy_free(snd_pcm_hw_strategy_t *strategy);
+int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
+ unsigned int badness_min,
+ unsigned int badness_max);
+int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy, int order,
unsigned int param,
- unsigned int count,
- snd_pcm_strategy_simple_choices_list_t *choices);
-int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
- snd_pcm_hw_params_t *fail,
- snd_pcm_hw_params_t *success,
- unsigned int depth,
- FILE *fp);
+ unsigned int best,
+ unsigned int mul);
+int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order,
+ unsigned int param,
+ unsigned int count,
+ snd_pcm_hw_strategy_simple_choices_list_t *choices);
+
+#define SND_PCM_SW_PARAM_START_MODE 0
+#define SND_PCM_SW_PARAM_READY_MODE 1
+#define SND_PCM_SW_PARAM_XRUN_MODE 2
+#define SND_PCM_SW_PARAM_SILENCE_MODE 3
+#define SND_PCM_SW_PARAM_TSTAMP_MODE 4
+#define SND_PCM_SW_PARAM_AVAIL_MIN 5
+#define SND_PCM_SW_PARAM_XFER_ALIGN 6
+#define SND_PCM_SW_PARAM_SILENCE_THRESHOLD 7
+#define SND_PCM_SW_PARAM_SILENCE_SIZE 8
+#define SND_PCM_SW_PARAM_LAST 8
+
+int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
+int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
+int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var);
+int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp);
/* mmap */
const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm);
ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size);
ssize_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, size_t size);
+const char *snd_pcm_stream_name(unsigned int stream);
+const char *snd_pcm_hw_param_name(unsigned int params);
+const char *snd_pcm_sw_param_name(unsigned int params);
const char *snd_pcm_access_name(unsigned int access);
const char *snd_pcm_format_name(unsigned int format);
const char *snd_pcm_subformat_name(unsigned int subformat);
-const char *snd_pcm_hw_param_name(unsigned int params);
-const char *snd_pcm_sw_param_name(unsigned int params);
-
const char *snd_pcm_format_description(unsigned int format);
int snd_pcm_format_value(const char* name);
+const char *snd_pcm_start_mode_name(unsigned int mode);
+const char *snd_pcm_ready_mode_name(unsigned int mode);
+const char *snd_pcm_xrun_mode_name(unsigned int mode);
+const char *snd_pcm_silence_mode_name(unsigned int mode);
+const char *snd_pcm_tstamp_mode_name(unsigned int mode);
+const char *snd_pcm_state_name(unsigned int state);
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
size_t samples, int format);
pcm.c pcm_hw.c pcm_plugin.c pcm_copy.c pcm_linear.c \
pcm_route.c pcm_mulaw.c pcm_alaw.c pcm_adpcm.c \
pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
- pcm_shm.c pcm_file.c pcm_share.c pcm_null.c pcm_params.c
+ pcm_shm.c pcm_file.c pcm_share.c pcm_null.c \
+ pcm_params.c
noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
interval.h interval_inline.h
*/
#define INTERVAL_C
+#define INTERVAL_INLINE
#include <sys/types.h>
#include <limits.h>
return interval_refine(i, &t);
}
+/* a <- b + c */
+int interval_add(interval_t *a, const interval_t *b, const interval_t *c)
+{
+ interval_t t;
+ assert(!a->empty && !b->empty && !c->empty);
+ t.min = add(b->min, c->min);
+ t.openmin = (b->openmin || c->openmin);
+ t.max = add(b->max, c->max);
+ t.openmax = (b->openmax || c->openmax);
+ return interval_refine(a, &t);
+}
+
+/* a <- b - c */
+int interval_sub(interval_t *a, const interval_t *b, const interval_t *c)
+{
+ interval_t t;
+ assert(!a->empty && !b->empty && !c->empty);
+ t.min = sub(b->min, c->max);
+ t.openmin = (b->openmin || c->openmax);
+ t.max = add(b->max, c->min);
+ t.openmax = (b->openmax || c->openmin);
+ return interval_refine(a, &t);
+}
+
/* a <- b * c */
int interval_mul(interval_t *a, const interval_t *b, const interval_t *c)
{
#include <stdio.h>
-#ifdef INTERVAL_C
+#ifdef INTERVAL_INLINE
#include "interval_inline.h"
-#endif
-
+#else
void interval_all(interval_t *i);
void interval_setreal(interval_t *i);
int interval_empty(const interval_t *i);
int interval_min(const interval_t *i);
int interval_max(const interval_t *i);
int interval_test(const interval_t *i, unsigned int val);
-int interval_refine_min(interval_t *i, unsigned int min);
-int interval_refine_max(interval_t *i, unsigned int max);
-int interval_refine(interval_t *i, const interval_t *v);
-int interval_refine_first(interval_t *i);
-int interval_refine_last(interval_t *i);
-int interval_refine_set(interval_t *i, unsigned int val);
+void interval_copy(interval_t *dst, const interval_t *src);
+int interval_eq(const interval_t *i1, const interval_t *i2);
+#endif
+
+int interval_add(interval_t *a, const interval_t *b, const interval_t *c);
+int interval_sub(interval_t *a, const interval_t *b, const interval_t *c);
int interval_mul(interval_t *a, const interval_t *b, const interval_t *c);
int interval_div(interval_t *a, const interval_t *b, const interval_t *c);
int interval_muldivk(interval_t *a, unsigned int k,
const interval_t *b, const interval_t *c);
int interval_mulkdiv(interval_t *a, unsigned int k,
const interval_t *b, const interval_t *c);
-void interval_copy(interval_t *dst, const interval_t *src);
void interval_print(const interval_t *i, FILE *fp);
-int interval_eq(const interval_t *i1, const interval_t *i2);
+int interval_refine_min(interval_t *i, unsigned int min);
+int interval_refine_max(interval_t *i, unsigned int max);
+int interval_refine(interval_t *i, const interval_t *v);
+int interval_refine_first(interval_t *i);
+int interval_refine_last(interval_t *i);
+int interval_refine_set(interval_t *i, unsigned int val);
#ifdef INTERVAL_C
#define INLINE inline
#else
-#define INLINE static inline
+#define INLINE extern inline
#endif
INLINE void interval_all(interval_t *i)
*/
#define MASK_C
+#define MASK_INLINE
#include <sys/types.h>
#include <limits.h>
#define MASK_MAX 32
-#ifdef MASK_C
+#ifdef MASK_INLINE
#include "mask_inline.h"
-#endif
-
+#else
void mask_none(mask_t *mask);
void mask_all(mask_t *mask);
void mask_load(mask_t *mask, unsigned int msk);
int mask_empty(const mask_t *mask);
+int mask_full(const mask_t *mask);
void mask_set(mask_t *mask, unsigned int val);
void mask_reset(mask_t *mask, unsigned int val);
void mask_copy(mask_t *mask, const mask_t *v);
int mask_refine_max(mask_t *mask, unsigned int val);
int mask_refine_set(mask_t *mask, unsigned int val);
int mask_value(const mask_t *mask);
+#endif
*
*/
+#include <sys/types.h>
+#include <assert.h>
+
#ifdef MASK_C
#define INLINE inline
#else
-#define INLINE static inline
+#define INLINE extern inline
+#endif
+
+#ifndef MASK_MASK
+#define MASK_MAX 32
#endif
struct _mask {
return mask_bits(mask) == 0;
}
+INLINE int mask_full(const mask_t *mask)
+{
+ return mask_bits(mask) == ~0U;
+}
+
INLINE unsigned int mask_count(const mask_t *mask)
{
return hweight32(mask_bits(mask));
return pcm->ops->info(pcm->op_arg, info);
}
-int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
-{
- int err;
- assert(pcm && params);
- assert(pcm->setup);
- if ((err = pcm->ops->sw_params(pcm->op_arg, params)) < 0)
- return err;
- pcm->start_mode = params->start_mode;
- pcm->ready_mode = params->ready_mode;
- pcm->xrun_mode = params->xrun_mode;
- pcm->avail_min = params->avail_min;
- pcm->xfer_min = params->xfer_min;
- pcm->xfer_align = params->xfer_align;
- pcm->time = params->time;
- pcm->boundary = params->boundary;
- return 0;
-}
-
int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
{
assert(pcm && status);
return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
}
-int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- int err;
- assert(pcm);
- assert(pcm->setup);
- assert(frames > 0);
- err = pcm->fast_ops->set_avail_min(pcm->fast_op_arg, frames);
- if (err < 0)
- return err;
- pcm->avail_min = frames;
- return 0;
-}
-
ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
{
assert(pcm);
#define STREAM(v) [SND_PCM_STREAM_##v] = #v
#define READY(v) [SND_PCM_READY_##v] = #v
#define XRUN(v) [SND_PCM_XRUN_##v] = #v
+#define SILENCE(v) [SND_PCM_SILENCE_##v] = #v
+#define TSTAMP(v) [SND_PCM_TSTAMP_##v] = #v
#define ACCESS(v) [SND_PCM_ACCESS_##v] = #v
#define START(v) [SND_PCM_START_##v] = #v
#define HW_PARAM(v) [SND_PCM_HW_PARAM_##v] = #v
char *snd_pcm_sw_param_names[] = {
SW_PARAM(START_MODE),
SW_PARAM(READY_MODE),
+ SW_PARAM(XRUN_MODE),
+ SW_PARAM(SILENCE_MODE),
+ SW_PARAM(TSTAMP_MODE),
SW_PARAM(AVAIL_MIN),
- SW_PARAM(XFER_MIN),
SW_PARAM(XFER_ALIGN),
- SW_PARAM(XRUN_MODE),
- SW_PARAM(TIME),
+ SW_PARAM(SILENCE_THRESHOLD),
+ SW_PARAM(SILENCE_SIZE),
};
char *snd_pcm_access_names[] = {
};
char *snd_pcm_xrun_mode_names[] = {
- XRUN(ASAP),
XRUN(FRAGMENT),
+ XRUN(ASAP),
XRUN(NONE),
};
-static char *onoff[] = {
- [0] = "OFF",
- [1] = "ON",
+char *snd_pcm_silence_mode_names[] = {
+ SILENCE(FRAGMENT),
+ SILENCE(ASAP),
+};
+
+char *snd_pcm_tstamp_mode_names[] = {
+ TSTAMP(NONE),
+ TSTAMP(MMAP),
};
-#define assoc(value, names) ({ \
- unsigned int __v = value; \
- assert(__v < sizeof(names) / sizeof(names[0])); \
- names[__v]; \
-})
+const char *snd_pcm_stream_name(unsigned int stream)
+{
+ assert(stream <= SND_PCM_STREAM_LAST);
+ return snd_pcm_stream_names[stream];
+}
+
+const char *snd_pcm_access_name(unsigned int access)
+{
+ assert(access <= SND_PCM_ACCESS_LAST);
+ return snd_pcm_access_names[access];
+}
+
+const char *snd_pcm_format_name(unsigned int format)
+{
+ assert(format <= SND_PCM_FORMAT_LAST);
+ return snd_pcm_format_names[format];
+}
+
+const char *snd_pcm_format_description(unsigned int format)
+{
+ assert(format <= SND_PCM_FORMAT_LAST);
+ return snd_pcm_format_descriptions[format];
+}
+
+int snd_pcm_format_value(const char* name)
+{
+ unsigned int format;
+ for (format = 0; format <= SND_PCM_FORMAT_LAST; format++)
+ if (snd_pcm_format_names[format] &&
+ strcasecmp(name, snd_pcm_format_names[format]) == 0)
+ return format;
+ return -1;
+}
+
+const char *snd_pcm_subformat_name(unsigned int subformat)
+{
+ assert(subformat <= SND_PCM_SUBFORMAT_LAST);
+ return snd_pcm_subformat_names[subformat];
+}
+
+const char *snd_pcm_hw_param_name(unsigned int param)
+{
+ assert(param <= SND_PCM_HW_PARAM_LAST);
+ return snd_pcm_hw_param_names[param];
+}
+const char *snd_pcm_sw_param_name(unsigned int param)
+{
+ assert(param <= SND_PCM_SW_PARAM_LAST);
+ return snd_pcm_sw_param_names[param];
+}
+
+const char *snd_pcm_start_mode_name(unsigned int mode)
+{
+ assert(mode <= SND_PCM_START_LAST);
+ return snd_pcm_start_mode_names[mode];
+}
+
+const char *snd_pcm_ready_mode_name(unsigned int mode)
+{
+ assert(mode <= SND_PCM_READY_LAST);
+ return snd_pcm_ready_mode_names[mode];
+}
+
+const char *snd_pcm_xrun_mode_name(unsigned int mode)
+{
+ assert(mode <= SND_PCM_XRUN_LAST);
+ return snd_pcm_xrun_mode_names[mode];
+}
+
+const char *snd_pcm_silence_mode_name(unsigned int mode)
+{
+ assert(mode <= SND_PCM_SILENCE_LAST);
+ return snd_pcm_silence_mode_names[mode];
+}
+
+const char *snd_pcm_tstamp_mode_name(unsigned int mode)
+{
+ assert(mode <= SND_PCM_TSTAMP_LAST);
+ return snd_pcm_tstamp_mode_names[mode];
+}
+
+const char *snd_pcm_state_name(unsigned int state)
+{
+ assert(state <= SND_PCM_STATE_LAST);
+ return snd_pcm_state_names[state];
+}
int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp)
{
assert(pcm);
assert(fp);
assert(pcm->setup);
- fprintf(fp, "stream : %s\n", assoc(pcm->stream, snd_pcm_stream_names));
- fprintf(fp, "access : %s\n", assoc(pcm->access, snd_pcm_access_names));
- fprintf(fp, "format : %s\n", assoc(pcm->format, snd_pcm_format_names));
- fprintf(fp, "subformat : %s\n", assoc(pcm->subformat, snd_pcm_subformat_names));
+ fprintf(fp, "stream : %s\n", snd_pcm_stream_name(pcm->stream));
+ fprintf(fp, "access : %s\n", snd_pcm_access_name(pcm->access));
+ fprintf(fp, "format : %s\n", snd_pcm_format_name(pcm->format));
+ fprintf(fp, "subformat : %s\n", snd_pcm_subformat_name(pcm->subformat));
fprintf(fp, "channels : %u\n", pcm->channels);
fprintf(fp, "rate : %u\n", pcm->rate);
fprintf(fp, "exact rate : %g (%u/%u)\n", (double) pcm->rate_num / pcm->rate_den, pcm->rate_num, pcm->rate_den);
assert(pcm);
assert(fp);
assert(pcm->setup);
- fprintf(fp, "start_mode : %s\n", assoc(pcm->start_mode, snd_pcm_start_mode_names));
- fprintf(fp, "ready_mode : %s\n", assoc(pcm->ready_mode, snd_pcm_ready_mode_names));
- fprintf(fp, "xrun_mode : %s\n", assoc(pcm->xrun_mode, snd_pcm_xrun_mode_names));
+ fprintf(fp, "start_mode : %s\n", snd_pcm_start_mode_name(pcm->start_mode));
+ fprintf(fp, "xrun_mode : %s\n", snd_pcm_xrun_mode_name(pcm->xrun_mode));
+ fprintf(fp, "ready_mode : %s\n", snd_pcm_ready_mode_name(pcm->ready_mode));
+ fprintf(fp, "silence_mode : %s\n", snd_pcm_silence_mode_name(pcm->silence_mode));
+ fprintf(fp, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
fprintf(fp, "avail_min : %ld\n", (long)pcm->avail_min);
- fprintf(fp, "xfer_min : %ld\n", (long)pcm->xfer_min);
fprintf(fp, "xfer_align : %ld\n", (long)pcm->xfer_align);
- fprintf(fp, "time : %s\n", assoc(pcm->time, onoff));
+ fprintf(fp, "silence_threshold: %ld\n", (long)pcm->silence_threshold);
+ fprintf(fp, "silence_size : %ld\n", (long)pcm->silence_size);
fprintf(fp, "boundary : %ld\n", (long)pcm->boundary);
return 0;
}
return 0;
}
-int snd_pcm_dump_sw_params_fail(snd_pcm_sw_params_t *params, FILE *fp)
-{
- int k;
- if (params->fail_mask == 0) {
- fprintf(fp, "unknown sw_params failure reason\n");
- return 0;
- }
- fprintf(fp, "sw_params failed on the following field value(s):\n");
- for (k = 0; k <= SND_PCM_SW_PARAM_LAST; ++k) {
- if (!(params->fail_mask & (1U << k)))
- continue;
- switch (k) {
- case SND_PCM_SW_PARAM_START_MODE:
- fprintf(fp, "start_mode: %s\n", assoc(params->start_mode, snd_pcm_start_mode_names));
- break;
- case SND_PCM_SW_PARAM_READY_MODE:
- fprintf(fp, "ready_mode: %s\n", assoc(params->ready_mode, snd_pcm_ready_mode_names));
- break;
- case SND_PCM_SW_PARAM_XRUN_MODE:
- fprintf(fp, "xrun_mode: %s\n", assoc(params->xrun_mode, snd_pcm_xrun_mode_names));
- break;
- case SND_PCM_SW_PARAM_AVAIL_MIN:
- fprintf(fp, "avail_min: %ld\n", (long)params->avail_min);
- break;
- case SND_PCM_SW_PARAM_XFER_MIN:
- fprintf(fp, "xfer_min: %ld\n", (long)params->xfer_min);
- break;
- case SND_PCM_SW_PARAM_XFER_ALIGN:
- fprintf(fp, "xfer_align: %ld\n", (long)params->xfer_align);
- break;
- case SND_PCM_SW_PARAM_TIME:
- fprintf(fp, "time: %d\n", params->time);
- break;
- default:
- assert(0);
- break;
- }
- }
- return 0;
-}
-
-int snd_pcm_dump_status(snd_pcm_status_t *status, FILE *fp)
+int snd_pcm_status_dump(snd_pcm_status_t *status, FILE *fp)
{
assert(status);
- fprintf(fp, "state : %s\n", assoc(status->state, snd_pcm_state_names));
+ fprintf(fp, "state : %s\n", snd_pcm_state_name(status->state));
fprintf(fp, "trigger_time: %ld.%06ld\n",
status->trigger_time.tv_sec, status->trigger_time.tv_usec);
fprintf(fp, "tstamp : %ld.%06ld\n",
return 0;
}
-const char *snd_pcm_access_name(unsigned int access)
-{
- assert(access <= SND_PCM_ACCESS_LAST);
- return snd_pcm_access_names[access];
-}
-
-const char *snd_pcm_format_name(unsigned int format)
-{
- assert(format <= SND_PCM_FORMAT_LAST);
- return snd_pcm_format_names[format];
-}
-
-const char *snd_pcm_format_description(unsigned int format)
-{
- assert(format <= SND_PCM_FORMAT_LAST);
- return snd_pcm_format_descriptions[format];
-}
-
-int snd_pcm_format_value(const char* name)
-{
- unsigned int format;
- for (format = 0; format <= SND_PCM_FORMAT_LAST; format++)
- if (snd_pcm_format_names[format] &&
- strcasecmp(name, snd_pcm_format_names[format]) == 0)
- return format;
- return -1;
-}
-
-const char *snd_pcm_subformat_name(unsigned int subformat)
-{
- assert(subformat <= SND_PCM_SUBFORMAT_LAST);
- return snd_pcm_subformat_names[subformat];
-}
-
-const char *snd_pcm_hw_param_name(unsigned int param)
-{
- assert(param <= SND_PCM_HW_PARAM_LAST);
- return snd_pcm_hw_param_names[param];
-}
-
ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
{
assert(pcm);
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
mask_t *format_mask = alloca(mask_sizeof());
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
- err = _snd_pcm_hw_params_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params, 1,
SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_params_set(params, 1,
+ err = _snd_pcm_hw_param_set(params, 1,
SND_PCM_HW_PARAM_FORMAT,
SND_PCM_FORMAT_IMA_ADPCM);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
adpcm->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave,
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
adpcm->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
- adpcm->getput_idx = get_index(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+ adpcm->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
adpcm->func = adpcm_encode;
} else {
adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
}
} else {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
- adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT));
+ adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
adpcm->func = adpcm_decode;
} else {
adpcm->getput_idx = get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
}
if (adpcm->states)
free(adpcm->states);
- adpcm->states = malloc(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*adpcm->states));
+ adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*adpcm->states));
return 0;
}
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
mask_t *format_mask = alloca(mask_sizeof());
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
- err = _snd_pcm_hw_params_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params, 1,
SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_params_set(params, 1,
+ err = _snd_pcm_hw_param_set(params, 1,
SND_PCM_HW_PARAM_FORMAT,
SND_PCM_FORMAT_A_LAW);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
alaw->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave,
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
alaw->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
- alaw->getput_idx = get_index(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+ alaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
alaw->func = alaw_encode;
} else {
alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, alaw->sformat);
}
} else {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
- alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT));
+ alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
alaw->func = alaw_decode;
} else {
alaw->getput_idx = get_index(alaw->sformat, SND_PCM_FORMAT_S16);
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave,
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
return snd_pcm_avail_update(file->slave);
}
-static int snd_pcm_file_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_file_t *file = pcm->private;
- return snd_pcm_set_avail_min(file->slave, frames);
-}
-
static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_file_t *file = pcm->private;
readn: snd_pcm_file_readn,
avail_update: snd_pcm_file_avail_update,
mmap_forward: snd_pcm_file_mmap_forward,
- set_avail_min: snd_pcm_file_set_avail_min,
};
int snd_pcm_file_open(snd_pcm_t **pcmp, char *name, char *fname, int fd, char *fmt, snd_pcm_t *slave, int close_slave)
{
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
+ if (params->start_mode == pcm->start_mode &&
+ params->ready_mode == pcm->ready_mode &&
+ params->xrun_mode == pcm->xrun_mode &&
+ params->silence_mode == pcm->silence_mode &&
+ params->tstamp_mode == pcm->tstamp_mode &&
+ params->xfer_align == pcm->xfer_align &&
+ params->silence_threshold == pcm->silence_threshold &&
+ params->silence_size == pcm->silence_size) {
+ hw->mmap_control->avail_min = params->avail_min;
+ return 0;
+ }
if (ioctl(fd, SND_PCM_IOCTL_SW_PARAMS, params) < 0) {
SYSERR("SND_PCM_IOCTL_SW_PARAMS failed");
return -errno;
return avail;
}
-static int snd_pcm_hw_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_hw_t *hw = pcm->private;
- hw->mmap_control->avail_min = frames;
- return 0;
-}
-
static void snd_pcm_hw_dump(snd_pcm_t *pcm, FILE *fp)
{
snd_pcm_hw_t *hw = pcm->private;
readn: snd_pcm_hw_readn,
avail_update: snd_pcm_hw_avail_update,
mmap_forward: snd_pcm_hw_mmap_forward,
- set_avail_min: snd_pcm_hw_set_avail_min,
};
int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdevice, int stream, int mode)
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
linear->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave,
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
linear->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
- linear->conv_idx = conv_index(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT),
+ linear->conv_idx = conv_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT),
linear->sformat);
else
linear->conv_idx = conv_index(linear->sformat,
- snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT));
+ snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
return 0;
}
ssize_t (*readn)(snd_pcm_t *pcm, void **bufs, size_t size);
ssize_t (*avail_update)(snd_pcm_t *pcm);
ssize_t (*mmap_forward)(snd_pcm_t *pcm, size_t size);
- int (*set_avail_min)(snd_pcm_t *pcm, size_t frames);
} snd_pcm_fast_ops_t;
struct _snd_pcm {
size_t fragment_size; /* fragment size */
unsigned int fragments; /* fragments */
unsigned int start_mode; /* start mode */
- unsigned int ready_mode; /* ready detection mode */
unsigned int xrun_mode; /* xrun detection mode */
+ unsigned int ready_mode; /* ready detection mode */
+ unsigned int tstamp_mode; /* timestamp mode */
size_t avail_min; /* min avail frames for wakeup */
- size_t xfer_min; /* xfer min size */
+ unsigned int silence_mode; /* Silence filling mode */
+ size_t silence_threshold; /* Silence filling happens when
+ noise is nearest than this */
+ size_t silence_size; /* Silence filling size */
size_t xfer_align; /* xfer size need to be a multiple */
- unsigned int time: 1; /* timestamp switch */
size_t boundary; /* pointers wrap point */
unsigned int info; /* Info for returned setup */
unsigned int msbits; /* used most significant bits */
size_t bits_per_sample;
size_t bits_per_frame;
size_t *appl_ptr;
+ size_t min_align;
volatile size_t *hw_ptr;
int mmap_rw;
snd_pcm_channel_info_t *mmap_channels;
snd_pcm_xfer_areas_func_t func);
ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size);
ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size);
-int snd_pcm_hw_info_complete(snd_pcm_hw_params_t *info);
int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params);
void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
-int _snd_pcm_hw_params_mask(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
unsigned int var, const mask_t *mask);
-int _snd_pcm_hw_params_first(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
unsigned int var);
-int _snd_pcm_hw_params_last(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
unsigned int var);
-int _snd_pcm_hw_params_set(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, int hw,
unsigned int var, unsigned int val);
-int _snd_pcm_hw_params_min(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
unsigned int var, unsigned int val);
-int _snd_pcm_hw_params_max(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
unsigned int var, unsigned int val);
int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams,
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
- access_mask);
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ access_mask);
if (err < 0)
return err;
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
mask_t *format_mask = alloca(mask_sizeof());
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
- err = _snd_pcm_hw_params_mask(params, 1,
- SND_PCM_HW_PARAM_FORMAT,
- format_mask);
+ err = _snd_pcm_hw_param_mask(params, 1,
+ SND_PCM_HW_PARAM_FORMAT,
+ format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_params_set(params, 1,
- SND_PCM_HW_PARAM_FORMAT,
- SND_PCM_FORMAT_MU_LAW);
+ err = _snd_pcm_hw_param_set(params, 1,
+ SND_PCM_HW_PARAM_FORMAT,
+ SND_PCM_FORMAT_MU_LAW);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
- saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- mulaw->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ mulaw->sformat);
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave,
SND_PCM_HW_PARBIT_CHANNELS |
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
- saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- mulaw->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ mulaw->sformat);
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
SND_PCM_HW_PARBIT_CHANNELS |
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
- mulaw->getput_idx = get_index(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
+ mulaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT), SND_PCM_FORMAT_S16);
mulaw->func = mulaw_encode;
} else {
mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, mulaw->sformat);
}
} else {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
- mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT));
+ mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
mulaw->func = mulaw_decode;
} else {
mulaw->getput_idx = get_index(mulaw->sformat, SND_PCM_FORMAT_S16);
snd_pcm_hw_params_t sparams;
int changed = 0;
int err;
- const mask_t *access_mask = snd_pcm_hw_params_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
mask_t *saccess_mask = alloca(mask_sizeof());
if (mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
}
}
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
multi->channels_count);
if (err < 0)
return err;
for (k = 0; k < multi->slaves_count; ++k) {
snd_pcm_t *slave = multi->slaves[k].pcm;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0,
+ _snd_pcm_hw_param_mask(&sparams, 0,
SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0,
+ _snd_pcm_hw_param_set(&sparams, 0,
SND_PCM_HW_PARAM_CHANNELS,
multi->slaves[k].channels_count);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_multi_t *multi = pcm->private;
unsigned int k;
int err;
- const mask_t *access_mask = snd_pcm_hw_params_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
mask_t *saccess_mask = alloca(mask_sizeof());
if (mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
snd_pcm_t *slave = multi->slaves[k].pcm;
snd_pcm_hw_params_t sparams;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
multi->slaves[k].channels_count);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave,
return size;
}
-static int snd_pcm_multi_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_multi_t *multi = pcm->private;
- return snd_pcm_set_avail_min(multi->slaves[0].pcm, frames);
-}
-
static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
return 0;
rewind: snd_pcm_multi_rewind,
avail_update: snd_pcm_multi_avail_update,
mmap_forward: snd_pcm_multi_mmap_forward,
- set_avail_min: snd_pcm_multi_set_avail_min,
};
int snd_pcm_multi_open(snd_pcm_t **pcmp, char *name,
return pcm->buffer_size;
}
-static int snd_pcm_null_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- pcm->avail_min = frames;
- return 0;
-}
-
static int snd_pcm_null_hw_refine(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
{
- _snd_pcm_hw_refine(params);
+ int err = _snd_pcm_hw_refine(params);
params->fifo_size = 0;
- return 0;
+ return err;
}
static int snd_pcm_null_hw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t * params ATTRIBUTE_UNUSED)
return 0;
}
-static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params)
+static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED)
{
- if (params->start_mode > SND_PCM_START_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_START_MODE;
- return -EINVAL;
- }
- if (params->ready_mode > SND_PCM_READY_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_READY_MODE;
- return -EINVAL;
- }
- if (params->xrun_mode > SND_PCM_XRUN_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_XRUN_MODE;
- return -EINVAL;
- }
return 0;
}
readn: snd_pcm_null_readn,
avail_update: snd_pcm_null_avail_update,
mmap_forward: snd_pcm_null_mmap_forward,
- set_avail_min: snd_pcm_null_set_avail_min,
};
int snd_pcm_null_open(snd_pcm_t **pcmp, char *name, int stream, int mode)
*/
#include "pcm_local.h"
-#include "interval_inline.h"
+#define INTERVAL_INLINE
+#define MASK_INLINE
#include "interval.h"
#include "mask.h"
return 0;
}
-static inline int is_mask(int var)
+static inline int hw_is_mask(int var)
{
return var >= SND_PCM_HW_PARAM_FIRST_MASK &&
var <= SND_PCM_HW_PARAM_LAST_MASK;
}
-static inline int is_interval(int var)
+static inline int hw_is_interval(int var)
{
return var >= SND_PCM_HW_PARAM_FIRST_INTERVAL &&
var <= SND_PCM_HW_PARAM_LAST_INTERVAL;
}
-static inline mask_t *params_mask(snd_pcm_hw_params_t *params,
+static inline mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
unsigned int var)
{
- assert(is_mask(var));
+ assert(hw_is_mask(var));
return (mask_t*)¶ms->masks[var - SND_PCM_HW_PARAM_FIRST_MASK];
}
-static inline interval_t *params_interval(snd_pcm_hw_params_t *params,
+static inline interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
unsigned int var)
{
- assert(is_interval(var));
+ assert(hw_is_interval(var));
return ¶ms->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
}
-static inline const mask_t *params_mask_c(const snd_pcm_hw_params_t *params,
+static inline const mask_t *hw_param_mask_c(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- return (const mask_t *)params_mask((snd_pcm_hw_params_t*) params, var);
+ return (const mask_t *)hw_param_mask((snd_pcm_hw_params_t*) params, var);
}
-static inline const interval_t *params_interval_c(const snd_pcm_hw_params_t *params,
+static inline const interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- return (const interval_t *)params_interval((snd_pcm_hw_params_t*) params, var);
+ return (const interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
+}
+
+void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, unsigned int var)
+{
+ if (hw_is_mask(var)) {
+ mask_all(hw_param_mask(params, var));
+ params->appl_cmask |= 1 << var;
+ return;
+ }
+ if (hw_is_interval(var)) {
+ interval_all(hw_param_interval(params, var));
+ params->appl_cmask |= 1 << var;
+ return;
+ }
+ assert(0);
+}
+
+int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ unsigned int var)
+{
+ _snd_pcm_hw_param_any(params, var);
+ return snd_pcm_hw_refine(pcm, params);
}
void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
{
unsigned int k;
memset(params, 0, sizeof(*params));
- for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++) {
- mask_all(params_mask(params, k));
- params->appl_cmask |= 1 << k;
- }
-
- for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++) {
- interval_all(params_interval(params, k));
- params->appl_cmask |= 1 << k;
- }
- interval_setreal(params_interval(params, SND_PCM_HW_PARAM_RATE));
- interval_setreal(params_interval(params, SND_PCM_HW_PARAM_FRAGMENT_LENGTH));
- interval_setreal(params_interval(params, SND_PCM_HW_PARAM_BUFFER_LENGTH));
+ for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
+ _snd_pcm_hw_param_any(params, k);
+ interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_RATE));
+ interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_FRAGMENT_LENGTH));
+ interval_setreal(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_LENGTH));
params->info = ~0U;
}
/* Return the value for field PAR if it's fixed in configuration space
defined by PARAMS. Return -EINVAL otherwise
*/
-int snd_pcm_hw_params_value(const snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- if (is_mask(var)) {
- const mask_t *mask = params_mask_c(params, var);
+ if (hw_is_mask(var)) {
+ const mask_t *mask = hw_param_mask_c(params, var);
if (!mask_single(mask))
return -EINVAL;
return mask_value(mask);
}
- if (is_interval(var)) {
- const interval_t *i = params_interval_c(params, var);
+ if (hw_is_interval(var)) {
+ const interval_t *i = hw_param_interval_c(params, var);
if (!interval_single(i))
return -EINVAL;
return interval_value(i);
}
/* Return the minimum value for field PAR. */
-unsigned int snd_pcm_hw_params_value_min(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- if (is_mask(var)) {
- return mask_min(params_mask_c(params, var));
+ if (hw_is_mask(var)) {
+ return mask_min(hw_param_mask_c(params, var));
}
- if (is_interval(var)) {
- return interval_min(params_interval_c(params, var));
+ if (hw_is_interval(var)) {
+ return interval_min(hw_param_interval_c(params, var));
}
assert(0);
return -EINVAL;
}
/* Return the maximum value for field PAR. */
-unsigned int snd_pcm_hw_params_value_max(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- if (is_mask(var)) {
- return mask_max(params_mask_c(params, var));
+ if (hw_is_mask(var)) {
+ return mask_max(hw_param_mask_c(params, var));
}
- if (is_interval(var)) {
- return interval_max(params_interval_c(params, var));
+ if (hw_is_interval(var)) {
+ return interval_max(hw_param_interval_c(params, var));
}
assert(0);
return -EINVAL;
/* Return the mask for field PAR.
This function can be called only for SND_PCM_HW_PARAM_ACCESS,
SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT. */
-const mask_t *snd_pcm_hw_params_value_mask(const snd_pcm_hw_params_t *params,
+const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- assert(is_mask(var));
- return params_mask_c(params, var);
+ assert(hw_is_mask(var));
+ return hw_param_mask_c(params, var);
}
/* Return the interval for field PAR.
This function cannot be called for SND_PCM_HW_PARAM_ACCESS,
SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT. */
-const interval_t *snd_pcm_hw_params_value_interval(const snd_pcm_hw_params_t *params,
+const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- assert(is_interval(var));
- return params_interval_c(params, var);
+ assert(hw_is_interval(var));
+ return hw_param_interval_c(params, var);
}
/* --- Refinement functions --- */
-int _snd_pcm_hw_params_first(snd_pcm_hw_params_t *params, int hw,
- unsigned int var)
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
+ unsigned int var)
{
int changed;
- if (is_mask(var))
- changed = mask_refine_first(params_mask(params, var));
- else if (is_interval(var))
- changed = interval_refine_first(params_interval(params, var));
+ if (hw_is_mask(var))
+ changed = mask_refine_first(hw_param_mask(params, var));
+ else if (hw_is_interval(var))
+ changed = interval_refine_first(hw_param_interval(params, var));
else {
assert(0);
return -EINVAL;
values > minimum. Reduce configuration space accordingly.
Return the minimum.
*/
-int snd_pcm_hw_params_first(snd_pcm_t *pcm,
- snd_pcm_hw_params_t *params, unsigned int var)
+int snd_pcm_hw_param_first(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params, unsigned int var)
{
- int changed = _snd_pcm_hw_params_first(params, 0, var);
+ int changed = _snd_pcm_hw_param_first(params, 0, var);
if (changed < 0)
return changed;
if (changed) {
int err = snd_pcm_hw_refine(pcm, params);
assert(err >= 0);
}
- return snd_pcm_hw_params_value(params, var);
+ return snd_pcm_hw_param_value(params, var);
}
-int _snd_pcm_hw_params_last(snd_pcm_hw_params_t *params, int hw,
- unsigned int var)
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
+ unsigned int var)
{
int changed;
- if (is_mask(var))
- changed = mask_refine_last(params_mask(params, var));
- else if (is_interval(var))
- changed = interval_refine_last(params_interval(params, var));
+ if (hw_is_mask(var))
+ changed = mask_refine_last(hw_param_mask(params, var));
+ else if (hw_is_interval(var))
+ changed = interval_refine_last(hw_param_interval(params, var));
else {
assert(0);
return -EINVAL;
values < maximum. Reduce configuration space accordingly.
Return the maximum.
*/
-int snd_pcm_hw_params_last(snd_pcm_t *pcm,
- snd_pcm_hw_params_t *params, unsigned int var)
+int snd_pcm_hw_param_last(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params, unsigned int var)
{
- int changed = _snd_pcm_hw_params_last(params, 0, var);
+ int changed = _snd_pcm_hw_param_last(params, 0, var);
if (changed < 0)
return changed;
if (changed) {
int err = snd_pcm_hw_refine(pcm, params);
assert(err >= 0);
}
- return snd_pcm_hw_params_value(params, var);
+ return snd_pcm_hw_param_value(params, var);
}
-int _snd_pcm_hw_params_min(snd_pcm_hw_params_t *params, int hw,
- unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
+ unsigned int var, unsigned int val)
{
int changed;
- if (is_mask(var))
- changed = mask_refine_min(params_mask(params, var), val);
- else if (is_interval(var))
- changed = interval_refine_min(params_interval(params, var), val);
+ if (hw_is_mask(var))
+ changed = mask_refine_min(hw_param_mask(params, var), val);
+ else if (hw_is_interval(var))
+ changed = interval_refine_min(hw_param_interval(params, var), val);
else {
assert(0);
return -EINVAL;
values < VAL. Reduce configuration space accordingly.
Return new minimum or -EINVAL if the configuration space is empty
*/
-int snd_pcm_hw_params_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val)
{
- int changed = _snd_pcm_hw_params_min(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_min(params, 0, var, val);
if (changed < 0)
return changed;
if (changed) {
if (err < 0)
return err;
}
- return snd_pcm_hw_params_value_min(params, var);
+ return snd_pcm_hw_param_value_min(params, var);
}
-int _snd_pcm_hw_params_max(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
unsigned int var, unsigned int val)
{
int changed;
- if (is_mask(var))
- changed = mask_refine_max(params_mask(params, var), val);
- else if (is_interval(var))
- changed = interval_refine_max(params_interval(params, var), val);
+ if (hw_is_mask(var))
+ changed = mask_refine_max(hw_param_mask(params, var), val);
+ else if (hw_is_interval(var))
+ changed = interval_refine_max(hw_param_interval(params, var), val);
else {
assert(0);
return -EINVAL;
values >= VAL + 1. Reduce configuration space accordingly.
Return new maximum or -EINVAL if the configuration space is empty
*/
-int snd_pcm_hw_params_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val)
{
- int changed = _snd_pcm_hw_params_max(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_max(params, 0, var, val);
if (changed < 0)
return changed;
if (changed) {
if (err < 0)
return err;
}
- return snd_pcm_hw_params_value_max(params, var);
+ return snd_pcm_hw_param_value_max(params, var);
}
-int _snd_pcm_hw_params_minmax(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
unsigned int var,
unsigned int min, unsigned int max)
{
int changed, c1, c2;
- if (is_mask(var)) {
- mask_t *mask = params_mask(params, var);
+ if (hw_is_mask(var)) {
+ mask_t *mask = hw_param_mask(params, var);
c1 = mask_refine_min(mask, min);
if (c1 < 0)
changed = c1;
changed = (c1 || c2);
}
}
- else if (is_interval(var)) {
- interval_t *i = params_interval(params, var);
+ else if (hw_is_interval(var)) {
+ interval_t *i = hw_param_interval(params, var);
c1 = interval_refine_min(i, min);
if (c1 < 0)
changed = c1;
values < MIN and all values > MAX. Reduce configuration space accordingly.
Return 0 or -EINVAL if the configuration space is empty
*/
-int snd_pcm_hw_params_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var,
unsigned int min, unsigned int max)
{
- int changed = _snd_pcm_hw_params_minmax(params, 0, var, min, max);
+ int changed = _snd_pcm_hw_param_minmax(params, 0, var, min, max);
if (changed < 0)
return changed;
if (changed) {
return 0;
}
-int _snd_pcm_hw_params_set(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, int hw,
unsigned int var, unsigned int val)
{
int changed;
- if (is_mask(var))
- changed = mask_refine_set(params_mask(params, var), val);
- else if (is_interval(var))
- changed = interval_refine_set(params_interval(params, var), val);
+ if (hw_is_mask(var))
+ changed = mask_refine_set(hw_param_mask(params, var), val);
+ else if (hw_is_interval(var))
+ changed = interval_refine_set(hw_param_interval(params, var), val);
else {
assert(0);
return -EINVAL;
values < VAL and >= VAL +1. Reduce configuration space accordingly.
Return VAL or -EINVAL if the configuration space is empty
*/
-int snd_pcm_hw_params_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val)
{
- int changed = _snd_pcm_hw_params_set(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_set(params, 0, var, val);
if (changed < 0)
return changed;
if (changed) {
if (err < 0)
return err;
}
- return snd_pcm_hw_params_value(params, var);
+ return snd_pcm_hw_param_value(params, var);
}
-int _snd_pcm_hw_params_mask(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
unsigned int var, const mask_t *val)
{
int changed;
- assert(is_mask(var));
- changed = mask_refine(params_mask(params, var), val);
+ assert(hw_is_mask(var));
+ changed = mask_refine(hw_param_mask(params, var), val);
if (changed) {
if (hw)
params->hw_cmask |= 1 << var;
Return 0 on success or -EINVAL
if the configuration space is empty
*/
-int snd_pcm_hw_params_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, const mask_t *val)
+int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ unsigned int var, const mask_t *val)
{
- int changed = _snd_pcm_hw_params_mask(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_mask(params, 0, var, val);
if (changed < 0)
return changed;
if (changed) {
SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT.
Return the value found.
*/
-int snd_pcm_hw_params_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val)
{
snd_pcm_hw_params_t save;
unsigned int max1 = val, min2 = add(val, 1);
unsigned int hw_cmask;
save = *params;
- v = snd_pcm_hw_params_max(pcm, params, var, max1);
+ v = snd_pcm_hw_param_max(pcm, params, var, max1);
if (v >= 0) {
int v1;
snd_pcm_hw_params_t params1;
if (val == (unsigned int)v)
goto _end;
params1 = save;
- v1 = snd_pcm_hw_params_min(pcm, ¶ms1, var, min2);
+ v1 = snd_pcm_hw_param_min(pcm, ¶ms1, var, min2);
if (v1 < 0)
goto _end;
if (val - v > v1 - val) {
}
} else {
*params = save;
- v = snd_pcm_hw_params_min(pcm, params, var, min2);
+ v = snd_pcm_hw_param_min(pcm, params, var, min2);
assert(v >= 0);
}
_end:
hw_cmask = params->hw_cmask;
- v = snd_pcm_hw_params_set(pcm, params, var, v);
+ v = snd_pcm_hw_param_set(pcm, params, var, v);
params->hw_cmask |= hw_cmask;
assert(v >= 0);
return v;
SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT.
Return the value found.
*/
-int snd_pcm_hw_params_next(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_next(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val,
unsigned int old)
{
min2 = add(old, 1);
}
save = *params;
- v = snd_pcm_hw_params_max(pcm, params, var, max1);
+ v = snd_pcm_hw_param_max(pcm, params, var, max1);
if (v >= 0) {
int v1;
snd_pcm_hw_params_t params1;
if (val == (unsigned int)v)
goto _end;
params1 = save;
- v1 = snd_pcm_hw_params_min(pcm, ¶ms1, var, min2);
+ v1 = snd_pcm_hw_param_min(pcm, ¶ms1, var, min2);
if (v1 < 0)
goto _end;
if (val - v > v1 - val) {
}
} else {
*params = save;
- v = snd_pcm_hw_params_min(pcm, params, var, min2);
+ v = snd_pcm_hw_param_min(pcm, params, var, min2);
if (v < 0)
return v;
}
_end:
- v = snd_pcm_hw_params_set(pcm, params, var, v);
+ v = snd_pcm_hw_param_set(pcm, params, var, v);
return v;
}
/* ---- end of refinement functions ---- */
-int snd_pcm_hw_params_empty(const snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- if (is_mask(var))
- return mask_empty(params_mask_c(params, var));
- if (is_interval(var))
- return interval_empty(params_interval_c(params, var));
+ if (hw_is_mask(var))
+ return mask_empty(hw_param_mask_c(params, var));
+ if (hw_is_interval(var))
+ return interval_empty(hw_param_interval_c(params, var));
assert(0);
return -EINVAL;
}
int err;
unsigned int hw_cmask = params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_ACCESS);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_ACCESS);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_FORMAT);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FORMAT);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_RATE);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_RATE);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_first(pcm, params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
- err = snd_pcm_hw_params_last(pcm, params, SND_PCM_HW_PARAM_FRAGMENTS);
+ err = snd_pcm_hw_param_last(pcm, params, SND_PCM_HW_PARAM_FRAGMENTS);
assert(err >= 0);
hw_cmask |= params->hw_cmask;
params->hw_cmask = hw_cmask;
}
-int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
- int err;
- assert(pcm && params);
- params->hw_cmask = 0;
- err = pcm->ops->hw_refine(pcm->op_arg, params);
- params->appl_cmask = 0;
- return err;
-}
-
-/* Install one of the configurations present in configuration
- space defined by PARAMS.
- The configuration choosen is that obtained fixing in this order:
- first access
- first format
- first subformat
- min channels
- min rate
- min fragment_size
- max fragments
- Return 0 on success or a negative number expressing the error.
-*/
-int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
-{
- int err;
- err = snd_pcm_hw_refine(pcm, params);
- if (err < 0)
- return err;
- snd_pcm_hw_params_choose(pcm, params);
- if (pcm->mmap_channels) {
- err = snd_pcm_munmap(pcm);
- if (err < 0)
- return err;
- }
- err = pcm->ops->hw_params(pcm->op_arg, params);
- if (err < 0)
- goto _mmap;
-
- pcm->setup = 1;
- pcm->access = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_ACCESS);
- pcm->format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
- pcm->subformat = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_SUBFORMAT);
- pcm->channels = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_CHANNELS);
- pcm->rate = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_RATE);
- pcm->fragment_size = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
- pcm->fragments = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FRAGMENTS);
- pcm->bits_per_sample = snd_pcm_format_physical_width(pcm->format);
- pcm->bits_per_frame = pcm->bits_per_sample * pcm->channels;
- pcm->buffer_size = pcm->fragment_size * pcm->fragments;
-
- pcm->info = params->info;
- pcm->msbits = params->msbits;
- pcm->rate_num = params->rate_num;
- pcm->rate_den = params->rate_den;
- pcm->fifo_size = params->fifo_size;
-
- /* Default sw params */
- pcm->start_mode = SND_PCM_START_DATA;
- pcm->ready_mode = SND_PCM_READY_FRAGMENT;
- pcm->xrun_mode = SND_PCM_XRUN_FRAGMENT;
- pcm->avail_min = pcm->fragment_size;
- pcm->xfer_min = pcm->fragment_size;
- pcm->xfer_align = pcm->fragment_size;
- pcm->time = 0;
- pcm->boundary = LONG_MAX - pcm->buffer_size * 2 - LONG_MAX % pcm->buffer_size;
-
- _mmap:
- if (pcm->setup &&
- (pcm->mmap_rw ||
- (pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED ||
- pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED ||
- pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX))) {
- int err;
- err = snd_pcm_mmap(pcm);
- if (err < 0)
- return err;
- }
- if (err >= 0)
- snd_pcm_prepare(pcm);
- return err;
-}
-
/* Strategies */
-struct _snd_pcm_strategy {
+struct _snd_pcm_hw_strategy {
unsigned int badness_min, badness_max;
int (*choose_param)(const snd_pcm_hw_params_t *params,
snd_pcm_t *pcm,
- const snd_pcm_strategy_t *strategy);
+ const snd_pcm_hw_strategy_t *strategy);
int (*next_value)(snd_pcm_hw_params_t *params,
unsigned int param,
int value,
snd_pcm_t *pcm,
- const snd_pcm_strategy_t *strategy);
+ const snd_pcm_hw_strategy_t *strategy);
int (*min_badness)(const snd_pcm_hw_params_t *params,
unsigned int max_badness,
snd_pcm_t *pcm,
- const snd_pcm_strategy_t *strategy);
+ const snd_pcm_hw_strategy_t *strategy);
void *private;
- void (*free)(snd_pcm_strategy_t *strategy);
+ void (*free)(snd_pcm_hw_strategy_t *strategy);
};
/* Independent badness */
-typedef struct _snd_pcm_strategy_simple snd_pcm_strategy_simple_t;
+typedef struct _snd_pcm_hw_strategy_simple snd_pcm_hw_strategy_simple_t;
-struct _snd_pcm_strategy_simple {
+struct _snd_pcm_hw_strategy_simple {
int valid;
unsigned int order;
int (*next_value)(snd_pcm_hw_params_t *params,
unsigned int param,
int value,
snd_pcm_t *pcm,
- const snd_pcm_strategy_simple_t *par);
+ const snd_pcm_hw_strategy_simple_t *par);
unsigned int (*min_badness)(const snd_pcm_hw_params_t *params,
unsigned int param,
snd_pcm_t *pcm,
- const snd_pcm_strategy_simple_t *par);
+ const snd_pcm_hw_strategy_simple_t *par);
void *private;
- void (*free)(snd_pcm_strategy_simple_t *strategy);
+ void (*free)(snd_pcm_hw_strategy_simple_t *strategy);
};
-typedef struct _snd_pcm_strategy_simple_near {
+typedef struct _snd_pcm_hw_strategy_simple_near {
int best;
unsigned int mul;
-} snd_pcm_strategy_simple_near_t;
+} snd_pcm_hw_strategy_simple_near_t;
-typedef struct _snd_pcm_strategy_simple_choices {
+typedef struct _snd_pcm_hw_strategy_simple_choices {
unsigned int count;
/* choices need to be sorted on ascending badness */
- snd_pcm_strategy_simple_choices_list_t *choices;
-} snd_pcm_strategy_simple_choices_t;
+ snd_pcm_hw_strategy_simple_choices_list_t *choices;
+} snd_pcm_hw_strategy_simple_choices_t;
-int snd_pcm_hw_params_test(const snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_test(const snd_pcm_hw_params_t *params,
unsigned int var, unsigned int val)
{
- if (is_mask(var)) {
- const mask_t *mask = params_mask_c(params, var);
+ if (hw_is_mask(var)) {
+ const mask_t *mask = hw_param_mask_c(params, var);
return mask_test(mask, val);
}
- if (is_interval(var)) {
- const interval_t *i = params_interval_c(params, var);
+ if (hw_is_interval(var)) {
+ const interval_t *i = hw_param_interval_c(params, var);
return interval_test(i, val);
}
assert(0);
return -EINVAL;
}
-unsigned int snd_pcm_hw_params_count(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_param_count(const snd_pcm_hw_params_t *params,
unsigned int var)
{
- if (is_mask(var)) {
- const mask_t *mask = params_mask_c(params, var);
+ if (hw_is_mask(var)) {
+ const mask_t *mask = hw_param_mask_c(params, var);
return mask_count(mask);
}
- if (is_interval(var)) {
- const interval_t *i = params_interval_c(params, var);
+ if (hw_is_interval(var)) {
+ const interval_t *i = hw_param_interval_c(params, var);
return interval_max(i) - interval_min(i) + 1;
}
assert(0);
return 0;
}
-void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *params, unsigned int var,
+int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params, int hw,
+ unsigned int var,
+ const snd_pcm_hw_params_t *src)
+{
+ int changed = 0;
+ if (hw_is_mask(var)) {
+ mask_t *d = hw_param_mask(params, var);
+ const mask_t *s = hw_param_mask_c(src, var);
+ changed = mask_refine(d, s);
+ } else if (hw_is_interval(var)) {
+ interval_t *d = hw_param_interval(params, var);
+ const interval_t *s = hw_param_interval_c(src, var);
+ changed = interval_refine(d, s);
+ } else
+ assert(0);
+ if (changed) {
+ if (hw)
+ params->hw_cmask |= 1 << var;
+ else
+ params->appl_cmask |= 1 << var;
+ }
+ return changed;
+}
+
+void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, unsigned int var,
const snd_pcm_hw_params_t *src)
{
- if (is_mask(var)) {
- mask_t *d = params_mask(params, var);
- const mask_t *s = params_mask_c(src, var);
+ if (hw_is_mask(var)) {
+ mask_t *d = hw_param_mask(params, var);
+ const mask_t *s = hw_param_mask_c(src, var);
mask_copy(d, s);
}
- if (is_interval(var)) {
- interval_t *d = params_interval(params, var);
- const interval_t *s = params_interval_c(src, var);
+ if (hw_is_interval(var)) {
+ interval_t *d = hw_param_interval(params, var);
+ const interval_t *s = hw_param_interval_c(src, var);
interval_copy(d, s);
}
assert(0);
}
-void snd_pcm_hw_params_dump(const snd_pcm_hw_params_t *params,
- unsigned int var, FILE *fp)
+void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params,
+ unsigned int var, FILE *fp)
{
- if (is_mask(var)) {
- const mask_t *mask = params_mask_c(params, var);
+ static const char *(*funcs[])(unsigned int k) = {
+ [SND_PCM_HW_PARAM_ACCESS] = snd_pcm_access_name,
+ [SND_PCM_HW_PARAM_FORMAT] = snd_pcm_format_name,
+ [SND_PCM_HW_PARAM_SUBFORMAT] = snd_pcm_subformat_name,
+ };
+ if (hw_is_mask(var)) {
+ const mask_t *mask = hw_param_mask_c(params, var);
if (mask_empty(mask))
fputs(" NONE", fp);
+ else if (mask_full(mask))
+ fputs(" ALL", fp);
else {
unsigned int k;
for (k = 0; k <= MASK_MAX; ++k) {
if (mask_test(mask, k)) {
+ const char *(*f)(unsigned int k);
putc(' ', fp);
- switch (var) {
- case SND_PCM_HW_PARAM_ACCESS:
- fputs(snd_pcm_access_name(k), fp);
- break;
- case SND_PCM_HW_PARAM_FORMAT:
- fputs(snd_pcm_format_name(k), fp);
- break;
- case SND_PCM_HW_PARAM_SUBFORMAT:
- fputs(snd_pcm_subformat_name(k), fp);
- break;
- default:
- assert(0);
- }
+ assert(var < sizeof(funcs) / sizeof(funcs[0]));
+ f = funcs[k];
+ assert(f);
+ fputs(f(k), fp);
}
}
}
return;
}
- if (is_interval(var)) {
- interval_print(params_interval_c(params, var), fp);
+ if (hw_is_interval(var)) {
+ interval_print(hw_param_interval_c(params, var), fp);
return;
}
assert(0);
}
-int snd_pcm_dump_hw_params(snd_pcm_hw_params_t *params, FILE *fp)
+int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, FILE *fp)
{
unsigned int k;
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++) {
fprintf(fp, "%s: ", snd_pcm_hw_param_name(k));
- snd_pcm_hw_params_dump(params, k, fp);
+ snd_pcm_hw_param_dump(params, k, fp);
putc('\n', fp);
}
return 0;
}
int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- const snd_pcm_strategy_t *strategy,
- unsigned int badness_min,
- unsigned int badness_max)
+ const snd_pcm_hw_strategy_t *strategy,
+ unsigned int badness_min,
+ unsigned int badness_max)
{
snd_pcm_hw_params_t best_params;
int var;
snd_pcm_hw_params_t params1;
#if 0
printf("\nBadness: %d\n", badness);
- snd_pcm_dump_hw_params(params, stdout);
+ snd_pcm_hw_params_dump(params, stdout);
#endif
if (badness < 0)
return badness;
return best_badness;
}
-void snd_pcm_strategy_simple_free(snd_pcm_strategy_t *strategy)
+void snd_pcm_hw_strategy_simple_free(snd_pcm_hw_strategy_t *strategy)
{
- snd_pcm_strategy_simple_t *pars = strategy->private;
+ snd_pcm_hw_strategy_simple_t *pars = strategy->private;
int k;
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
if (pars[k].valid && pars[k].free)
free(pars);
}
-int snd_pcm_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
+int snd_pcm_hw_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
snd_pcm_t *pcm ATTRIBUTE_UNUSED,
- const snd_pcm_strategy_t *strategy)
+ const snd_pcm_hw_strategy_t *strategy)
{
unsigned int var;
int best_var = -1;
- const snd_pcm_strategy_simple_t *pars = strategy->private;
+ const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
unsigned int min_choices = UINT_MAX;
unsigned int min_order = UINT_MAX;
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
- const snd_pcm_strategy_simple_t *p = &pars[var];
+ const snd_pcm_hw_strategy_simple_t *p = &pars[var];
unsigned int choices;
if (!p->valid)
continue;
- choices = snd_pcm_hw_params_count(params, var);
+ choices = snd_pcm_hw_param_count(params, var);
if (choices == 1)
continue;
assert(choices != 0);
return best_var;
}
-int snd_pcm_strategy_simple_next_value(snd_pcm_hw_params_t *params,
+int snd_pcm_hw_strategy_simple_next_value(snd_pcm_hw_params_t *params,
unsigned int var,
int value,
snd_pcm_t *pcm,
- const snd_pcm_strategy_t *strategy)
+ const snd_pcm_hw_strategy_t *strategy)
{
- const snd_pcm_strategy_simple_t *pars = strategy->private;
+ const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
assert(pars[var].valid);
return pars[var].next_value(params, var, value, pcm, &pars[var]);
}
-int snd_pcm_strategy_simple_min_badness(const snd_pcm_hw_params_t *params,
+int snd_pcm_hw_strategy_simple_min_badness(const snd_pcm_hw_params_t *params,
unsigned int max_badness,
snd_pcm_t *pcm,
- const snd_pcm_strategy_t *strategy)
+ const snd_pcm_hw_strategy_t *strategy)
{
unsigned int var;
unsigned int badness = 0;
- const snd_pcm_strategy_simple_t *pars = strategy->private;
+ const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
unsigned int b;
if (!pars[var].valid)
}
-void snd_pcm_strategy_simple_near_free(snd_pcm_strategy_simple_t *par)
+void snd_pcm_hw_strategy_simple_near_free(snd_pcm_hw_strategy_simple_t *par)
{
- snd_pcm_strategy_simple_near_t *p = par->private;
+ snd_pcm_hw_strategy_simple_near_t *p = par->private;
free(p);
}
-unsigned int snd_pcm_strategy_simple_near_min_badness(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_strategy_simple_near_min_badness(const snd_pcm_hw_params_t *params,
unsigned int var,
snd_pcm_t *pcm,
- const snd_pcm_strategy_simple_t *par)
+ const snd_pcm_hw_strategy_simple_t *par)
{
- const snd_pcm_strategy_simple_near_t *p = par->private;
+ const snd_pcm_hw_strategy_simple_near_t *p = par->private;
snd_pcm_hw_params_t params1 = *params;
- int value = snd_pcm_hw_params_near(pcm, ¶ms1, var, p->best);
+ int value = snd_pcm_hw_param_near(pcm, ¶ms1, var, p->best);
int diff;
assert(value >= 0);
diff = p->best - value;
return diff * p->mul;
}
-int snd_pcm_strategy_simple_near_next_value(snd_pcm_hw_params_t *params,
+int snd_pcm_hw_strategy_simple_near_next_value(snd_pcm_hw_params_t *params,
unsigned int var,
int value,
snd_pcm_t *pcm,
- const snd_pcm_strategy_simple_t *par)
+ const snd_pcm_hw_strategy_simple_t *par)
{
- const snd_pcm_strategy_simple_near_t *p = par->private;
+ const snd_pcm_hw_strategy_simple_near_t *p = par->private;
if (value < 0)
- return snd_pcm_hw_params_near(pcm, params, var, p->best);
+ return snd_pcm_hw_param_near(pcm, params, var, p->best);
else
- return snd_pcm_hw_params_next(pcm, params, var, p->best, value);
+ return snd_pcm_hw_param_next(pcm, params, var, p->best, value);
}
-void snd_pcm_strategy_simple_choices_free(snd_pcm_strategy_simple_t *par)
+void snd_pcm_hw_strategy_simple_choices_free(snd_pcm_hw_strategy_simple_t *par)
{
- snd_pcm_strategy_simple_choices_t *p = par->private;
+ snd_pcm_hw_strategy_simple_choices_t *p = par->private;
// free(p->choices);
free(p);
}
-unsigned int snd_pcm_strategy_simple_choices_min_badness(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_strategy_simple_choices_min_badness(const snd_pcm_hw_params_t *params,
unsigned int var,
snd_pcm_t *pcm ATTRIBUTE_UNUSED,
- const snd_pcm_strategy_simple_t *par)
+ const snd_pcm_hw_strategy_simple_t *par)
{
- const snd_pcm_strategy_simple_choices_t *p = par->private;
+ const snd_pcm_hw_strategy_simple_choices_t *p = par->private;
unsigned int k;
for (k = 0; k < p->count; ++k) {
- if (snd_pcm_hw_params_test(params, var, p->choices[k].value))
+ if (snd_pcm_hw_param_test(params, var, p->choices[k].value))
return p->choices[k].badness;
}
assert(0);
return UINT_MAX;
}
-int snd_pcm_strategy_simple_choices_next_value(snd_pcm_hw_params_t *params,
+int snd_pcm_hw_strategy_simple_choices_next_value(snd_pcm_hw_params_t *params,
unsigned int var,
int value,
snd_pcm_t *pcm,
- const snd_pcm_strategy_simple_t *par)
+ const snd_pcm_hw_strategy_simple_t *par)
{
- const snd_pcm_strategy_simple_choices_t *p = par->private;
+ const snd_pcm_hw_strategy_simple_choices_t *p = par->private;
unsigned int k = 0;
if (value >= 0) {
for (; k < p->count; ++k) {
}
for (; k < p->count; ++k) {
unsigned int v = p->choices[k].value;
- if (snd_pcm_hw_params_test(params, var, v)) {
+ if (snd_pcm_hw_param_test(params, var, v)) {
snd_pcm_hw_params_t save = *params;
- int err = snd_pcm_hw_params_set(pcm, params, var, v);
+ int err = snd_pcm_hw_param_set(pcm, params, var, v);
if (err < 0) {
*params = save;
continue;
return -1;
}
-int snd_pcm_strategy_free(snd_pcm_strategy_t *strategy)
+int snd_pcm_hw_strategy_free(snd_pcm_hw_strategy_t *strategy)
{
if (strategy->free)
strategy->free(strategy);
return 0;
}
-int snd_pcm_strategy_simple(snd_pcm_strategy_t **strategyp,
+int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
unsigned int badness_min,
unsigned int badness_max)
{
- snd_pcm_strategy_simple_t *data;
- snd_pcm_strategy_t *s;
+ snd_pcm_hw_strategy_simple_t *data;
+ snd_pcm_hw_strategy_t *s;
assert(strategyp);
data = calloc(SND_PCM_HW_PARAM_LAST + 1, sizeof(*data));
if (!data)
free(data);
return -ENOMEM;
}
- s->choose_param = snd_pcm_strategy_simple_choose_param;
- s->next_value = snd_pcm_strategy_simple_next_value;
- s->min_badness = snd_pcm_strategy_simple_min_badness;
+ s->choose_param = snd_pcm_hw_strategy_simple_choose_param;
+ s->next_value = snd_pcm_hw_strategy_simple_next_value;
+ s->min_badness = snd_pcm_hw_strategy_simple_min_badness;
s->badness_min = badness_min;
s->badness_max = badness_max;
s->private = data;
- s->free = snd_pcm_strategy_simple_free;
+ s->free = snd_pcm_hw_strategy_simple_free;
*strategyp = s;
return 0;
}
-int snd_pcm_strategy_simple_near(snd_pcm_strategy_t *strategy,
+int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
int order,
unsigned int var,
unsigned int best,
unsigned int mul)
{
- snd_pcm_strategy_simple_t *s = strategy->private;
- snd_pcm_strategy_simple_near_t *data;
+ snd_pcm_hw_strategy_simple_t *s = strategy->private;
+ snd_pcm_hw_strategy_simple_near_t *data;
assert(strategy);
assert(var <= SND_PCM_HW_PARAM_LAST);
assert(!s->valid);
s += var;
s->order = order;
s->valid = 1;
- s->next_value = snd_pcm_strategy_simple_near_next_value;
- s->min_badness = snd_pcm_strategy_simple_near_min_badness;
+ s->next_value = snd_pcm_hw_strategy_simple_near_next_value;
+ s->min_badness = snd_pcm_hw_strategy_simple_near_min_badness;
s->private = data;
- s->free = snd_pcm_strategy_simple_near_free;
+ s->free = snd_pcm_hw_strategy_simple_near_free;
return 0;
}
-int snd_pcm_strategy_simple_choices(snd_pcm_strategy_t *strategy,
+int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy,
int order,
unsigned int var,
unsigned int count,
- snd_pcm_strategy_simple_choices_list_t *choices)
+ snd_pcm_hw_strategy_simple_choices_list_t *choices)
{
- snd_pcm_strategy_simple_t *s = strategy->private;
- snd_pcm_strategy_simple_choices_t *data;
+ snd_pcm_hw_strategy_simple_t *s = strategy->private;
+ snd_pcm_hw_strategy_simple_choices_t *data;
assert(strategy);
assert(var <= SND_PCM_HW_PARAM_LAST);
assert(!s->valid);
s += var;
s->valid = 1;
s->order = order;
- s->next_value = snd_pcm_strategy_simple_choices_next_value;
- s->min_badness = snd_pcm_strategy_simple_choices_min_badness;
+ s->next_value = snd_pcm_hw_strategy_simple_choices_next_value;
+ s->min_badness = snd_pcm_hw_strategy_simple_choices_min_badness;
s->private = data;
- s->free = snd_pcm_strategy_simple_choices_free;
+ s->free = snd_pcm_hw_strategy_simple_choices_free;
return 0;
}
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
int err;
i = *success;
- snd_pcm_hw_params_copy(&i, var, fail);
+ snd_pcm_hw_param_copy(&i, var, fail);
err = snd_pcm_hw_refine(pcm, &i);
if (err == 0 &&
snd_pcm_hw_params_try_explain_failure1(pcm, fail, &i, depth - 1, fp) < 0)
continue;
fprintf(fp, "%s: ", snd_pcm_hw_param_name(var));
- snd_pcm_hw_params_dump(fail, var, fp);
+ snd_pcm_hw_param_dump(fail, var, fp);
putc('\n', fp);
return 0;
}
int done = 0;
assert(pcm && fail);
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
- if (!snd_pcm_hw_params_empty(fail, var))
+ if (!snd_pcm_hw_param_empty(fail, var))
continue;
fprintf(fp, "%s is empty\n", snd_pcm_hw_param_name(var));
done = 1;
int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_mul(params_interval(params, rule->var),
- params_interval(params, rule->deps[0]),
- params_interval(params, rule->deps[1]));
+ return interval_mul(hw_param_interval(params, rule->var),
+ hw_param_interval(params, rule->deps[0]),
+ hw_param_interval(params, rule->deps[1]));
}
int snd_pcm_hw_rule_div(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_div(params_interval(params, rule->var),
- params_interval(params, rule->deps[0]),
- params_interval(params, rule->deps[1]));
+ return interval_div(hw_param_interval(params, rule->var),
+ hw_param_interval(params, rule->deps[0]),
+ hw_param_interval(params, rule->deps[1]));
}
int snd_pcm_hw_rule_muldivk(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_muldivk(params_interval(params, rule->var),
+ return interval_muldivk(hw_param_interval(params, rule->var),
(unsigned long) rule->private,
- params_interval(params, rule->deps[0]),
- params_interval(params, rule->deps[1]));
+ hw_param_interval(params, rule->deps[0]),
+ hw_param_interval(params, rule->deps[1]));
}
int snd_pcm_hw_rule_mulkdiv(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_mulkdiv(params_interval(params, rule->var),
+ return interval_mulkdiv(hw_param_interval(params, rule->var),
(unsigned long) rule->private,
- params_interval(params, rule->deps[0]),
- params_interval(params, rule->deps[1]));
+ hw_param_interval(params, rule->deps[0]),
+ hw_param_interval(params, rule->deps[1]));
}
int snd_pcm_hw_rule_format(snd_pcm_hw_params_t *params,
{
int changed = 0;
unsigned int k;
- mask_t *mask = params_mask(params, rule->var);
- interval_t *i = params_interval(params, rule->deps[0]);
+ mask_t *mask = hw_param_mask(params, rule->var);
+ interval_t *i = hw_param_interval(params, rule->deps[0]);
for (k = 0; k <= SND_PCM_FORMAT_LAST; ++k) {
int bits;
if (!mask_test(mask, k))
{
unsigned int min, max;
unsigned int k;
- interval_t *i = params_interval(params, rule->var);
- mask_t *mask = params_mask(params, rule->deps[0]);
+ interval_t *i = hw_param_interval(params, rule->var);
+ mask_t *mask = hw_param_mask(params, rule->deps[0]);
int c, changed = 0;
min = UINT_MAX;
max = 0;
return changed;
}
-snd_pcm_hw_rule_t snd_pcm_hw_rules[] = {
+static snd_pcm_hw_rule_t refine_rules[] = {
{
var: SND_PCM_HW_PARAM_FORMAT,
func: snd_pcm_hw_rule_format,
},
};
-#define RULES (sizeof(snd_pcm_hw_rules) / sizeof(snd_pcm_hw_rules[0]))
+#define RULES (sizeof(refine_rules) / sizeof(refine_rules[0]))
+
+static mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_MASK + 1] = {
+ [SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK] = {
+ bits: (1 << (SND_PCM_ACCESS_LAST + 1)) - 1,
+ },
+ [SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK] = {
+ bits: 0x81ffffff,
+ },
+ [SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK] = {
+ bits: (1 << (SND_PCM_SUBFORMAT_LAST + 1)) - 1,
+ },
+};
+
+static interval_t refine_intervals[SND_PCM_HW_PARAM_LAST_INTERVAL - SND_PCM_HW_PARAM_FIRST_INTERVAL + 1] = {
+ [SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_FRAGMENT_LENGTH - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_FRAGMENT_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_FRAGMENTS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_BUFFER_LENGTH - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_BUFFER_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_SAMPLE_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_FRAGMENT_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_BUFFER_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 1, max: UINT_MAX,
+ openmin: 0, openmax: 0, real: 0, empty: 0,
+ },
+};
+
+
int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
{
unsigned int k;
interval_t *i;
- snd_pcm_hw_rule_t *rules = snd_pcm_hw_rules;
unsigned int rstamps[RULES];
unsigned int vstamps[SND_PCM_HW_PARAM_LAST + 1];
unsigned int stamp = 2;
int err, changed;
+ for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++) {
+ if (!params->appl_cmask & (1 << k))
+ continue;
+ err = mask_refine(hw_param_mask(params, k),
+ &refine_masks[k - SND_PCM_HW_PARAM_FIRST_MASK]);
+ if (err < 0)
+ return err;
+ }
+
+ for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++) {
+ if (!params->appl_cmask & (1 << k))
+ continue;
+ err = interval_refine(hw_param_interval(params, k),
+ &refine_intervals[k - SND_PCM_HW_PARAM_FIRST_INTERVAL]);
+ if (err < 0)
+ return err;
+ }
+
for (k = 0; k < RULES; k++)
rstamps[k] = 0;
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
while (changed) {
changed = 0;
for (k = 0; k < RULES; k++) {
- snd_pcm_hw_rule_t *r = &rules[k];
+ snd_pcm_hw_rule_t *r = &refine_rules[k];
unsigned int d;
int doit = 0;
#ifdef RULES_DEBUG
if (!doit)
continue;
#ifdef RULES_DEBUG
- i = params_interval(params, r->var);
+ i = hw_param_interval(params, r->var);
fprintf(stderr, "Rule %d: %u ", k, r->var);
interval_print(i, stderr);
#endif
}
}
if (!params->msbits) {
- i = params_interval(params, SND_PCM_HW_PARAM_SAMPLE_BITS);
+ i = hw_param_interval(params, SND_PCM_HW_PARAM_SAMPLE_BITS);
if (interval_single(i))
params->msbits = interval_value(i);
}
if (!params->rate_den) {
- i = params_interval(params, SND_PCM_HW_PARAM_RATE);
+ i = hw_param_interval(params, SND_PCM_HW_PARAM_RATE);
if (interval_single(i)) {
params->rate_num = interval_value(i);
params->rate_den = 1;
return 0;
}
-int snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params, unsigned int var,
- const snd_pcm_hw_params_t *src)
-{
- if (is_mask(var)) {
- mask_t *d = params_mask(params, var);
- const mask_t *s = params_mask_c(src, var);
- return mask_refine(d, s);
- }
- if (is_interval(var)) {
- interval_t *d = params_interval(params, var);
- const interval_t *s = params_interval_c(src, var);
- return interval_refine(d, s);
- }
- assert(0);
- return -EINVAL;
-}
-
int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams,
int (*func)(snd_pcm_t *slave,
continue;
if (!(client_from_slave & (1 << k)))
continue;
- changed = snd_pcm_hw_params_refine(params, k, sparams);
+ changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
if (changed) {
hw_cmask |= 1 << k;
slave_from_client |= 1 << k;
continue;
if (!(slave_from_client & (1 << k)))
continue;
- changed = snd_pcm_hw_params_refine(sparams, k, params);
+ changed = _snd_pcm_hw_param_refine(sparams, 1, k, params);
if (changed) {
slave_refine |= 1 << k;
client_from_slave |= 1 << k;
int changed;
if (!(links & (1 << k)))
continue;
- changed = snd_pcm_hw_params_refine(sparams, k, params);
+ changed = _snd_pcm_hw_param_refine(sparams, 0, k, params);
if (changed < 0)
return changed;
}
continue;
if (!(sparams->hw_cmask & (1 << k)))
continue;
- changed = snd_pcm_hw_params_refine(params, k, sparams);
- if (changed)
- params->hw_cmask |= 1 << k;
+ changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
+ }
+ return err;
+}
+
+int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
+{
+ assert(pcm && params);
+ assert(pcm->setup);
+ params->start_mode = pcm->start_mode;
+ params->ready_mode = pcm->ready_mode;
+ params->xrun_mode = pcm->xrun_mode;
+ params->silence_mode = pcm->silence_mode;
+ params->tstamp_mode = pcm->tstamp_mode;
+ params->avail_min = pcm->avail_min;
+ params->xfer_align = pcm->xfer_align;
+ params->silence_threshold = pcm->silence_threshold;
+ params->silence_size = pcm->silence_size;
+ params->boundary = pcm->boundary;
+ return 0;
+}
+
+int snd_pcm_sw_params_default(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
+{
+ assert(pcm && params);
+ assert(pcm->setup);
+ params->start_mode = SND_PCM_START_DATA;
+ params->ready_mode = SND_PCM_READY_FRAGMENT;
+ params->xrun_mode = SND_PCM_XRUN_FRAGMENT;
+ params->silence_mode = SND_PCM_SILENCE_FRAGMENT;
+ params->tstamp_mode = SND_PCM_TSTAMP_NONE;
+ params->avail_min = pcm->fragment_size;
+ params->xfer_align = pcm->fragment_size;
+ params->silence_threshold = 0;
+ params->silence_size = 0;
+ params->boundary = LONG_MAX - pcm->buffer_size * 2 - LONG_MAX % pcm->buffer_size;
+ return 0;
+}
+
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var)
+{
+ switch (var) {
+ case SND_PCM_SW_PARAM_START_MODE:
+ return params->start_mode;
+ case SND_PCM_SW_PARAM_READY_MODE:
+ return params->ready_mode;
+ case SND_PCM_SW_PARAM_XRUN_MODE:
+ return params->xrun_mode;
+ case SND_PCM_SW_PARAM_SILENCE_MODE:
+ return params->silence_mode;
+ case SND_PCM_SW_PARAM_TSTAMP_MODE:
+ return params->tstamp_mode;
+ case SND_PCM_SW_PARAM_AVAIL_MIN:
+ return params->avail_min;
+ case SND_PCM_SW_PARAM_XFER_ALIGN:
+ return params->xfer_align;
+ case SND_PCM_SW_PARAM_SILENCE_THRESHOLD:
+ return params->silence_threshold;
+ case SND_PCM_SW_PARAM_SILENCE_SIZE:
+ return params->silence_size;
+ default:
+ assert(0);
+ return -EINVAL;
+ }
+}
+
+int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
+ unsigned int var, unsigned int val)
+{
+ switch (var) {
+ case SND_PCM_SW_PARAM_START_MODE:
+ assert(val <= SND_PCM_START_LAST);
+ params->start_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_READY_MODE:
+ assert(val <= SND_PCM_READY_LAST);
+ params->ready_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_XRUN_MODE:
+ assert(val <= SND_PCM_XRUN_LAST);
+ params->xrun_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_MODE:
+ assert(val <= SND_PCM_SILENCE_LAST);
+ params->silence_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_TSTAMP_MODE:
+ assert(val <= SND_PCM_TSTAMP_LAST);
+ params->tstamp_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_AVAIL_MIN:
+ assert(val > 0);
+ params->avail_min = val;
+ break;
+ case SND_PCM_SW_PARAM_XFER_ALIGN:
+ assert(val > 0 && val % pcm->min_align == 0);
+ params->xfer_align = val;
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_THRESHOLD:
+ assert(val + params->silence_size <= pcm->buffer_size);
+ params->silence_threshold = val;
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_SIZE:
+ assert(val + params->silence_threshold <= pcm->buffer_size);
+ params->silence_size = val;
+ break;
+ default:
+ assert(0);
+ return -EINVAL;
+ }
+ return val;
+}
+
+int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
+ unsigned int var, unsigned int val)
+{
+ switch (var) {
+ case SND_PCM_SW_PARAM_START_MODE:
+ assert(val <= SND_PCM_START_LAST);
+ params->start_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_READY_MODE:
+ assert(val <= SND_PCM_READY_LAST);
+ params->ready_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_XRUN_MODE:
+ assert(val <= SND_PCM_XRUN_LAST);
+ params->xrun_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_MODE:
+ assert(val <= SND_PCM_SILENCE_LAST);
+ params->silence_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_TSTAMP_MODE:
+ assert(val <= SND_PCM_TSTAMP_LAST);
+ params->tstamp_mode = val;
+ break;
+ case SND_PCM_SW_PARAM_AVAIL_MIN:
+ if (val == 0)
+ val = pcm->min_align;
+ params->avail_min = val;
+ break;
+ case SND_PCM_SW_PARAM_XFER_ALIGN:
+ {
+ size_t r = val % pcm->min_align;
+ if (r >= (pcm->min_align + 1) / 2)
+ val += pcm->min_align - r;
+ else
+ val -= r;
+ if (val == 0)
+ val = pcm->min_align;
+ params->xfer_align = val;
+ break;
+ }
+ case SND_PCM_SW_PARAM_SILENCE_THRESHOLD:
+ if (val > pcm->buffer_size - params->silence_size)
+ val = pcm->buffer_size - params->silence_size;
+ params->silence_threshold = val;
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_SIZE:
+ if (val > pcm->buffer_size - params->silence_threshold)
+ val = pcm->buffer_size - params->silence_threshold;
+ params->silence_size = val;
+ break;
+ default:
+ assert(0);
+ return -EINVAL;
+ }
+ return val;
+}
+
+void snd_pcm_sw_param_dump(const snd_pcm_sw_params_t *params,
+ unsigned int var, FILE *fp)
+{
+ switch (var) {
+ case SND_PCM_SW_PARAM_START_MODE:
+ fputs(snd_pcm_start_mode_name(params->start_mode), fp);
+ break;
+ case SND_PCM_SW_PARAM_READY_MODE:
+ fputs(snd_pcm_ready_mode_name(params->ready_mode), fp);
+ break;
+ case SND_PCM_SW_PARAM_XRUN_MODE:
+ fputs(snd_pcm_xrun_mode_name(params->xrun_mode), fp);
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_MODE:
+ fputs(snd_pcm_silence_mode_name(params->silence_mode), fp);
+ break;
+ case SND_PCM_SW_PARAM_TSTAMP_MODE:
+ fputs(snd_pcm_tstamp_mode_name(params->tstamp_mode), fp);
+ break;
+ case SND_PCM_SW_PARAM_AVAIL_MIN:
+ fprintf(fp, "%ld", (long) params->avail_min);
+ break;
+ case SND_PCM_SW_PARAM_XFER_ALIGN:
+ fprintf(fp, "%ld", (long) params->xfer_align);
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_THRESHOLD:
+ fprintf(fp, "%ld", (long) params->silence_threshold);
+ break;
+ case SND_PCM_SW_PARAM_SILENCE_SIZE:
+ fprintf(fp, "%ld", (long) params->silence_size);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp)
+{
+ unsigned int k;
+ for (k = 0; k <= SND_PCM_SW_PARAM_LAST; k++) {
+ fprintf(fp, "%s: ", snd_pcm_sw_param_name(k));
+ snd_pcm_sw_param_dump(params, k, fp);
+ putc('\n', fp);
+ }
+ return 0;
+}
+
+
+int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+ int err;
+ assert(pcm && params);
+ params->hw_cmask = 0;
+ err = pcm->ops->hw_refine(pcm->op_arg, params);
+ params->appl_cmask = 0;
+ return err;
+}
+
+/* Install one of the configurations present in configuration
+ space defined by PARAMS.
+ The configuration choosen is that obtained fixing in this order:
+ first access
+ first format
+ first subformat
+ min channels
+ min rate
+ min fragment_size
+ max fragments
+ Return 0 on success or a negative number expressing the error.
+*/
+int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+{
+ int err;
+ snd_pcm_sw_params_t sw;
+ int fb, min_align;
+ err = snd_pcm_hw_refine(pcm, params);
+ if (err < 0)
+ return err;
+ snd_pcm_hw_params_choose(pcm, params);
+ if (pcm->mmap_channels) {
+ err = snd_pcm_munmap(pcm);
+ if (err < 0)
+ return err;
+ }
+ err = pcm->ops->hw_params(pcm->op_arg, params);
+ if (err < 0)
+ goto _mmap;
+
+ pcm->setup = 1;
+ pcm->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS);
+ pcm->format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ pcm->subformat = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_SUBFORMAT);
+ pcm->channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS);
+ pcm->rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+ pcm->fragment_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
+ pcm->fragments = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FRAGMENTS);
+ pcm->bits_per_sample = snd_pcm_format_physical_width(pcm->format);
+ pcm->bits_per_frame = pcm->bits_per_sample * pcm->channels;
+ fb = pcm->bits_per_frame;
+ min_align = 1;
+ while (fb % 8) {
+ fb *= 2;
+ min_align *= 2;
+ }
+ pcm->min_align = min_align;
+ pcm->buffer_size = pcm->fragment_size * pcm->fragments;
+
+ pcm->info = params->info;
+ pcm->msbits = params->msbits;
+ pcm->rate_num = params->rate_num;
+ pcm->rate_den = params->rate_den;
+ pcm->fifo_size = params->fifo_size;
+ /* Default sw params */
+ snd_pcm_sw_params_default(pcm, &sw);
+ err = snd_pcm_sw_params(pcm, &sw);
+ assert(err >= 0);
+
+ _mmap:
+ if (pcm->setup &&
+ (pcm->mmap_rw ||
+ (pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED ||
+ pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED ||
+ pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX))) {
+ int err;
+ err = snd_pcm_mmap(pcm);
+ if (err < 0)
+ return err;
}
+ if (err >= 0)
+ err = snd_pcm_prepare(pcm);
return err;
}
+int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
+{
+ int err;
+ err = pcm->ops->sw_params(pcm->op_arg, params);
+ if (err < 0)
+ return err;
+ pcm->start_mode = params->start_mode;
+ pcm->ready_mode = params->ready_mode;
+ pcm->xrun_mode = params->xrun_mode;
+ pcm->silence_mode = params->silence_mode;
+ pcm->tstamp_mode = params->tstamp_mode;
+ pcm->avail_min = params->avail_min;
+ pcm->xfer_align = params->xfer_align;
+ pcm->silence_threshold = params->silence_threshold;
+ pcm->silence_size = params->silence_size;
+ pcm->boundary = params->boundary;
+ return 0;
+}
+
mask_load(mmap_mask, SND_PCM_ACCBIT_MMAP);
mask_load(fmtplug_mask, SND_PCM_FMTBIT_PLUG);
- err = _snd_pcm_hw_params_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
+ err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_min(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MIN);
+ err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MIN);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_max(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MAX);
+ err = _snd_pcm_hw_param_max(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MAX);
if (err < 0)
return err;
if (err < 0)
return err;
- rate_min = snd_pcm_hw_params_value_min(params, SND_PCM_HW_PARAM_RATE);
- rate_max = snd_pcm_hw_params_value_max(params, SND_PCM_HW_PARAM_RATE);
+ rate_min = snd_pcm_hw_param_value_min(params, SND_PCM_HW_PARAM_RATE);
+ rate_max = snd_pcm_hw_param_value_max(params, SND_PCM_HW_PARAM_RATE);
tmp = *sparams;
- srate_min = snd_pcm_hw_params_near(slave, &tmp,
+ srate_min = snd_pcm_hw_param_near(slave, &tmp,
SND_PCM_HW_PARAM_RATE, rate_min);
if (srate_min < rate_max) {
tmp = *sparams;
- srate_max = snd_pcm_hw_params_near(slave, &tmp,
+ srate_max = snd_pcm_hw_param_near(slave, &tmp,
SND_PCM_HW_PARAM_RATE, rate_max);
} else
srate_max = srate_min;
- err = snd_pcm_hw_params_minmax(slave, sparams,
+ err = snd_pcm_hw_param_minmax(slave, sparams,
SND_PCM_HW_PARAM_RATE,
srate_min, srate_max);
assert(err >= 0);
- channels_min = snd_pcm_hw_params_value_min(params, SND_PCM_HW_PARAM_CHANNELS);
- channels_max = snd_pcm_hw_params_value_max(params, SND_PCM_HW_PARAM_CHANNELS);
+ channels_min = snd_pcm_hw_param_value_min(params, SND_PCM_HW_PARAM_CHANNELS);
+ channels_max = snd_pcm_hw_param_value_max(params, SND_PCM_HW_PARAM_CHANNELS);
tmp = *sparams;
- schannels_min = snd_pcm_hw_params_near(slave, &tmp,
+ schannels_min = snd_pcm_hw_param_near(slave, &tmp,
SND_PCM_HW_PARAM_CHANNELS, channels_min);
if (schannels_min < channels_max) {
tmp = *sparams;
- schannels_max = snd_pcm_hw_params_near(slave, &tmp,
+ schannels_max = snd_pcm_hw_param_near(slave, &tmp,
SND_PCM_HW_PARAM_CHANNELS, channels_max);
} else
schannels_max = schannels_min;
- err = snd_pcm_hw_params_minmax(slave, sparams,
+ err = snd_pcm_hw_param_minmax(slave, sparams,
SND_PCM_HW_PARAM_CHANNELS,
schannels_min, schannels_max);
assert(err >= 0);
- format_mask = snd_pcm_hw_params_value_mask(params,
+ format_mask = snd_pcm_hw_param_value_mask(params,
SND_PCM_HW_PARAM_FORMAT);
- sformat_mask = snd_pcm_hw_params_value_mask(sparams,
+ sformat_mask = snd_pcm_hw_param_value_mask(sparams,
SND_PCM_HW_PARAM_FORMAT);
mask_none(tmp_mask);
for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
mask_t *m = alloca(mask_sizeof());
mask_all(m);
mask_reset(m, format);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_FORMAT, m);
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT, m);
if (err < 0)
return err;
continue;
mask_set(tmp_mask, f);
}
- err = _snd_pcm_hw_params_mask(sparams, 0,
+ err = _snd_pcm_hw_param_mask(sparams, 0,
SND_PCM_HW_PARAM_FORMAT, tmp_mask);
assert(err >= 0);
- sformat_mask = snd_pcm_hw_params_value_mask(sparams,
+ sformat_mask = snd_pcm_hw_param_value_mask(sparams,
SND_PCM_HW_PARAM_FORMAT);
same_rate = (rate_min == rate_max &&
}
if (same_rate && same_channels && same_format) {
- const mask_t *access_mask = snd_pcm_hw_params_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
- mask_copy(tmp_mask, snd_pcm_hw_params_value_mask(sparams, SND_PCM_HW_PARAM_ACCESS));
+ const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ mask_copy(tmp_mask, snd_pcm_hw_param_value_mask(sparams, SND_PCM_HW_PARAM_ACCESS));
mask_intersect(tmp_mask, access_mask);
if (!mask_empty(tmp_mask))
- _snd_pcm_hw_params_mask(sparams, 0,
+ _snd_pcm_hw_param_mask(sparams, 0,
SND_PCM_HW_PARAM_ACCESS,
access_mask);
else
- _snd_pcm_hw_params_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
mmap_mask);
} else {
- err = _snd_pcm_hw_params_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params, 1,
SND_PCM_HW_PARAM_ACCESS,
accplug_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params, 1,
SND_PCM_HW_PARAM_FORMAT,
fmtplug_mask);
if (err < 0)
return err;
- _snd_pcm_hw_params_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
mmap_mask);
- _snd_pcm_hw_params_mask(sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_FORMAT,
fmtplug_mask);
}
err = snd_pcm_hw_refine2(params, sparams,
int err = snd_pcm_plug_hw_refine1(pcm, params, &sparams);
assert(err >= 0);
- clt_params.access = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_ACCESS);
- clt_params.format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
- clt_params.channels = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_CHANNELS);
- clt_params.rate = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_RATE);
+ clt_params.access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS);
+ clt_params.format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ clt_params.channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS);
+ clt_params.rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
- slv_params.access = snd_pcm_hw_params_first(slave, &sparams, SND_PCM_HW_PARAM_ACCESS);
- slv_params.format = snd_pcm_hw_params_value(&sparams, SND_PCM_HW_PARAM_FORMAT);
- slv_params.channels = snd_pcm_hw_params_value(&sparams, SND_PCM_HW_PARAM_CHANNELS);
- slv_params.rate = snd_pcm_hw_params_value(&sparams, SND_PCM_HW_PARAM_RATE);
+ slv_params.access = snd_pcm_hw_param_first(slave, &sparams, SND_PCM_HW_PARAM_ACCESS);
+ slv_params.format = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_FORMAT);
+ slv_params.channels = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_CHANNELS);
+ slv_params.rate = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_RATE);
snd_pcm_plug_clear(pcm);
err = snd_pcm_plug_insert_plugins(pcm, &clt_params, &slv_params);
{
snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *slave = plug->req_slave;
- size_t avail_min, xfer_min, xfer_align;
+ size_t avail_min, xfer_align, silence_threshold, silence_size;
int err;
avail_min = params->avail_min;
- xfer_min = params->xfer_min;
xfer_align = params->xfer_align;
+ silence_threshold = params->silence_threshold;
+ silence_size = params->silence_size;
params->avail_min = muldiv_near(params->avail_min, slave->rate, pcm->rate);
- params->xfer_min = muldiv_near(params->xfer_min, slave->rate, pcm->rate);
params->xfer_align = muldiv_near(params->xfer_align, slave->rate, pcm->rate);
+ params->silence_threshold = muldiv_near(params->silence_threshold, slave->rate, pcm->rate);
+ params->silence_size = muldiv_near(params->silence_size, slave->rate, pcm->rate);
err = snd_pcm_sw_params(slave, params);
params->avail_min = avail_min;
- params->xfer_min = xfer_min;
params->xfer_align = xfer_align;
+ params->silence_threshold = silence_threshold;
+ params->silence_size = silence_size;
params->boundary = LONG_MAX - pcm->buffer_size * 2 - LONG_MAX % pcm->buffer_size;
return err;
}
frames -= n;
}
if (frames > 0) {
- ssize_t err = snd_pcm_rewind(plugin->slave, frames);
+ ssize_t err;
+ /* FIXME: rate plugin */
+ if (plugin->slave_frames)
+ frames = plugin->slave_frames(pcm, frames);
+ err = snd_pcm_rewind(plugin->slave, frames);
if (err < 0) {
if (n <= 0)
return err;
return err;
}
-int snd_pcm_plugin_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_plugin_t *plugin = pcm->private;
- snd_pcm_t *slave = plugin->slave;
- return snd_pcm_set_avail_min(slave, frames);
-}
-
int snd_pcm_plugin_mmap(snd_pcm_t *pcm)
{
snd_pcm_plugin_t *plug = pcm->private;
readn: snd_pcm_plugin_readn,
avail_update: snd_pcm_plugin_avail_update,
mmap_forward: snd_pcm_plugin_mmap_forward,
- set_avail_min: snd_pcm_plugin_set_avail_min,
};
snd_pcm_xfer_areas_func_t read;
snd_pcm_xfer_areas_func_t write;
ssize_t (*client_frames)(snd_pcm_t *pcm, ssize_t frames);
+ ssize_t (*slave_frames)(snd_pcm_t *pcm, ssize_t frames);
int (*init)(snd_pcm_t *pcm);
int shmid;
size_t appl_ptr, hw_ptr;
int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
+int snd_pcm_plugin_sw_refine(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status);
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_min(params, 1,
+ err = _snd_pcm_hw_param_min(params, 1,
SND_PCM_HW_PARAM_RATE, RATE_MIN);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_max(params, 1,
+ err = _snd_pcm_hw_param_max(params, 1,
SND_PCM_HW_PARAM_RATE, RATE_MAX);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (rate->sformat >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
rate->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
} else
links |= (SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS |
SND_PCM_HW_PARBIT_FRAME_BITS);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
rate->srate);
err = snd_pcm_hw_refine2(params, &sparams,
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (rate->sformat >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
rate->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
} else
links |= (SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS |
SND_PCM_HW_PARBIT_FRAME_BITS);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
rate->srate);
err = snd_pcm_hw_params2(params, &sparams,
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- src_format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
+ src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
dst_format = slave->format;
- src_rate = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_RATE);
+ src_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
dst_rate = slave->rate;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
+ dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
src_rate = slave->rate;
- dst_rate = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_RATE);
+ dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
}
rate->get_idx = get_index(src_format, SND_PCM_FORMAT_S16);
rate->put_idx = put_index(SND_PCM_FORMAT_S16, dst_format);
rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate;
if (rate->states)
free(rate->states);
- rate->states = malloc(snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*rate->states));
+ rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*rate->states));
return 0;
}
{
snd_pcm_rate_t *rate = pcm->private;
snd_pcm_t *slave = rate->plug.slave;
- size_t avail_min, xfer_min, xfer_align;
+ size_t avail_min, xfer_align, silence_threshold, silence_size;
int err;
avail_min = params->avail_min;
- xfer_min = params->xfer_min;
xfer_align = params->xfer_align;
+ silence_threshold = params->silence_threshold;
+ silence_size = params->silence_size;
params->avail_min = muldiv_near(params->avail_min, slave->rate, pcm->rate);
- params->xfer_min = muldiv_near(params->xfer_min, slave->rate, pcm->rate);
params->xfer_align = muldiv_near(params->xfer_align, slave->rate, pcm->rate);
+ params->silence_threshold = muldiv_near(params->silence_threshold, slave->rate, pcm->rate);
+ params->silence_size = muldiv_near(params->silence_size, slave->rate, pcm->rate);
err = snd_pcm_sw_params(slave, params);
params->avail_min = avail_min;
- params->xfer_min = xfer_min;
params->xfer_align = xfer_align;
+ params->silence_threshold = silence_threshold;
+ params->silence_size = silence_size;
params->boundary = LONG_MAX - pcm->buffer_size * 2 - LONG_MAX % pcm->buffer_size;
return err;
}
return muldiv_down(frames, rate->pitch, DIV);
}
+ssize_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, ssize_t frames)
+{
+ snd_pcm_rate_t *rate = pcm->private;
+ /* Round toward zero */
+ if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
+ return muldiv_down(frames, rate->pitch, DIV);
+ else
+ return muldiv_down(frames, DIV, rate->pitch);
+}
+
static void snd_pcm_rate_dump(snd_pcm_t *pcm, FILE *fp)
{
snd_pcm_rate_t *rate = pcm->private;
rate->plug.read = snd_pcm_rate_read_areas;
rate->plug.write = snd_pcm_rate_write_areas;
rate->plug.client_frames = snd_pcm_rate_client_frames;
+ rate->plug.slave_frames = snd_pcm_rate_slave_frames;
rate->plug.init = snd_pcm_rate_init;
rate->plug.slave = slave;
rate->plug.close_slave = close_slave;
mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
mask_load(format_mask, SND_PCM_FMTBIT_LINEAR);
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_params_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
+ err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
if (err < 0)
return err;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (route->sformat >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
route->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
} else
links |= (SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS);
if (route->schannels >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
route->schannels);
} else {
links |= SND_PCM_HW_PARBIT_CHANNELS;
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (route->sformat >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
route->sformat);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
SND_PCM_SUBFORMAT_STD);
} else
links |= (SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS);
if (route->schannels >= 0) {
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
- route->schannels);
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
+ route->schannels);
} else {
links |= SND_PCM_HW_PARBIT_CHANNELS;
if (route->sformat < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- src_format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
+ src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
dst_format = slave->format;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_params_value(params, SND_PCM_HW_PARAM_FORMAT);
+ dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
}
route->params.get_idx = get_index(src_format, SND_PCM_FORMAT_U16);
route->params.put_idx = put_index(SND_PCM_FORMAT_U32, dst_format);
size_t running_count;
size_t safety_threshold;
size_t silence_frames;
+ snd_pcm_sw_params_t sw_params;
size_t hw_ptr;
int poll[2];
int polling;
if (avail_min < 0)
avail_min += spcm->boundary;
// printf("avail_min=%d\n", avail_min);
- if ((size_t)avail_min != spcm->avail_min)
- snd_pcm_set_avail_min(spcm, avail_min);
+ if ((size_t)avail_min != spcm->avail_min) {
+ snd_pcm_sw_param_near(spcm, &slave->sw_params, SND_PCM_SW_PARAM_AVAIL_MIN, avail_min);
+ err = snd_pcm_sw_params(spcm, &slave->sw_params);
+ assert(err >= 0);
+ }
slave->polling = 1;
Pthread_mutex_unlock(&slave->mutex);
err = poll(pfd, 2, -1);
if (missing < INT_MAX) {
size_t hw_ptr;
ssize_t avail_min;
+ int err;
hw_ptr = slave->hw_ptr + missing;
hw_ptr += spcm->fragment_size - 1;
if (hw_ptr >= spcm->boundary)
avail_min += spcm->buffer_size;
if (avail_min < 0)
avail_min += spcm->boundary;
- if ((size_t)avail_min < spcm->avail_min)
- snd_pcm_set_avail_min(spcm, avail_min);
+ if ((size_t)avail_min < spcm->avail_min) {
+ snd_pcm_sw_param_near(spcm, &slave->sw_params, SND_PCM_SW_PARAM_AVAIL_MIN, avail_min);
+ err = snd_pcm_sw_params(spcm, &slave->sw_params);
+ assert(err >= 0);
+ }
}
}
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
share->channels_count);
if (err < 0)
return err;
if (slave->format >= 0) {
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
slave->format);
if (err < 0)
return err;
}
if (slave->rate >= 0) {
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_RATE,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
slave->rate);
if (err < 0)
return err;
}
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
slave->channels_count);
err = snd_pcm_hw_refine2(params, &sparams,
snd_pcm_hw_refine, slave->pcm,
SND_PCM_HW_PARBIT_FRAGMENTS);
if (err < 0)
return err;
- mmap_mask = snd_pcm_hw_params_value_mask(&sparams, SND_PCM_HW_PARAM_ACCESS);
+ mmap_mask = snd_pcm_hw_param_value_mask(&sparams, SND_PCM_HW_PARAM_ACCESS);
mask_all(access_mask);
mask_reset(access_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
if (!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED))
if (!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_COMPLEX) &&
!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED))
mask_reset(access_mask, SND_PCM_ACCESS_MMAP_COMPLEX);
- err = _snd_pcm_hw_params_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
Pthread_mutex_lock(&slave->mutex);
if (slave->setup_count > 1 ||
(slave->setup_count == 1 && !pcm->setup)) {
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
spcm->format);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
spcm->subformat);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_RATE,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
spcm->rate);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENT_SIZE,
spcm->fragment_size);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_params_set(params, 1, SND_PCM_HW_PARAM_FRAGMENTS,
+ err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENTS,
spcm->fragments);
_err:
if (err < 0) {
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_params_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
+ _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
share->channels_count);
err = snd_pcm_hw_params2(params, &sparams,
snd_pcm_hw_params, slave->pcm,
SND_PCM_HW_PARBIT_FRAGMENTS);
if (err < 0)
goto _end;
+ snd_pcm_sw_params_current(slave->pcm, &slave->sw_params);
/* >= 30 ms */
slave->safety_threshold = slave->pcm->rate * 30 / 1000;
slave->safety_threshold += slave->pcm->fragment_size - 1;
return err;
}
-static int snd_pcm_share_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params)
+static int snd_pcm_share_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED)
{
- if (params->start_mode > SND_PCM_START_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_START_MODE;
- return -EINVAL;
- }
- if (params->ready_mode > SND_PCM_READY_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_READY_MODE;
- return -EINVAL;
- }
- if (params->xrun_mode > SND_PCM_XRUN_LAST) {
- params->fail_mask = 1 << SND_PCM_SW_PARAM_XRUN_MODE;
- return -EINVAL;
- }
return 0;
}
return ret;
}
-static int snd_pcm_share_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_share_t *share = pcm->private;
- snd_pcm_share_slave_t *slave = share->slave;
- Pthread_mutex_lock(&slave->mutex);
- pcm->avail_min = frames;
- share->avail_min = frames;
- _snd_pcm_share_update(pcm);
- Pthread_mutex_unlock(&slave->mutex);
- return 0;
-}
-
/* Warning: take the mutex before to call this */
static void _snd_pcm_share_stop(snd_pcm_t *pcm, int state)
{
rewind: snd_pcm_share_rewind,
avail_update: snd_pcm_share_avail_update,
mmap_forward: snd_pcm_share_mmap_forward,
- set_avail_min: snd_pcm_share_set_avail_min,
};
int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
static int snd_pcm_shm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_hw_params_t sparams;
- const mask_t *access_mask = snd_pcm_hw_params_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
if (!mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) &&
!mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
mask_intersect(saccess_mask, access_mask);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
return snd_pcm_hw_refine2(params, &sparams,
_snd_pcm_shm_hw_refine, pcm,
static int snd_pcm_shm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_hw_params_t sparams;
- const mask_t *access_mask = snd_pcm_hw_params_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
+ const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
if (!mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) &&
!mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
mask_intersect(saccess_mask, access_mask);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_params_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
return snd_pcm_hw_params2(params, &sparams,
_snd_pcm_shm_hw_params, pcm,
return snd_pcm_shm_action(pcm);
}
-static int snd_pcm_shm_set_avail_min(snd_pcm_t *pcm, size_t frames)
-{
- snd_pcm_shm_t *shm = pcm->private;
- volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
- ctrl->cmd = SND_PCM_IOCTL_SET_AVAIL_MIN;
- ctrl->u.set_avail_min.frames = frames;
- return snd_pcm_shm_action(pcm);
-}
-
static int snd_pcm_shm_poll_descriptor(snd_pcm_t *pcm)
{
snd_pcm_shm_t *shm = pcm->private;
readn: snd_pcm_mmap_readn,
avail_update: snd_pcm_shm_avail_update,
mmap_forward: snd_pcm_shm_mmap_forward,
- set_avail_min: snd_pcm_shm_set_avail_min,
};
static int make_local_socket(const char *filename)