summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo@alsa-project.org>2001-01-15 11:06:53 +0000
committerAbramo Bagnara <abramo@alsa-project.org>2001-01-15 11:06:53 +0000
commitcc90e325579c7dbdf70c2b5f70e5290a97df48b4 (patch)
treebaeb502b76a20d1928e7a6ac0089dcf45d3801ae
parent7b06e6f7622b0f95e44d2fe50f20e934d569a4ba (diff)
downloadalsa-lib-cc90e325579c7dbdf70c2b5f70e5290a97df48b4.tar.gz
New PCM model with fragment concept removal and two interrupt sources
Renamed size_t/ssize_t to snd_pcm_sframes_t/snd_pcm_uframes_t
-rw-r--r--TODO1
-rw-r--r--include/pcm.h171
-rw-r--r--src/pcm/interval.c219
-rw-r--r--src/pcm/interval.h31
-rw-r--r--src/pcm/interval_inline.h61
-rw-r--r--src/pcm/mask.h5
-rw-r--r--src/pcm/mask_inline.h18
-rw-r--r--src/pcm/pcm.c164
-rw-r--r--src/pcm/pcm_adpcm.c141
-rw-r--r--src/pcm/pcm_alaw.c141
-rw-r--r--src/pcm/pcm_copy.c61
-rw-r--r--src/pcm/pcm_file.c60
-rw-r--r--src/pcm/pcm_hw.c61
-rw-r--r--src/pcm/pcm_linear.c115
-rw-r--r--src/pcm/pcm_local.h201
-rw-r--r--src/pcm/pcm_misc.c6
-rw-r--r--src/pcm/pcm_mmap.c102
-rw-r--r--src/pcm/pcm_mulaw.c137
-rw-r--r--src/pcm/pcm_multi.c121
-rw-r--r--src/pcm/pcm_null.c22
-rw-r--r--src/pcm/pcm_params.c1158
-rw-r--r--src/pcm/pcm_plug.c293
-rw-r--r--src/pcm/pcm_plugin.c70
-rw-r--r--src/pcm/pcm_plugin.h22
-rw-r--r--src/pcm/pcm_rate.c168
-rw-r--r--src/pcm/pcm_route.c148
-rw-r--r--src/pcm/pcm_share.c286
-rw-r--r--src/pcm/pcm_shm.c50
-rw-r--r--src/rawmidi/rawmidi_hw.c2
29 files changed, 2281 insertions, 1754 deletions
diff --git a/TODO b/TODO
index d89b5909..cb99d9e9 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
+H change functions that take a FILE* to take a char * and a maximum size
M think about xrun recovery helpers
M add abstraction layer to timer, hwdep
L move OSS emulation to user space? (pseudo device driver and daemon)
diff --git a/include/pcm.h b/include/pcm.h
index 9e38827b..cd138ba5 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -47,8 +47,8 @@ int snd_pcm_open(snd_pcm_t **pcm, char *name,
/* Obsolete functions */
#define snd_pcm_write snd_pcm_writei
#define snd_pcm_read snd_pcm_readi
-ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
-ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
+snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
+snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
@@ -69,12 +69,12 @@ int snd_pcm_drop(snd_pcm_t *pcm);
int snd_pcm_drain(snd_pcm_t *pcm);
int snd_pcm_pause(snd_pcm_t *pcm, int enable);
int snd_pcm_state(snd_pcm_t *pcm);
-int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp);
-ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames);
-ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size);
+int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp);
int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp);
@@ -85,13 +85,13 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int snd_pcm_unlink(snd_pcm_t *pcm);
int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
-ssize_t snd_pcm_avail_update(snd_pcm_t *pcm);
-int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t size);
+snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
+int snd_pcm_set_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t size);
typedef struct _mask mask_t;
size_t mask_sizeof();
void mask_none(mask_t *mask);
-void mask_all(mask_t *mask);
+void mask_any(mask_t *mask);
void mask_load(mask_t *mask, unsigned int msk);
int mask_empty(const mask_t *mask);
void mask_set(mask_t *mask, unsigned int val);
@@ -99,48 +99,59 @@ void mask_reset(mask_t *mask, unsigned int val);
void mask_copy(mask_t *mask, const mask_t *v);
int mask_test(const mask_t *mask, unsigned int val);
void mask_intersect(mask_t *mask, const mask_t *v);
+void mask_union(mask_t *mask, const mask_t *v);
int mask_eq(const mask_t *a, const mask_t *b);
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_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var);
+int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var);
int snd_pcm_hw_param_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int par);
+ snd_pcm_hw_param_t var, int *dir);
int snd_pcm_hw_param_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int par);
+ snd_pcm_hw_param_t var, int *dir);
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_param_t var, unsigned int val,
+ int *dir);
int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var, unsigned int val, int *dir);
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);
+ snd_pcm_hw_param_t var,
+ unsigned int *min, int *mindir,
+ unsigned int *max, int *maxdir);
int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var, unsigned int val, int dir);
int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, const mask_t *mask);
+ snd_pcm_hw_param_t var, const mask_t *mask);
int snd_pcm_hw_param_min_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
int snd_pcm_hw_param_max_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
int snd_pcm_hw_param_minmax_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int min, unsigned int max);
+ snd_pcm_hw_param_t var,
+ unsigned int *min, int *mindir,
+ unsigned int *max, int *maxdir);
int snd_pcm_hw_param_set_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val);
+ snd_pcm_hw_param_t var, unsigned int val, int dir);
int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, const mask_t *mask);
+ snd_pcm_hw_param_t var, const mask_t *mask);
int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var, int *dir);
const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var);
const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var);
unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var, int *dir);
unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
- unsigned int var);
+ snd_pcm_hw_param_t var, int *dir);
int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
snd_pcm_hw_params_t *fail,
snd_pcm_hw_params_t *success,
@@ -174,73 +185,73 @@ 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,
+ snd_pcm_hw_param_t var,
unsigned int best,
unsigned int mul);
int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order,
- unsigned int param,
+ snd_pcm_hw_param_t var,
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
+typedef enum _snd_pcm_sw_param {
+ SND_PCM_SW_PARAM_START_MODE,
+ SND_PCM_SW_PARAM_XRUN_MODE,
+ SND_PCM_SW_PARAM_TSTAMP_MODE,
+ SND_PCM_SW_PARAM_PERIOD_STEP,
+ SND_PCM_SW_PARAM_SLEEP_MIN,
+ SND_PCM_SW_PARAM_AVAIL_MIN,
+ SND_PCM_SW_PARAM_XFER_ALIGN,
+ SND_PCM_SW_PARAM_SILENCE_THRESHOLD,
+ SND_PCM_SW_PARAM_SILENCE_SIZE,
+ SND_PCM_SW_PARAM_LAST = SND_PCM_SW_PARAM_SILENCE_SIZE,
+} snd_pcm_sw_param_t;
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_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
+int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t 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);
const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm);
const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm);
-ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size);
-size_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
-size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t size);
-ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-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);
+snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_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_format_description(unsigned int format);
+const char *snd_pcm_stream_name(snd_pcm_stream_t stream);
+const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t var);
+const char *snd_pcm_sw_param_name(snd_pcm_sw_param_t var);
+const char *snd_pcm_access_name(snd_pcm_access_t access);
+const char *snd_pcm_format_name(snd_pcm_format_t format);
+const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat);
+const char *snd_pcm_format_description(snd_pcm_format_t 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);
+const char *snd_pcm_start_mode_name(snd_pcm_start_t mode);
+const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode);
+const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode);
+const char *snd_pcm_state_name(snd_pcm_state_t state);
-int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
- size_t samples, int format);
-int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
- size_t vcount, size_t frames, int format);
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset,
- const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
- size_t samples, int format);
-int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, size_t src_offset,
- const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
- size_t channels, size_t frames, int format);
+int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+ unsigned int samples, int format);
+int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int format);
+int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset,
+ const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
+ unsigned int samples, int format);
+int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset,
+ const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int format);
-ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
-ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, ssize_t frames);
-ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
-ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, ssize_t samples);
+snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
+int snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples);
/* misc */
@@ -259,7 +270,7 @@ u_int8_t snd_pcm_format_silence(int format);
u_int16_t snd_pcm_format_silence_16(int format);
u_int32_t snd_pcm_format_silence_32(int format);
u_int64_t snd_pcm_format_silence_64(int format);
-ssize_t snd_pcm_format_set_silence(int format, void *buf, size_t count);
+int snd_pcm_format_set_silence(int format, void *buf, unsigned int samples);
#ifdef __cplusplus
}
diff --git a/src/pcm/interval.c b/src/pcm/interval.c
index 2a5283d9..0e2793b9 100644
--- a/src/pcm/interval.c
+++ b/src/pcm/interval.c
@@ -58,6 +58,8 @@ static inline unsigned int div_up(unsigned int a, unsigned int b)
static inline unsigned int mul(unsigned int a, unsigned int b)
{
+ if (a == 0)
+ return 0;
if (div_down(UINT_MAX, a) < b)
return UINT_MAX;
return a * b;
@@ -89,10 +91,9 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
return n;
}
-int interval_refine_min(interval_t *i, unsigned int min)
+int interval_refine_min(interval_t *i, unsigned int min, int openmin)
{
int changed = 0;
- int openmin = 0;
assert(!interval_empty(i));
if (i->min < min) {
i->min = min;
@@ -102,24 +103,22 @@ int interval_refine_min(interval_t *i, unsigned int min)
i->openmin = 1;
changed = 1;
}
- if (!i->real) {
+ if (i->integer) {
if (i->openmin) {
i->min++;
i->openmin = 0;
}
}
if (interval_checkempty(i)) {
- i->empty = 1;
+ interval_none(i);
return -EINVAL;
}
return changed;
}
-int interval_refine_max(interval_t *i, unsigned int max)
+int interval_refine_max(interval_t *i, unsigned int max, int openmax)
{
int changed = 0;
- int openmax = 1;
- max = add(max, 1);
assert(!interval_empty(i));
if (i->max > max) {
i->max = max;
@@ -129,14 +128,14 @@ int interval_refine_max(interval_t *i, unsigned int max)
i->openmax = 1;
changed = 1;
}
- if (!i->real) {
+ if (i->integer) {
if (i->openmax) {
i->max--;
i->openmax = 0;
}
}
if (interval_checkempty(i)) {
- i->empty = 1;
+ interval_none(i);
return -EINVAL;
}
return changed;
@@ -163,7 +162,11 @@ int interval_refine(interval_t *i, const interval_t *v)
i->openmax = 1;
changed = 1;
}
- if (!i->real) {
+ if (!i->integer && v->integer) {
+ i->integer = 1;
+ changed = 1;
+ }
+ if (i->integer) {
if (i->openmin) {
i->min++;
i->openmin = 0;
@@ -172,9 +175,10 @@ int interval_refine(interval_t *i, const interval_t *v)
i->max--;
i->openmax = 0;
}
- }
+ } else if (!i->openmin && !i->openmax && i->min == i->max)
+ i->integer = 1;
if (interval_checkempty(i)) {
- i->empty = 1;
+ interval_none(i);
return -EINVAL;
}
return changed;
@@ -183,8 +187,7 @@ int interval_refine(interval_t *i, const interval_t *v)
int interval_refine_first(interval_t *i)
{
assert(!interval_empty(i));
- if (i->min == i->max ||
- (i->min + 1 == i->max && i->openmin && i->openmax))
+ if (interval_single(i))
return 0;
i->max = i->min;
i->openmax = i->openmin;
@@ -196,8 +199,7 @@ int interval_refine_first(interval_t *i)
int interval_refine_last(interval_t *i)
{
assert(!interval_empty(i));
- if (i->min == i->max ||
- (i->min + 1 == i->max && i->openmin && i->openmax))
+ if (interval_single(i))
return 0;
i->min = i->max;
i->openmin = i->openmax;
@@ -209,107 +211,154 @@ int interval_refine_last(interval_t *i)
int interval_refine_set(interval_t *i, unsigned int val)
{
interval_t t;
- t.min = val;
- t.openmin = 0;
- t.max = add(val, 1);
- t.openmax = 1;
+ t.empty = 0;
+ t.min = t.max = val;
+ t.openmin = t.openmax = 0;
+ t.integer = 1;
return interval_refine(i, &t);
}
-/* a <- b + c */
-int interval_add(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_add(const interval_t *a, const interval_t *b, 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);
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = add(a->min, b->min);
+ c->openmin = (a->openmin || b->openmin);
+ c->max = add(a->max, b->max);
+ c->openmax = (a->openmax || b->openmax);
+ c->integer = (a->integer && b->integer);
}
-/* a <- b - c */
-int interval_sub(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_sub(const interval_t *a, const interval_t *b, 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);
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = sub(a->min, b->max);
+ c->openmin = (a->openmin || b->openmax);
+ c->max = add(a->max, b->min);
+ c->openmax = (a->openmax || b->openmin);
+ c->integer = (a->integer && b->integer);
}
-/* a <- b * c */
-int interval_mul(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_mul(const interval_t *a, const interval_t *b, interval_t *c)
{
- interval_t t;
- assert(!a->empty && !b->empty && !c->empty);
- t.min = mul(b->min, c->min);
- t.openmin = (b->openmin || c->openmin);
- t.max = mul(b->max, c->max);
- t.openmax = (b->openmax || c->openmax);
- return interval_refine(a, &t);
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = mul(a->min, b->min);
+ c->openmin = (a->openmin || b->openmin);
+ c->max = mul(a->max, b->max);
+ c->openmax = (a->openmax || b->openmax);
+ c->integer = (a->integer && b->integer);
}
-/* a <- b / c */
-int interval_div(interval_t *a, const interval_t *b, const interval_t *c)
+void interval_div(const interval_t *a, const interval_t *b, interval_t *c)
{
- interval_t t;
unsigned int r;
- assert(!a->empty && !b->empty && !c->empty);
- t.min = div32(b->min, c->max, &r);
- t.openmin = (r || b->openmin || c->openmax);
- t.max = div32(b->max, c->min, &r);
- if (r) {
- t.max++;
- t.openmax = 1;
- } else
- t.openmax = (b->openmax || c->openmin);
- return interval_refine(a, &t);
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = div32(a->min, b->max, &r);
+ c->openmin = (r || a->openmin || b->openmax);
+ if (b->min > 0) {
+ c->max = div32(a->max, b->min, &r);
+ if (r) {
+ c->max++;
+ c->openmax = 1;
+ } else
+ c->openmax = (a->openmax || b->openmin);
+ } else {
+ c->max = UINT_MAX;
+ c->openmax = 0;
+ }
+ c->integer = 0;
}
-
-/* a <- b * c / k */
-int interval_muldivk(interval_t *a, unsigned int k,
- const interval_t *b, const interval_t *c)
+/* a * b / c */
+void interval_muldiv(const interval_t *a, const interval_t *b,
+ const interval_t *c, interval_t *d)
{
- interval_t t;
unsigned int r;
- assert(!a->empty && !b->empty && !c->empty);
- t.min = muldiv32(b->min, c->min, k, &r);
- t.openmin = (r || b->openmin || c->openmin);
- t.max = muldiv32(b->max, c->max, k, &r);
+ if (a->empty || b->empty || c->empty) {
+ interval_none(d);
+ return;
+ }
+ d->empty = 0;
+ d->min = muldiv32(a->min, b->min, c->max, &r);
+ d->openmin = (r || a->openmin || b->openmin || c->openmax);
+ d->max = muldiv32(a->max, b->max, c->min, &r);
if (r) {
- t.max++;
- t.openmax = 1;
+ d->max++;
+ d->openmax = 1;
} else
- t.openmax = (b->openmax || c->openmax);
- return interval_refine(a, &t);
+ d->openmax = (a->openmax || b->openmax || c->openmin);
+ d->integer = 0;
}
-/* a <- b * k / c */
-int interval_mulkdiv(interval_t *a, unsigned int k,
- const interval_t *b, const interval_t *c)
+/* a * b / k */
+void interval_muldivk(const interval_t *a, const interval_t *b,
+ unsigned int k, interval_t *c)
{
- interval_t t;
unsigned int r;
- assert(!a->empty && !b->empty && !c->empty);
- t.min = muldiv32(b->min, k, c->max, &r);
- t.openmin = (r || b->openmin || c->openmax);
- t.max = muldiv32(b->max, k, c->min, &r);
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = muldiv32(a->min, b->min, k, &r);
+ c->openmin = (r || a->openmin || b->openmin);
+ c->max = muldiv32(a->max, b->max, k, &r);
if (r) {
- t.max++;
- t.openmax = 1;
+ c->max++;
+ c->openmax = 1;
} else
- t.openmax = (b->openmax || c->openmin);
- return interval_refine(a, &t);
+ c->openmax = (a->openmax || b->openmax);
+ c->integer = 0;
+}
+
+/* a * k / b */
+void interval_mulkdiv(const interval_t *a, unsigned int k,
+ const interval_t *b, interval_t *c)
+{
+ unsigned int r;
+ if (a->empty || b->empty) {
+ interval_none(c);
+ return;
+ }
+ c->empty = 0;
+ c->min = muldiv32(a->min, k, b->max, &r);
+ c->openmin = (r || a->openmin || b->openmax);
+ if (b->min > 0) {
+ c->max = muldiv32(a->max, k, b->min, &r);
+ if (r) {
+ c->max++;
+ c->openmax = 1;
+ } else
+ c->openmax = (a->openmax || b->openmin);
+ } else {
+ c->max = UINT_MAX;
+ c->openmax = 0;
+ }
+ c->integer = 0;
}
void interval_print(const interval_t *i, FILE *fp)
{
if (interval_empty(i))
fprintf(fp, "NONE");
+ else if (i->min == 0 && i->openmin == 0 &&
+ i->max == UINT_MAX && i->openmax == 0)
+ fprintf(fp, "ALL");
else if (interval_single(i))
fprintf(fp, "%u", interval_value(i));
else
diff --git a/src/pcm/interval.h b/src/pcm/interval.h
index 8c6e0d8d..2f549b42 100644
--- a/src/pcm/interval.h
+++ b/src/pcm/interval.h
@@ -24,8 +24,9 @@
#ifdef INTERVAL_INLINE
#include "interval_inline.h"
#else
-void interval_all(interval_t *i);
-void interval_setreal(interval_t *i);
+void interval_any(interval_t *i);
+void interval_none(interval_t *i);
+int interval_setinteger(interval_t *i);
int interval_empty(const interval_t *i);
int interval_single(const interval_t *i);
int interval_value(const interval_t *i);
@@ -33,20 +34,24 @@ int interval_min(const interval_t *i);
int interval_max(const interval_t *i);
int interval_test(const 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);
+void interval_round(interval_t *i);
+int interval_always_eq(const interval_t *i1, const interval_t *i2);
+int interval_never_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_add(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_sub(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_mul(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_div(const interval_t *a, const interval_t *b, interval_t *c);
+void interval_muldiv(const interval_t *a, const interval_t *b,
+ const interval_t *c, interval_t *d);
+void interval_muldivk(const interval_t *a, const interval_t *b,
+ unsigned int k, interval_t *c);
+void interval_mulkdiv(const interval_t *a, unsigned int k,
+ const interval_t *b, interval_t *c);
void interval_print(const interval_t *i, FILE *fp);
-int interval_refine_min(interval_t *i, unsigned int min);
-int interval_refine_max(interval_t *i, unsigned int max);
+int interval_refine_min(interval_t *i, unsigned int min, int openmin);
+int interval_refine_max(interval_t *i, unsigned int max, int openmax);
int interval_refine(interval_t *i, const interval_t *v);
int interval_refine_first(interval_t *i);
int interval_refine_last(interval_t *i);
diff --git a/src/pcm/interval_inline.h b/src/pcm/interval_inline.h
index ae78bcf6..a14c83eb 100644
--- a/src/pcm/interval_inline.h
+++ b/src/pcm/interval_inline.h
@@ -25,10 +25,19 @@
#define INLINE extern inline
#endif
-INLINE void interval_all(interval_t *i)
+INLINE void interval_any(interval_t *i)
{
- i->min = 1;
+ i->min = 0;
+ i->openmin = 0;
i->max = UINT_MAX;
+ i->openmax = 0;
+ i->integer = 0;
+ i->empty = 0;
+}
+
+INLINE void interval_none(interval_t *i)
+{
+ i->empty = 1;
}
INLINE int interval_checkempty(const interval_t *i)
@@ -63,12 +72,8 @@ INLINE int interval_min(const interval_t *i)
INLINE int interval_max(const interval_t *i)
{
- unsigned int v;
assert(!interval_empty(i));
- v = i->max;
- if (i->openmax)
- v--;
- return v;
+ return i->max;
}
INLINE int interval_test(const interval_t *i, unsigned int val)
@@ -82,18 +87,42 @@ INLINE void interval_copy(interval_t *d, const interval_t *s)
*d = *s;
}
-INLINE void interval_setreal(interval_t *i)
+INLINE int interval_setinteger(interval_t *i)
+{
+ if (i->integer)
+ return 0;
+ if (i->openmin && i->openmax && i->min == i->max)
+ return -EINVAL;
+ i->integer = 1;
+ return 1;
+}
+
+INLINE void interval_round(interval_t *i)
{
- i->real = 1;
+ assert(!interval_empty(i));
+ if (i->integer)
+ return;
+ i->openmin = 0;
+ i->openmax = 0;
+ i->integer = 1;
+}
+
+INLINE int interval_always_eq(const interval_t *i1, const interval_t *i2)
+{
+ return interval_single(i1) && interval_single(i2) &&
+ interval_value(i1) == interval_value(i2);
}
-INLINE int interval_eq(const interval_t *i1, const interval_t *i2)
+INLINE int interval_never_eq(const interval_t *i1, const interval_t *i2)
{
- if (i1->empty)
- return i2->empty;
- if (i2->empty)
- return i1->empty;
- return i1->min == i2->min && i1->openmin == i2->openmin &&
- i1->max == i2->max && i1->openmax == i2->openmax;
+
+ return (i1->max < i2->min ||
+ (i1->max == i2->min &&
+ (i1->openmax || i1->openmin)) ||
+ i1->min > i2->max ||
+ (i1->min == i2->max &&
+ (i1->openmin || i2->openmax)));
}
+
+
diff --git a/src/pcm/mask.h b/src/pcm/mask.h
index 8a654619..b6e6792c 100644
--- a/src/pcm/mask.h
+++ b/src/pcm/mask.h
@@ -31,7 +31,7 @@
#include "mask_inline.h"
#else
void mask_none(mask_t *mask);
-void mask_all(mask_t *mask);
+void mask_any(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);
@@ -40,6 +40,7 @@ void mask_reset(mask_t *mask, unsigned int val);
void mask_copy(mask_t *mask, const mask_t *v);
int mask_test(const mask_t *mask, unsigned int val);
void mask_intersect(mask_t *mask, const mask_t *v);
+void mask_union(mask_t *mask, const mask_t *v);
unsigned int mask_count(const mask_t *mask);
unsigned int mask_min(const mask_t *mask);
unsigned int mask_max(const mask_t *mask);
@@ -55,4 +56,6 @@ int mask_refine_min(mask_t *mask, unsigned int val);
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);
+int mask_always_eq(const mask_t *m1, const mask_t *m2);
+int mask_never_eq(const mask_t *m1, const mask_t *m2);
#endif
diff --git a/src/pcm/mask_inline.h b/src/pcm/mask_inline.h
index 44892110..5f3e1a1a 100644
--- a/src/pcm/mask_inline.h
+++ b/src/pcm/mask_inline.h
@@ -82,7 +82,7 @@ INLINE void mask_none(mask_t *mask)
mask_bits(mask) = 0;
}
-INLINE void mask_all(mask_t *mask)
+INLINE void mask_any(mask_t *mask)
{
mask_bits(mask) = ~0U;
}
@@ -154,6 +154,11 @@ INLINE void mask_intersect(mask_t *mask, const mask_t *v)
mask_bits(mask) &= mask_bits(v);
}
+INLINE void mask_union(mask_t *mask, const mask_t *v)
+{
+ mask_bits(mask) |= mask_bits(v);
+}
+
INLINE int mask_eq(const mask_t *mask, const mask_t *v)
{
return mask_bits(mask) == mask_bits(v);
@@ -243,3 +248,14 @@ INLINE int mask_value(const mask_t *mask)
assert(!mask_empty(mask));
return mask_min(mask);
}
+
+INLINE int mask_always_eq(const mask_t *m1, const mask_t *m2)
+{
+ return mask_single(m1) && mask_single(m2) &&
+ mask_value(m1) == mask_value(m2);
+}
+
+INLINE int mask_never_eq(const mask_t *m1, const mask_t *m2)
+{
+ return (mask_bits(m1) & mask_bits(m2)) == 0;
+}
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index b94d3208..2cbce95e 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -106,7 +106,7 @@ int snd_pcm_state(snd_pcm_t *pcm)
return pcm->fast_ops->state(pcm->fast_op_arg);
}
-int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp)
+int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
assert(pcm);
assert(pcm->setup);
@@ -156,7 +156,7 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
}
-ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
+snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
assert(pcm);
assert(pcm->setup);
@@ -164,7 +164,7 @@ ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
}
-ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
assert(pcm);
assert(size == 0 || buffer);
@@ -173,7 +173,7 @@ ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
return _snd_pcm_writei(pcm, buffer, size);
}
-ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
assert(pcm);
assert(size == 0 || bufs);
@@ -182,7 +182,7 @@ ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
return _snd_pcm_writen(pcm, bufs, size);
}
-ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
assert(pcm);
assert(size == 0 || buffer);
@@ -191,7 +191,7 @@ ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
return _snd_pcm_readi(pcm, buffer, size);
}
-ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
assert(pcm);
assert(size == 0 || bufs);
@@ -200,7 +200,7 @@ ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
return _snd_pcm_readn(pcm, bufs, size);
}
-ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
+snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
{
void **bufs;
int k;
@@ -215,7 +215,7 @@ ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
return snd_pcm_writen(pcm, bufs, vector[0].iov_len);
}
-ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
+snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
{
void **bufs;
int k;
@@ -310,25 +310,26 @@ char *snd_pcm_hw_param_names[] = {
HW_PARAM(ACCESS),
HW_PARAM(FORMAT),
HW_PARAM(SUBFORMAT),
+ HW_PARAM(SAMPLE_BITS),
+ HW_PARAM(FRAME_BITS),
HW_PARAM(CHANNELS),
HW_PARAM(RATE),
- HW_PARAM(FRAGMENT_LENGTH),
- HW_PARAM(FRAGMENT_SIZE),
- HW_PARAM(FRAGMENTS),
- HW_PARAM(BUFFER_LENGTH),
+ HW_PARAM(PERIOD_TIME),
+ HW_PARAM(PERIOD_SIZE),
+ HW_PARAM(PERIOD_BYTES),
+ HW_PARAM(PERIODS),
+ HW_PARAM(BUFFER_TIME),
HW_PARAM(BUFFER_SIZE),
- HW_PARAM(SAMPLE_BITS),
- HW_PARAM(FRAME_BITS),
- HW_PARAM(FRAGMENT_BYTES),
HW_PARAM(BUFFER_BYTES),
+ HW_PARAM(TICK_TIME),
};
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(PERIOD_STEP),
+ SW_PARAM(SLEEP_MIN),
SW_PARAM(AVAIL_MIN),
SW_PARAM(XFER_ALIGN),
SW_PARAM(SILENCE_THRESHOLD),
@@ -414,20 +415,9 @@ char *snd_pcm_start_mode_names[] = {
START(DATA),
};
-char *snd_pcm_ready_mode_names[] = {
- READY(FRAGMENT),
- READY(ASAP),
-};
-
char *snd_pcm_xrun_mode_names[] = {
- XRUN(FRAGMENT),
- XRUN(ASAP),
XRUN(NONE),
-};
-
-char *snd_pcm_silence_mode_names[] = {
- SILENCE(FRAGMENT),
- SILENCE(ASAP),
+ XRUN(STOP),
};
char *snd_pcm_tstamp_mode_names[] = {
@@ -435,25 +425,25 @@ char *snd_pcm_tstamp_mode_names[] = {
TSTAMP(MMAP),
};
-const char *snd_pcm_stream_name(unsigned int stream)
+const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
{
assert(stream <= SND_PCM_STREAM_LAST);
return snd_pcm_stream_names[stream];
}
-const char *snd_pcm_access_name(unsigned int access)
+const char *snd_pcm_access_name(snd_pcm_access_t access)
{
assert(access <= SND_PCM_ACCESS_LAST);
return snd_pcm_access_names[access];
}
-const char *snd_pcm_format_name(unsigned int format)
+const char *snd_pcm_format_name(snd_pcm_format_t format)
{
assert(format <= SND_PCM_FORMAT_LAST);
return snd_pcm_format_names[format];
}
-const char *snd_pcm_format_description(unsigned int format)
+const char *snd_pcm_format_description(snd_pcm_format_t format)
{
assert(format <= SND_PCM_FORMAT_LAST);
return snd_pcm_format_descriptions[format];
@@ -469,55 +459,43 @@ int snd_pcm_format_value(const char* name)
return -1;
}
-const char *snd_pcm_subformat_name(unsigned int subformat)
+const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
{
assert(subformat <= SND_PCM_SUBFORMAT_LAST);
return snd_pcm_subformat_names[subformat];
}
-const char *snd_pcm_hw_param_name(unsigned int param)
+const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t 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)
+const char *snd_pcm_sw_param_name(snd_pcm_sw_param_t 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)
+const char *snd_pcm_start_mode_name(snd_pcm_start_t 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)
+const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t 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)
+const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
{
assert(mode <= SND_PCM_TSTAMP_LAST);
return snd_pcm_tstamp_mode_names[mode];
}
-const char *snd_pcm_state_name(unsigned int state)
+const char *snd_pcm_state_name(snd_pcm_state_t state)
{
assert(state <= SND_PCM_STATE_LAST);
return snd_pcm_state_names[state];
@@ -536,8 +514,10 @@ int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp)
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);
fprintf(fp, "msbits : %u\n", pcm->msbits);
- fprintf(fp, "fragment_size: %lu\n", (long)pcm->fragment_size);
- fprintf(fp, "fragments : %u\n", pcm->fragments);
+ fprintf(fp, "buffer_size : %lu\n", pcm->buffer_size);
+ fprintf(fp, "period_size : %lu\n", pcm->period_size);
+ fprintf(fp, "period_time : %u\n", pcm->period_time);
+ fprintf(fp, "tick_time : %u\n", pcm->tick_time);
return 0;
}
@@ -548,9 +528,9 @@ int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp)
assert(pcm->setup);
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, "period_step : %ld\n", (long)pcm->period_step);
+ fprintf(fp, "sleep_min : %ld\n", (long)pcm->sleep_min);
fprintf(fp, "avail_min : %ld\n", (long)pcm->avail_min);
fprintf(fp, "xfer_align : %ld\n", (long)pcm->xfer_align);
fprintf(fp, "silence_threshold: %ld\n", (long)pcm->silence_threshold);
@@ -588,28 +568,28 @@ int snd_pcm_dump(snd_pcm_t *pcm, FILE *fp)
return 0;
}
-ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
+snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
{
assert(pcm);
assert(pcm->setup);
return bytes * 8 / pcm->bits_per_frame;
}
-ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, ssize_t frames)
+ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
{
assert(pcm);
assert(pcm->setup);
return frames * pcm->bits_per_frame / 8;
}
-ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
+int snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
{
assert(pcm);
assert(pcm->setup);
return bytes * 8 / pcm->bits_per_sample;
}
-ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, ssize_t samples)
+ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples)
{
assert(pcm);
assert(pcm->setup);
@@ -788,20 +768,20 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
return 0;
}
-ssize_t snd_pcm_avail_update(snd_pcm_t *pcm)
+snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
{
return pcm->fast_ops->avail_update(pcm->fast_op_arg);
}
-ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
assert(size > 0);
assert(size <= snd_pcm_mmap_avail(pcm));
return pcm->fast_ops->mmap_forward(pcm->fast_op_arg, size);
}
-int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
- size_t samples, int format)
+int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
+ unsigned int samples, int format)
{
/* FIXME: sub byte resolution and odd dst_offset */
char *dst;
@@ -814,7 +794,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
width = snd_pcm_format_physical_width(format);
silence = snd_pcm_format_silence_64(format);
if (dst_area->step == (unsigned int) width) {
- size_t dwords = samples * width / 64;
+ unsigned int dwords = samples * width / 64;
samples -= dwords * 64 / width;
while (dwords-- > 0)
*((u_int64_t*)dst)++ = silence;
@@ -882,8 +862,8 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs
return 0;
}
-int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
- size_t channels, size_t frames, int format)
+int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int format)
{
int width = snd_pcm_format_physical_width(format);
while (channels > 0) {
@@ -923,9 +903,9 @@ int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, size_t dst_of
}
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
- const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
- size_t samples, int format)
+int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, snd_pcm_uframes_t src_offset,
+ const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t dst_offset,
+ unsigned int samples, int format)
{
/* FIXME: sub byte resolution and odd dst_offset */
char *src, *dst;
@@ -1018,9 +998,9 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
return 0;
}
-int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, size_t src_offset,
- const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
- size_t channels, size_t frames, int format)
+int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
+ const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int format)
{
int width = snd_pcm_format_physical_width(format);
while (channels > 0) {
@@ -1065,12 +1045,12 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, size_t src_offse
return 0;
}
-ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
- size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
snd_pcm_xfer_areas_func_t func)
{
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
int state = snd_pcm_state(pcm);
assert(size > 0);
assert(state >= SND_PCM_STATE_PREPARED);
@@ -1082,15 +1062,15 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
state = SND_PCM_STATE_RUNNING;
}
while (xfer < size) {
- ssize_t avail;
- size_t frames;
+ snd_pcm_sframes_t avail;
+ snd_pcm_uframes_t frames;
again:
avail = snd_pcm_avail_update(pcm);
if (avail < 0) {
err = avail;
break;
}
- if ((size_t)avail < pcm->avail_min) {
+ if ((snd_pcm_uframes_t)avail < pcm->avail_min) {
if (state != SND_PCM_STATE_RUNNING) {
err = -EPIPE;
break;
@@ -1106,12 +1086,12 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
goto again;
}
frames = size - xfer;
- if (frames > (size_t)avail)
+ if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
err = func(pcm, areas, offset, frames, 0);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
xfer += err;
offset += err;
}
@@ -1120,18 +1100,18 @@ ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
return err;
}
-ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
- size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
snd_pcm_xfer_areas_func_t func)
{
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
int state = snd_pcm_state(pcm);
assert(size > 0);
assert(state >= SND_PCM_STATE_PREPARED);
while (xfer < size) {
- ssize_t avail;
- size_t frames;
+ snd_pcm_sframes_t avail;
+ snd_pcm_uframes_t frames;
again:
if (state == SND_PCM_STATE_XRUN) {
err = -EPIPE;
@@ -1142,7 +1122,7 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
err = avail;
break;
}
- if ((size_t)avail < pcm->avail_min) {
+ if ((snd_pcm_uframes_t)avail < pcm->avail_min) {
if (state != SND_PCM_STATE_RUNNING) {
err = -EPIPE;
break;
@@ -1158,12 +1138,12 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
goto again;
}
frames = size - xfer;
- if (frames > (size_t)avail)
+ if (frames > (snd_pcm_uframes_t)avail)
frames = avail;
err = func(pcm, areas, offset, frames, 0);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
xfer += err;
offset += err;
if (state == SND_PCM_STATE_PREPARED &&
@@ -1179,7 +1159,7 @@ ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
return err;
}
-size_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
+snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm)
{
return *pcm->hw_ptr;
}
diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c
index 41acc108..31c3f76c 100644
--- a/src/pcm/pcm_adpcm.c
+++ b/src/pcm/pcm_adpcm.c
@@ -57,10 +57,10 @@ typedef struct {
} adpcm_state_t;
typedef void (*adpcm_f)(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getputidx,
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getputidx,
adpcm_state_t *states);
typedef struct {
@@ -196,23 +196,23 @@ static int adpcm_decoder(unsigned char code, adpcm_state_t * state)
}
static void adpcm_decode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int putidx,
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int putidx,
adpcm_state_t *states)
{
#define PUT16_LABELS
#include "plugin_ops.h"
#undef PUT16_LABELS
void *put = put16_labels[putidx];
- size_t channel;
+ unsigned int channel;
for (channel = 0; channel < channels; ++channel, ++states) {
char *src;
int srcbit;
char *dst;
int src_step, srcbit_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -257,24 +257,24 @@ static void adpcm_decode(const snd_pcm_channel_area_t *src_areas,
}
static void adpcm_encode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getidx,
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getidx,
adpcm_state_t *states)
{
#define GET16_LABELS
#include "plugin_ops.h"
#undef GET16_LABELS
void *get = get16_labels[getidx];
- size_t channel;
+ unsigned int channel;
int16_t sample = 0;
for (channel = 0; channel < channels; ++channel, ++states) {
char *src;
char *dst;
int dstbit;
int src_step, dst_step, dstbit_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -334,51 +334,58 @@ static int snd_pcm_adpcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_adpcm_t *adpcm = pcm->private;
snd_pcm_t *slave = adpcm->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
mask_t *access_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, 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_param_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params,
SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_param_set(params, 1,
- SND_PCM_HW_PARAM_FORMAT,
- SND_PCM_FORMAT_IMA_ADPCM);
+ err = _snd_pcm_hw_param_set(params,
+ SND_PCM_HW_PARAM_FORMAT,
+ SND_PCM_FORMAT_IMA_ADPCM, 0);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- adpcm->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ adpcm->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -391,31 +398,39 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
snd_pcm_t *slave = adpcm->plug.slave;
int err;
snd_pcm_hw_params_t sparams;
+ unsigned int links;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- adpcm->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 |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ adpcm->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
+ links = SND_PCM_HW_PARBIT_CHANNELS |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME;
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
return err;
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_param_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, 0), SND_PCM_FORMAT_S16);
adpcm->func = adpcm_encode;
} else {
adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
@@ -423,7 +438,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
}
} else {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
- adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_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, 0));
adpcm->func = adpcm_decode;
} else {
adpcm->getput_idx = get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
@@ -432,7 +447,7 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
}
if (adpcm->states)
free(adpcm->states);
- adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*adpcm->states));
+ adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*adpcm->states));
return 0;
}
@@ -447,21 +462,21 @@ static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
return 0;
}
-static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_adpcm_t *adpcm = pcm->private;
snd_pcm_t *slave = adpcm->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
adpcm->func(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
pcm->channels, frames,
@@ -469,7 +484,7 @@ static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -482,21 +497,21 @@ static ssize_t snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_adpcm_t *adpcm = pcm->private;
snd_pcm_t *slave = adpcm->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
adpcm->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames,
@@ -504,7 +519,7 @@ static ssize_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c
index feb60008..1be95dbf 100644
--- a/src/pcm/pcm_alaw.c
+++ b/src/pcm/pcm_alaw.c
@@ -24,10 +24,10 @@
#include "pcm_plugin.h"
typedef void (*alaw_f)(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getputidx);
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getputidx);
typedef struct {
/* This field need to be the first */
@@ -121,21 +121,21 @@ static int alaw_to_s16(unsigned char a_val)
}
static void alaw_decode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int putidx)
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int putidx)
{
#define PUT16_LABELS
#include "plugin_ops.h"
#undef PUT16_LABELS
void *put = put16_labels[putidx];
- size_t channel;
+ unsigned int channel;
for (channel = 0; channel < channels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -166,22 +166,22 @@ static void alaw_decode(const snd_pcm_channel_area_t *src_areas,
}
static void alaw_encode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getidx)
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getidx)
{
#define GET16_LABELS
#include "plugin_ops.h"
#undef GET16_LABELS
void *get = get16_labels[getidx];
- size_t channel;
+ unsigned int channel;
int16_t sample = 0;
for (channel = 0; channel < channels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -216,51 +216,58 @@ static int snd_pcm_alaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_alaw_t *alaw = pcm->private;
snd_pcm_t *slave = alaw->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
mask_t *access_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, 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_param_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params,
SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_param_set(params, 1,
+ err = _snd_pcm_hw_param_set(params,
SND_PCM_HW_PARAM_FORMAT,
- SND_PCM_FORMAT_A_LAW);
+ SND_PCM_FORMAT_A_LAW, 0);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _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,
- alaw->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ alaw->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -273,31 +280,39 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
snd_pcm_t *slave = alaw->plug.slave;
int err;
snd_pcm_hw_params_t sparams;
+ unsigned int links;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _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,
- alaw->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 |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ alaw->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
+ links = SND_PCM_HW_PARBIT_CHANNELS |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME;
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
return err;
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_param_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, 0), SND_PCM_FORMAT_S16);
alaw->func = alaw_encode;
} else {
alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, alaw->sformat);
@@ -305,7 +320,7 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
}
} else {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
- alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_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, 0));
alaw->func = alaw_decode;
} else {
alaw->getput_idx = get_index(alaw->sformat, SND_PCM_FORMAT_S16);
@@ -315,21 +330,21 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0;
}
-static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_alaw_t *alaw = pcm->private;
snd_pcm_t *slave = alaw->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
alaw->func(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
pcm->channels, frames,
@@ -337,7 +352,7 @@ static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -350,21 +365,21 @@ static ssize_t snd_pcm_alaw_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_alaw_t *alaw = pcm->private;
snd_pcm_t *slave = alaw->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
alaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames,
@@ -372,7 +387,7 @@ static ssize_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c
index cdba7cce..e2bb724e 100644
--- a/src/pcm/pcm_copy.c
+++ b/src/pcm/pcm_copy.c
@@ -33,21 +33,27 @@ static int snd_pcm_copy_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_copy_t *copy = pcm->private;
snd_pcm_t *slave = copy->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
mask_t *access_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
- access_mask);
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
+ access_mask);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
~SND_PCM_HW_PARBIT_ACCESS);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -59,37 +65,44 @@ static int snd_pcm_copy_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_copy_t *copy = pcm->private;
snd_pcm_t *slave = copy->plug.slave;
int err;
+ unsigned int links;
snd_pcm_hw_params_t sparams;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- err = snd_pcm_hw_params2(params, &sparams,
- snd_pcm_hw_params, slave,
- ~SND_PCM_HW_PARBIT_ACCESS);
+ links = ~SND_PCM_HW_PARBIT_ACCESS;
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
return err;
}
-static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_copy_t *copy = pcm->private;
snd_pcm_t *slave = copy->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
snd_pcm_areas_copy(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
@@ -97,7 +110,7 @@ static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -110,28 +123,28 @@ static ssize_t snd_pcm_copy_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_copy_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_copy_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_copy_t *copy = pcm->private;
snd_pcm_t *slave = copy->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
snd_pcm_areas_copy(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames, pcm->format);
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
index 2f573d25..ca2f8c80 100644
--- a/src/pcm/pcm_file.c
+++ b/src/pcm/pcm_file.c
@@ -33,9 +33,9 @@ typedef struct {
char *fname;
int fd;
int format;
- size_t appl_ptr;
- size_t file_ptr_bytes;
- size_t wbuf_size;
+ snd_pcm_uframes_t appl_ptr;
+ snd_pcm_uframes_t file_ptr_bytes;
+ snd_pcm_uframes_t wbuf_size;
size_t wbuf_size_bytes;
size_t wbuf_used_bytes;
char *wbuf;
@@ -48,7 +48,7 @@ static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
snd_pcm_file_t *file = pcm->private;
assert(bytes <= file->wbuf_used_bytes);
while (bytes > 0) {
- ssize_t err;
+ snd_pcm_sframes_t err;
size_t n = bytes;
size_t cont = file->wbuf_size_bytes - file->file_ptr_bytes;
if (n > cont)
@@ -63,20 +63,20 @@ static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
file->file_ptr_bytes += err;
if (file->file_ptr_bytes == file->wbuf_size_bytes)
file->file_ptr_bytes = 0;
- if ((size_t)err != n)
+ if ((snd_pcm_uframes_t)err != n)
break;
}
}
static void snd_pcm_file_add_frames(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset, size_t frames)
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private;
while (frames > 0) {
- size_t n = frames;
- size_t cont = file->wbuf_size - file->appl_ptr;
- size_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+ snd_pcm_uframes_t n = frames;
+ snd_pcm_uframes_t cont = file->wbuf_size - file->appl_ptr;
+ snd_pcm_uframes_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
if (n > cont)
n = cont;
if (n > avail)
@@ -157,7 +157,7 @@ static int snd_pcm_file_state(snd_pcm_t *pcm)
return snd_pcm_state(file->slave);
}
-static int snd_pcm_file_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_file_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_file_t *file = pcm->private;
return snd_pcm_delay(file->slave, delayp);
@@ -216,13 +216,13 @@ static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
return snd_pcm_pause(file->slave, enable);
}
-static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private;
- ssize_t err = snd_pcm_rewind(file->slave, frames);
+ snd_pcm_sframes_t err = snd_pcm_rewind(file->slave, frames);
if (err > 0) {
- size_t n = snd_pcm_frames_to_bytes(pcm, frames);
- ssize_t ptr;
+ snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, frames);
+ snd_pcm_sframes_t ptr;
assert(n >= file->wbuf_used_bytes);
ptr = file->appl_ptr - err;
if (ptr < 0)
@@ -232,11 +232,11 @@ static ssize_t snd_pcm_file_rewind(snd_pcm_t *pcm, size_t frames)
return err;
}
-static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t n = snd_pcm_writei(file->slave, buffer, size);
+ snd_pcm_sframes_t n = snd_pcm_writei(file->slave, buffer, size);
if (n > 0) {
snd_pcm_areas_from_buf(pcm, areas, (void*) buffer);
snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -244,11 +244,11 @@ static ssize_t snd_pcm_file_writei(snd_pcm_t *pcm, const void *buffer, size_t si
return n;
}
-static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t n = snd_pcm_writen(file->slave, bufs, size);
+ snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
if (n > 0) {
snd_pcm_areas_from_bufs(pcm, areas, bufs);
snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -256,11 +256,11 @@ static ssize_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, size_t size)
return n;
}
-static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t n = snd_pcm_readi(file->slave, buffer, size);
+ snd_pcm_sframes_t n = snd_pcm_readi(file->slave, buffer, size);
if (n > 0) {
snd_pcm_areas_from_buf(pcm, areas, buffer);
snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -268,11 +268,11 @@ static ssize_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, size_t size)
return n;
}
-static ssize_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t n = snd_pcm_writen(file->slave, bufs, size);
+ snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
if (n > 0) {
snd_pcm_areas_from_bufs(pcm, areas, bufs);
snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -280,17 +280,17 @@ static ssize_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, size_t size)
return n;
}
-static ssize_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_file_t *file = pcm->private;
- size_t ofs = snd_pcm_mmap_offset(pcm);
- ssize_t n = snd_pcm_mmap_forward(file->slave, size);
- size_t xfer = 0;
+ snd_pcm_uframes_t ofs = snd_pcm_mmap_offset(pcm);
+ snd_pcm_sframes_t n = snd_pcm_mmap_forward(file->slave, size);
+ snd_pcm_uframes_t xfer = 0;
if (n <= 0)
return n;
- while (xfer < (size_t)n) {
- size_t frames = size - xfer;
- size_t cont = pcm->buffer_size - ofs;
+ while (xfer < (snd_pcm_uframes_t)n) {
+ snd_pcm_uframes_t frames = size - xfer;
+ snd_pcm_uframes_t cont = pcm->buffer_size - ofs;
if (frames > cont)
frames = cont;
snd_pcm_file_add_frames(pcm, snd_pcm_mmap_areas(file->slave), ofs, frames);
@@ -302,7 +302,7 @@ static ssize_t snd_pcm_file_mmap_forward(snd_pcm_t *pcm, size_t size)
return n;
}
-static ssize_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
{
snd_pcm_file_t *file = pcm->private;
return snd_pcm_avail_update(file->slave);
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index ebe34b5e..f64e037f 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -153,10 +153,10 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
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->period_step == pcm->period_step &&
+ params->sleep_min == pcm->sleep_min &&
params->xfer_align == pcm->xfer_align &&
params->silence_threshold == pcm->silence_threshold &&
params->silence_size == pcm->silence_size) {
@@ -210,7 +210,7 @@ static int snd_pcm_hw_state(snd_pcm_t *pcm)
return hw->mmap_status->state;
}
-static int snd_pcm_hw_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
@@ -291,27 +291,20 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
return 0;
}
-static ssize_t snd_pcm_hw_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- ssize_t hw_avail;
- if (pcm->xrun_mode == SND_PCM_XRUN_ASAP) {
- ssize_t d;
- int err = snd_pcm_hw_delay(pcm, &d);
- if (err < 0)
- return 0;
+ snd_pcm_hw_t *hw = pcm->private;
+ int fd = hw->fd;
+ if (ioctl(fd, SND_PCM_IOCTL_REWIND, &frames) < 0) {
+ SYSERR("SND_PCM_IOCTL_REWIND failed");
+ return -errno;
}
- hw_avail = snd_pcm_mmap_hw_avail(pcm);
- if (hw_avail <= 0)
- return 0;
- if (frames > (size_t)hw_avail)
- frames = hw_avail;
- snd_pcm_mmap_appl_backward(pcm, frames);
- return frames;
+ return 0;
}
-static ssize_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
- ssize_t result;
+ snd_pcm_sframes_t result;
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xferi_t xferi;
@@ -323,9 +316,9 @@ static ssize_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, size_t size
return xferi.result;
}
-static ssize_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
- ssize_t result;
+ snd_pcm_sframes_t result;
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xfern_t xfern;
@@ -337,9 +330,9 @@ static ssize_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, size_t size)
return xfern.result;
}
-static ssize_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
- ssize_t result;
+ snd_pcm_sframes_t result;
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xferi_t xferi;
@@ -351,9 +344,9 @@ static ssize_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, size_t size)
return xferi.result;
}
-ssize_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
- ssize_t result;
+ snd_pcm_sframes_t result;
snd_pcm_hw_t *hw = pcm->private;
int fd = hw->fd;
snd_xfern_t xfern;
@@ -419,7 +412,7 @@ static int snd_pcm_hw_mmap(snd_pcm_t *pcm)
{
snd_pcm_hw_t *hw = pcm->private;
if (!(pcm->info & SND_PCM_INFO_MMAP)) {
- size_t size = snd_pcm_frames_to_bytes(pcm, pcm->buffer_size);
+ snd_pcm_uframes_t size = snd_pcm_frames_to_bytes(pcm, pcm->buffer_size);
int id = shmget(IPC_PRIVATE, size, 0666);
if (id < 0) {
SYSERR("shmget failed");
@@ -455,7 +448,7 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
return 0;
}
-static ssize_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
if (!(pcm->info & SND_PCM_INFO_MMAP) &&
pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -464,17 +457,19 @@ static ssize_t snd_pcm_hw_mmap_forward(snd_pcm_t *pcm, size_t size)
return size;
}
-static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
{
- size_t avail;
- ssize_t err;
+ snd_pcm_uframes_t avail;
+ snd_pcm_sframes_t err;
+#if 0
if (pcm->ready_mode == SND_PCM_READY_ASAP ||
pcm->xrun_mode == SND_PCM_XRUN_ASAP) {
- ssize_t d;
+ snd_pcm_sframes_t d;
int err = snd_pcm_hw_delay(pcm, &d);
if (err < 0)
return err;
}
+#endif
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
avail = snd_pcm_mmap_playback_avail(pcm);
} else {
@@ -484,7 +479,7 @@ static ssize_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
err = snd_pcm_read_mmap(pcm, avail);
if (err < 0)
return err;
- assert((size_t)err == avail);
+ assert((snd_pcm_uframes_t)err == avail);
return err;
}
}
@@ -605,7 +600,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev
ret = -errno;
goto _err;
}
- if (info.subdevice != subdevice) {
+ if (info.subdevice != (unsigned int) subdevice) {
close(fd);
goto __again;
}
diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c
index 560c24ed..4c30e9e9 100644
--- a/src/pcm/pcm_linear.c
+++ b/src/pcm/pcm_linear.c
@@ -30,9 +30,9 @@ typedef struct {
int sformat;
} snd_pcm_linear_t;
-static void linear_transfer(const snd_pcm_channel_area_t *src_areas, size_t src_offset,
- const snd_pcm_channel_area_t *dst_areas, size_t dst_offset,
- size_t channels, size_t frames, int convidx)
+static void linear_transfer(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset,
+ const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int convidx)
{
#define CONV_LABELS
#include "plugin_ops.h"
@@ -43,7 +43,7 @@ static void linear_transfer(const snd_pcm_channel_area_t *src_areas, size_t src_
char *src;
char *dst;
int src_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -77,6 +77,7 @@ static int snd_pcm_linear_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_linear_t *linear = pcm->private;
snd_pcm_t *slave = linear->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
mask_t *access_mask = alloca(mask_sizeof());
mask_t *format_mask = alloca(mask_sizeof());
@@ -84,35 +85,41 @@ static int snd_pcm_linear_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- linear->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ linear->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -124,60 +131,68 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_linear_t *linear = pcm->private;
snd_pcm_t *slave = linear->plug.slave;
int err;
+ unsigned int links;
snd_pcm_hw_params_t sparams;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- linear->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 |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ linear->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
+ links = SND_PCM_HW_PARBIT_CHANNELS |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME;
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
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_param_value(params, SND_PCM_HW_PARAM_FORMAT),
+ linear->conv_idx = conv_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0),
linear->sformat);
else
linear->conv_idx = conv_index(linear->sformat,
- snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT));
+ snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
return 0;
}
-static ssize_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_linear_t *linear = pcm->private;
snd_pcm_t *slave = linear->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
linear_transfer(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
pcm->channels, frames, linear->conv_idx);
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -190,28 +205,28 @@ static ssize_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_linear_t *linear = pcm->private;
snd_pcm_t *slave = linear->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
linear_transfer(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames, linear->conv_idx);
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 7fba5fd3..c465d96c 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -71,14 +71,14 @@ typedef struct {
int (*drain)(snd_pcm_t *pcm);
int (*pause)(snd_pcm_t *pcm, int enable);
int (*state)(snd_pcm_t *pcm);
- int (*delay)(snd_pcm_t *pcm, ssize_t *delayp);
- ssize_t (*rewind)(snd_pcm_t *pcm, size_t frames);
- ssize_t (*writei)(snd_pcm_t *pcm, const void *buffer, size_t size);
- ssize_t (*writen)(snd_pcm_t *pcm, void **bufs, size_t size);
- ssize_t (*readi)(snd_pcm_t *pcm, void *buffer, size_t size);
- 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 (*delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+ snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+ snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+ snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+ snd_pcm_sframes_t (*readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+ snd_pcm_sframes_t (*readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+ snd_pcm_sframes_t (*avail_update)(snd_pcm_t *pcm);
+ snd_pcm_sframes_t (*mmap_forward)(snd_pcm_t *pcm, snd_pcm_uframes_t size);
} snd_pcm_fast_ops_t;
struct _snd_pcm {
@@ -93,30 +93,31 @@ struct _snd_pcm {
unsigned int subformat; /* subformat */
unsigned int channels; /* channels */
unsigned int rate; /* rate in Hz */
- size_t fragment_size; /* fragment size */
- unsigned int fragments; /* fragments */
- unsigned int start_mode; /* start 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 */
- unsigned int silence_mode; /* Silence filling mode */
- size_t silence_threshold; /* Silence filling happens when
+ snd_pcm_uframes_t period_size;
+ unsigned int period_time; /* period duration */
+ unsigned int tick_time;
+ snd_pcm_start_t start_mode; /* start mode */
+ snd_pcm_xrun_t xrun_mode; /* xrun detection mode */
+ snd_pcm_tstamp_t tstamp_mode; /* timestamp mode */
+ unsigned int period_step;
+ unsigned int sleep_min;
+ snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */
+ snd_pcm_uframes_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 */
- size_t boundary; /* pointers wrap point */
+ snd_pcm_uframes_t silence_size; /* Silence filling size */
+ snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
+ snd_pcm_uframes_t boundary; /* pointers wrap point */
unsigned int info; /* Info for returned setup */
unsigned int msbits; /* used most significant bits */
unsigned int rate_num; /* rate numerator */
unsigned int rate_den; /* rate denominator */
- size_t fifo_size; /* chip FIFO size in frames */
- size_t buffer_size;
- size_t bits_per_sample;
- size_t bits_per_frame;
- size_t *appl_ptr;
- size_t min_align;
- volatile size_t *hw_ptr;
+ snd_pcm_uframes_t fifo_size; /* chip FIFO size in frames */
+ snd_pcm_uframes_t buffer_size;
+ unsigned int bits_per_sample;
+ unsigned int bits_per_frame;
+ snd_pcm_uframes_t *appl_ptr;
+ snd_pcm_uframes_t min_align;
+ volatile snd_pcm_uframes_t *hw_ptr;
int mmap_rw;
snd_pcm_channel_info_t *mmap_channels;
snd_pcm_channel_area_t *running_areas;
@@ -142,52 +143,52 @@ void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void
int snd_pcm_mmap(snd_pcm_t *pcm);
int snd_pcm_munmap(snd_pcm_t *pcm);
int snd_pcm_mmap_ready(snd_pcm_t *pcm);
-ssize_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset);
-void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, size_t frames);
-void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, size_t frames);
-size_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
-size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames);
-size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames);
-
-typedef ssize_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
+snd_pcm_sframes_t snd_pcm_mmap_appl_ptr(snd_pcm_t *pcm, off_t offset);
+void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm);
+snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+
+typedef snd_pcm_sframes_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset, size_t size,
- size_t *slave_sizep);
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep);
-ssize_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
- size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
snd_pcm_xfer_areas_func_t func);
-ssize_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
- size_t offset, size_t size,
+snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas,
+ snd_pcm_uframes_t offset, snd_pcm_uframes_t size,
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);
+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size);
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);
-static inline size_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
+ snd_pcm_sframes_t avail;
avail = *pcm->hw_ptr + pcm->buffer_size - *pcm->appl_ptr;
if (avail < 0)
avail += pcm->boundary;
return avail;
}
-static inline size_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_capture_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
+ snd_pcm_sframes_t avail;
avail = *pcm->hw_ptr - *pcm->appl_ptr;
if (avail < 0)
avail += pcm->boundary;
return avail;
}
-static inline size_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
+static inline snd_pcm_uframes_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
+ snd_pcm_sframes_t avail;
avail = *pcm->hw_ptr - *pcm->appl_ptr;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
avail += pcm->buffer_size;
@@ -196,27 +197,19 @@ static inline size_t snd_pcm_mmap_avail(snd_pcm_t *pcm)
return avail;
}
-static inline ssize_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_playback_hw_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
- avail = *pcm->hw_ptr + pcm->buffer_size - *pcm->appl_ptr;
- if (avail < 0)
- avail += pcm->boundary;
- return pcm->buffer_size - avail;
+ return pcm->buffer_size - snd_pcm_mmap_playback_avail(pcm);
}
-static inline ssize_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_capture_hw_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
- avail = *pcm->hw_ptr - *pcm->appl_ptr;
- if (avail < 0)
- avail += pcm->boundary;
- return pcm->buffer_size - avail;
+ return pcm->buffer_size - snd_pcm_mmap_capture_avail(pcm);
}
-static inline ssize_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
{
- ssize_t avail;
+ snd_pcm_sframes_t avail;
avail = *pcm->hw_ptr - *pcm->appl_ptr;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
avail += pcm->buffer_size;
@@ -228,7 +221,7 @@ static inline ssize_t snd_pcm_mmap_hw_avail(snd_pcm_t *pcm)
#define snd_pcm_mmap_playback_delay snd_pcm_mmap_playback_hw_avail
#define snd_pcm_mmap_capture_delay snd_pcm_mmap_capture_avail
-static inline ssize_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
+static inline snd_pcm_sframes_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
{
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
return snd_pcm_mmap_playback_delay(pcm);
@@ -236,35 +229,35 @@ static inline ssize_t snd_pcm_mmap_delay(snd_pcm_t *pcm)
return snd_pcm_mmap_capture_delay(pcm);
}
-static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, size_t offset)
+static inline void *snd_pcm_channel_area_addr(const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset)
{
- size_t bitofs = area->first + area->step * offset;
+ unsigned int bitofs = area->first + area->step * offset;
assert(bitofs % 8 == 0);
return area->addr + bitofs / 8;
}
-static inline size_t snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
+static inline unsigned int snd_pcm_channel_area_step(const snd_pcm_channel_area_t *area)
{
assert(area->step % 8 == 0);
return area->step / 8;
}
-static inline ssize_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size);
}
-static inline ssize_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
return pcm->fast_ops->writen(pcm->fast_op_arg, bufs, size);
}
-static inline ssize_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size);
}
-static inline ssize_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+static inline snd_pcm_sframes_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size);
}
@@ -308,45 +301,71 @@ static inline int muldiv_near(int a, int b, int c)
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_param_mask(snd_pcm_hw_params_t *params, int hw,
+int _snd_pcm_hw_param_refine_interval(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const interval_t *val);
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
unsigned int var, const mask_t *mask);
-int _snd_pcm_hw_param_first(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,
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
unsigned int var);
-int _snd_pcm_hw_param_set(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 _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
- unsigned int var, unsigned int val);
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+ unsigned int var);
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+ unsigned int var, unsigned int val, int dir);
+int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+ unsigned int var, unsigned int val, int dir);
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+ unsigned int var, unsigned int val, int dir);
+int snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *src);
+int snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
+ unsigned int vars,
+ const snd_pcm_hw_params_t *src);
+int snd_pcm_generic_hw_link(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long links);
int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams,
- int (*func)(snd_pcm_t *slave,
- snd_pcm_hw_params_t *params),
+ int (*func)(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long private),
snd_pcm_t *slave,
- unsigned int links);
+ unsigned long private);
int snd_pcm_hw_params2(snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams,
int (*func)(snd_pcm_t *slave,
snd_pcm_hw_params_t *sparams),
snd_pcm_t *slave,
unsigned int links);
+void snd_pcm_hw_param_near_copy(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *src);
+int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *params1);
+int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *params1);
#define SND_PCM_HW_PARBIT_ACCESS (1 << SND_PCM_HW_PARAM_ACCESS)
#define SND_PCM_HW_PARBIT_FORMAT (1 << SND_PCM_HW_PARAM_FORMAT)
#define SND_PCM_HW_PARBIT_SUBFORMAT (1 << SND_PCM_HW_PARAM_SUBFORMAT)
#define SND_PCM_HW_PARBIT_CHANNELS (1 << SND_PCM_HW_PARAM_CHANNELS)
#define SND_PCM_HW_PARBIT_RATE (1 << SND_PCM_HW_PARAM_RATE)
-#define SND_PCM_HW_PARBIT_FRAGMENT_LENGTH (1 << SND_PCM_HW_PARAM_FRAGMENT_LENGTH)
-#define SND_PCM_HW_PARBIT_FRAGMENT_SIZE (1 << SND_PCM_HW_PARAM_FRAGMENT_SIZE)
-#define SND_PCM_HW_PARBIT_FRAGMENTS (1 << SND_PCM_HW_PARAM_FRAGMENTS)
-#define SND_PCM_HW_PARBIT_BUFFER_LENGTH (1 << SND_PCM_HW_PARAM_BUFFER_LENGTH)
+#define SND_PCM_HW_PARBIT_PERIOD_TIME (1 << SND_PCM_HW_PARAM_PERIOD_TIME)
+#define SND_PCM_HW_PARBIT_PERIOD_SIZE (1 << SND_PCM_HW_PARAM_PERIOD_SIZE)
+#define SND_PCM_HW_PARBIT_PERIODS (1 << SND_PCM_HW_PARAM_PERIODS)
+#define SND_PCM_HW_PARBIT_BUFFER_TIME (1 << SND_PCM_HW_PARAM_BUFFER_TIME)
#define SND_PCM_HW_PARBIT_BUFFER_SIZE (1 << SND_PCM_HW_PARAM_BUFFER_SIZE)
#define SND_PCM_HW_PARBIT_SAMPLE_BITS (1 << SND_PCM_HW_PARAM_SAMPLE_BITS)
#define SND_PCM_HW_PARBIT_FRAME_BITS (1 << SND_PCM_HW_PARAM_FRAME_BITS)
-#define SND_PCM_HW_PARBIT_FRAGMENT_BYTES (1 << SND_PCM_HW_PARAM_FRAGMENT_BYTES)
+#define SND_PCM_HW_PARBIT_PERIOD_BYTES (1 << SND_PCM_HW_PARAM_PERIOD_BYTES)
#define SND_PCM_HW_PARBIT_BUFFER_BYTES (1 << SND_PCM_HW_PARAM_BUFFER_BYTES)
+#define SND_PCM_HW_PARBIT_TICK_TIME (1 << SND_PCM_HW_PARAM_TICK_TIME)
#define SND_PCM_ACCBIT_MMAP ((1 << SND_PCM_ACCESS_MMAP_INTERLEAVED) | \
diff --git a/src/pcm/pcm_misc.c b/src/pcm/pcm_misc.c
index 5d0f0c20..fa7b7e7b 100644
--- a/src/pcm/pcm_misc.c
+++ b/src/pcm/pcm_misc.c
@@ -360,14 +360,14 @@ u_int8_t snd_pcm_format_silence(int format)
return (u_int8_t)snd_pcm_format_silence_64(format);
}
-ssize_t snd_pcm_format_set_silence(int format, void *data, size_t samples)
+int snd_pcm_format_set_silence(int format, void *data, unsigned int samples)
{
if (samples == 0)
return 0;
switch (snd_pcm_format_width(format)) {
case 4: {
u_int8_t silence = snd_pcm_format_silence_64(format);
- size_t samples1;
+ unsigned int samples1;
if (samples % 2 != 0)
return -EINVAL;
samples1 = samples / 2;
@@ -405,9 +405,9 @@ ssize_t snd_pcm_format_set_silence(int format, void *data, size_t samples)
static int linear_formats[4*2*2] = {
SND_PCM_FORMAT_S8,
- SND_PCM_FORMAT_U8,
SND_PCM_FORMAT_S8,
SND_PCM_FORMAT_U8,
+ SND_PCM_FORMAT_U8,
SND_PCM_FORMAT_S16_LE,
SND_PCM_FORMAT_S16_BE,
SND_PCM_FORMAT_U16_LE,
diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c
index 0ade84ab..d362aae6 100644
--- a/src/pcm/pcm_mmap.c
+++ b/src/pcm/pcm_mmap.c
@@ -52,10 +52,10 @@ const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm)
return pcm->running_areas;
}
-size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- size_t cont;
- size_t avail = snd_pcm_mmap_playback_avail(pcm);
+ snd_pcm_uframes_t cont;
+ snd_pcm_uframes_t avail = snd_pcm_mmap_playback_avail(pcm);
if (avail < frames)
frames = avail;
cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
@@ -64,10 +64,10 @@ size_t snd_pcm_mmap_playback_xfer(snd_pcm_t *pcm, size_t frames)
return frames;
}
-size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- size_t cont;
- size_t avail = snd_pcm_mmap_capture_avail(pcm);
+ snd_pcm_uframes_t cont;
+ snd_pcm_uframes_t avail = snd_pcm_mmap_capture_avail(pcm);
if (avail < frames)
frames = avail;
cont = pcm->buffer_size - *pcm->appl_ptr % pcm->buffer_size;
@@ -76,7 +76,7 @@ size_t snd_pcm_mmap_capture_xfer(snd_pcm_t *pcm, size_t frames)
return frames;
}
-size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t frames)
+snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
assert(pcm);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -85,73 +85,73 @@ size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t frames)
return snd_pcm_mmap_capture_xfer(pcm, frames);
}
-size_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
+snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm)
{
assert(pcm);
return *pcm->appl_ptr % pcm->buffer_size;
}
-size_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
+snd_pcm_uframes_t snd_pcm_mmap_hw_offset(snd_pcm_t *pcm)
{
assert(pcm);
return *pcm->hw_ptr % pcm->buffer_size;
}
-void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_appl_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- ssize_t appl_ptr = *pcm->appl_ptr;
+ snd_pcm_sframes_t appl_ptr = *pcm->appl_ptr;
appl_ptr -= frames;
if (appl_ptr < 0)
appl_ptr += pcm->boundary;
*pcm->appl_ptr = appl_ptr;
}
-void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_appl_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- size_t appl_ptr = *pcm->appl_ptr;
+ snd_pcm_uframes_t appl_ptr = *pcm->appl_ptr;
appl_ptr += frames;
if (appl_ptr >= pcm->boundary)
appl_ptr -= pcm->boundary;
*pcm->appl_ptr = appl_ptr;
}
-void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_hw_backward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- ssize_t hw_ptr = *pcm->hw_ptr;
+ snd_pcm_sframes_t hw_ptr = *pcm->hw_ptr;
hw_ptr -= frames;
if (hw_ptr < 0)
hw_ptr += pcm->boundary;
*pcm->hw_ptr = hw_ptr;
}
-void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, size_t frames)
+void snd_pcm_mmap_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
- size_t hw_ptr = *pcm->hw_ptr;
+ snd_pcm_uframes_t hw_ptr = *pcm->hw_ptr;
hw_ptr += frames;
if (hw_ptr >= pcm->boundary)
hw_ptr -= pcm->boundary;
*pcm->hw_ptr = hw_ptr;
}
-ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
+snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
- size_t xfer;
+ snd_pcm_uframes_t xfer;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
xfer = 0;
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer);
- ssize_t err;
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(pcm, size - xfer);
+ snd_pcm_sframes_t err;
snd_pcm_areas_copy(areas, offset,
snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
pcm->channels,
frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames);
- assert(err == (ssize_t)frames);
+ assert(err == (snd_pcm_sframes_t)frames);
offset += frames;
xfer += frames;
}
@@ -160,25 +160,25 @@ ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
return xfer;
}
-ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
+snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
- size_t xfer;
+ snd_pcm_uframes_t xfer;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
xfer = 0;
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer);
- ssize_t err;
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(pcm, size - xfer);
+ snd_pcm_sframes_t err;
snd_pcm_areas_copy(snd_pcm_mmap_areas(pcm), snd_pcm_mmap_offset(pcm),
areas, offset,
pcm->channels,
frames, pcm->format);
err = snd_pcm_mmap_forward(pcm, frames);
- assert(err == (ssize_t)frames);
+ assert(err == (snd_pcm_sframes_t)frames);
offset += frames;
xfer += frames;
}
@@ -187,7 +187,7 @@ ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
return xfer;
}
-ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_channel_area_t areas[pcm->channels];
snd_pcm_areas_from_buf(pcm, areas, (void*)buffer);
@@ -195,7 +195,7 @@ ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
snd_pcm_mmap_write_areas);
}
-ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_channel_area_t areas[pcm->channels];
snd_pcm_areas_from_bufs(pcm, areas, bufs);
@@ -203,7 +203,7 @@ ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size)
snd_pcm_mmap_write_areas);
}
-ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_channel_area_t areas[pcm->channels];
snd_pcm_areas_from_buf(pcm, areas, buffer);
@@ -211,7 +211,7 @@ ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size)
snd_pcm_mmap_read_areas);
}
-ssize_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_channel_area_t areas[pcm->channels];
snd_pcm_areas_from_bufs(pcm, areas, bufs);
@@ -421,15 +421,15 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
return 0;
}
-ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
assert(size > 0);
while (xfer < size) {
- size_t frames = size - xfer;
- size_t offset = snd_pcm_mmap_hw_offset(pcm);
- size_t cont = pcm->buffer_size - offset;
+ snd_pcm_uframes_t frames = size - xfer;
+ snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+ snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < frames)
frames = cont;
switch (pcm->access) {
@@ -442,7 +442,7 @@ ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
}
case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
{
- size_t channels = pcm->channels;
+ unsigned int channels = pcm->channels;
unsigned int c;
void *bufs[channels];
const snd_pcm_channel_area_t *areas = snd_pcm_mmap_areas(pcm);
@@ -467,15 +467,15 @@ ssize_t snd_pcm_write_mmap(snd_pcm_t *pcm, size_t size)
return err;
}
-ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size)
+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
assert(size > 0);
while (xfer < size) {
- size_t frames = size - xfer;
- size_t offset = snd_pcm_mmap_hw_offset(pcm);
- size_t cont = pcm->buffer_size - offset;
+ snd_pcm_uframes_t frames = size - xfer;
+ snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+ snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < frames)
frames = cont;
switch (pcm->access) {
@@ -488,7 +488,7 @@ ssize_t snd_pcm_read_mmap(snd_pcm_t *pcm, size_t size)
}
case SND_PCM_ACCESS_MMAP_NONINTERLEAVED:
{
- size_t channels = pcm->channels;
+ snd_pcm_uframes_t channels = pcm->channels;
unsigned int c;
void *bufs[channels];
const snd_pcm_channel_area_t *areas = snd_pcm_mmap_areas(pcm);
diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c
index 5f663464..ff67c6d3 100644
--- a/src/pcm/pcm_mulaw.c
+++ b/src/pcm/pcm_mulaw.c
@@ -24,10 +24,10 @@
#include "pcm_plugin.h"
typedef void (*mulaw_f)(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getputidx);
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getputidx);
typedef struct {
/* This field need to be the first */
@@ -138,21 +138,21 @@ static int ulaw_to_s16(unsigned char u_val)
}
static void mulaw_decode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int putidx)
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int putidx)
{
#define PUT16_LABELS
#include "plugin_ops.h"
#undef PUT16_LABELS
void *put = put16_labels[putidx];
- size_t channel;
+ unsigned int channel;
for (channel = 0; channel < channels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -183,22 +183,22 @@ static void mulaw_decode(const snd_pcm_channel_area_t *src_areas,
}
static void mulaw_encode(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t channels, size_t frames, int getidx)
+ snd_pcm_uframes_t dst_offset,
+ unsigned int channels, snd_pcm_uframes_t frames, int getidx)
{
#define GET16_LABELS
#include "plugin_ops.h"
#undef GET16_LABELS
void *get = get16_labels[getidx];
- size_t channel;
+ unsigned int channel;
int16_t sample = 0;
for (channel = 0; channel < channels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
- size_t frames1;
+ snd_pcm_uframes_t frames1;
const snd_pcm_channel_area_t *src_area = &src_areas[channel];
const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
#if 0
@@ -233,51 +233,58 @@ static int snd_pcm_mulaw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_mulaw_t *mulaw = pcm->private;
snd_pcm_t *slave = mulaw->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
mask_t *access_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, 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_param_mask(params, 1,
+ err = _snd_pcm_hw_param_mask(params,
SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
} else {
- err = _snd_pcm_hw_param_set(params, 1,
+ err = _snd_pcm_hw_param_set(params,
SND_PCM_HW_PARAM_FORMAT,
- SND_PCM_FORMAT_MU_LAW);
+ SND_PCM_FORMAT_MU_LAW, 0);
if (err < 0)
return err;
}
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 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);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ mulaw->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -289,32 +296,40 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
snd_pcm_mulaw_t *mulaw = pcm->private;
snd_pcm_t *slave = mulaw->plug.slave;
int err;
+ unsigned int links;
snd_pcm_hw_params_t sparams;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, 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 |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ mulaw->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
+ links = SND_PCM_HW_PARBIT_CHANNELS |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME;
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
return err;
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_param_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, 0), SND_PCM_FORMAT_S16);
mulaw->func = mulaw_encode;
} else {
mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, mulaw->sformat);
@@ -322,7 +337,7 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
}
} else {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
- mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_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, 0));
mulaw->func = mulaw_decode;
} else {
mulaw->getput_idx = get_index(mulaw->sformat, SND_PCM_FORMAT_S16);
@@ -332,21 +347,21 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0;
}
-static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_mulaw_t *mulaw = pcm->private;
snd_pcm_t *slave = mulaw->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
mulaw->func(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
pcm->channels, frames,
@@ -354,7 +369,7 @@ static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -367,21 +382,21 @@ static ssize_t snd_pcm_mulaw_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_mulaw_t *mulaw = pcm->private;
snd_pcm_t *slave = mulaw->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
mulaw->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames,
@@ -389,7 +404,7 @@ static ssize_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c
index 4cb55f8d..28719ae8 100644
--- a/src/pcm/pcm_multi.c
+++ b/src/pcm/pcm_multi.c
@@ -40,16 +40,16 @@ typedef struct {
} snd_pcm_multi_channel_t;
typedef struct {
- size_t slaves_count;
+ unsigned int slaves_count;
snd_pcm_multi_slave_t *slaves;
- size_t channels_count;
+ unsigned int channels_count;
snd_pcm_multi_channel_t *channels;
} snd_pcm_multi_t;
static int snd_pcm_multi_close(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private;
- size_t i;
+ unsigned int i;
int ret = 0;
for (i = 0; i < multi->slaves_count; ++i) {
int err;
@@ -102,7 +102,8 @@ static int snd_pcm_multi_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
unsigned int k;
snd_pcm_hw_params_t sparams;
int changed = 0;
- int err;
+ int err = 0;
+ unsigned int cmask, lcmask;
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) ||
@@ -122,38 +123,50 @@ static int snd_pcm_multi_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
}
}
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
- multi->channels_count);
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
+ multi->channels_count, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ cmask |= params->cmask;
+
changed = 0;
do {
for (k = 0; k < multi->slaves_count; ++k) {
snd_pcm_t *slave = multi->slaves[k].pcm;
+ params->cmask = cmask;
_snd_pcm_hw_params_any(&sparams);
- _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_CHANNELS,
- multi->slaves[k].channels_count);
+ _snd_pcm_hw_param_mask(&sparams,
+ SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams,
+ SND_PCM_HW_PARAM_CHANNELS,
+ multi->slaves[k].channels_count, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave,
+ snd_pcm_generic_hw_link, slave,
SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH |
- SND_PCM_HW_PARBIT_FRAGMENTS);
- if (err < 0)
- return err;
- if (params->hw_cmask)
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_TICK_TIME);
+ if (params->cmask) {
changed++;
+ lcmask |= params->cmask;
+ cmask |= params->cmask;
+ }
+ if (err < 0)
+ goto _end;
}
} while (changed && multi->slaves_count > 1);
- return 0;
+ _end:
+ params->cmask = lcmask;
+ return err;
}
static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
@@ -163,6 +176,16 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
int err;
const mask_t *access_mask = snd_pcm_hw_param_value_mask(params, SND_PCM_HW_PARAM_ACCESS);
mask_t *saccess_mask = alloca(mask_sizeof());
+ unsigned int links;
+ links = SND_PCM_HW_PARBIT_FORMAT |
+ SND_PCM_HW_PARBIT_SUBFORMAT |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_TICK_TIME;
if (mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
@@ -183,20 +206,18 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_t *slave = multi->slaves[k].pcm;
snd_pcm_hw_params_t sparams;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- _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,
- SND_PCM_HW_PARBIT_FORMAT |
- SND_PCM_HW_PARBIT_SUBFORMAT |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH |
- SND_PCM_HW_PARBIT_FRAGMENTS);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+ multi->slaves[k].channels_count, 0);
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 0)
return err;
err = snd_pcm_areas_silence(slave->running_areas, 0, slave->channels, slave->buffer_size, slave->format);
@@ -239,14 +260,14 @@ static int snd_pcm_multi_state(snd_pcm_t *pcm)
return snd_pcm_state(slave);
}
-static int snd_pcm_multi_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_multi_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *slave = multi->slaves[0].pcm;
return snd_pcm_delay(slave, delayp);
}
-static ssize_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_multi_avail_update(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private;
snd_pcm_t *slave = multi->slaves[0].pcm;
@@ -303,15 +324,15 @@ static int snd_pcm_multi_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *in
return err;
}
-static ssize_t snd_pcm_multi_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_multi_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
- size_t pos[multi->slaves_count];
+ snd_pcm_uframes_t pos[multi->slaves_count];
memset(pos, 0, sizeof(pos));
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *slave_i = multi->slaves[i].pcm;
- ssize_t f = snd_pcm_rewind(slave_i, frames);
+ snd_pcm_sframes_t f = snd_pcm_rewind(slave_i, frames);
if (f < 0)
return f;
pos[i] = f;
@@ -320,28 +341,28 @@ static ssize_t snd_pcm_multi_rewind(snd_pcm_t *pcm, size_t frames)
/* Realign the pointers */
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *slave_i = multi->slaves[i].pcm;
- size_t f = pos[i] - frames;
+ snd_pcm_uframes_t f = pos[i] - frames;
if (f > 0)
snd_pcm_mmap_appl_forward(slave_i, f);
}
return frames;
}
-static ssize_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_multi_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_multi_t *multi = pcm->private;
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_t *slave = multi->slaves[i].pcm;
- ssize_t frames = snd_pcm_mmap_forward(slave, size);
+ snd_pcm_sframes_t frames = snd_pcm_mmap_forward(slave, size);
if (frames < 0)
return frames;
if (i == 0) {
size = frames;
continue;
}
- if ((size_t) frames != size)
+ if ((snd_pcm_uframes_t) frames != size)
return -EBADFD;
}
return size;
@@ -422,9 +443,9 @@ snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
};
int snd_pcm_multi_open(snd_pcm_t **pcmp, char *name,
- size_t slaves_count,
- snd_pcm_t **slaves_pcm, size_t *schannels_count,
- size_t channels_count,
+ unsigned int slaves_count,
+ snd_pcm_t **slaves_pcm, unsigned int *schannels_count,
+ unsigned int channels_count,
int *sidxs, unsigned int *schannels,
int close_slaves)
{
@@ -505,11 +526,11 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
char **slaves_id = NULL;
char **slaves_name = NULL;
snd_pcm_t **slaves_pcm = NULL;
- size_t *slaves_channels = NULL;
+ unsigned int *slaves_channels = NULL;
unsigned int *channels_sidx = NULL;
unsigned int *channels_schannel = NULL;
- size_t slaves_count = 0;
- size_t channels_count = 0;
+ unsigned int slaves_count = 0;
+ unsigned int channels_count = 0;
snd_config_foreach(i, conf) {
snd_config_t *n = snd_config_entry(i);
if (strcmp(n->id, "comment") == 0)
@@ -667,7 +688,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
err = -EINVAL;
goto _free;
}
- if (slave < 0 || (size_t)slave >= slaves_count) {
+ if (slave < 0 || (unsigned int)slave >= slaves_count) {
ERR("Invalid or missing sidx");
err = -EINVAL;
goto _free;
diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c
index 3390e49c..f2e6e148 100644
--- a/src/pcm/pcm_null.c
+++ b/src/pcm/pcm_null.c
@@ -29,8 +29,8 @@ typedef struct {
snd_timestamp_t trigger_time;
int state;
int shmid;
- size_t appl_ptr;
- size_t hw_ptr;
+ snd_pcm_uframes_t appl_ptr;
+ snd_pcm_uframes_t hw_ptr;
int poll_fd;
} snd_pcm_null_t;
@@ -88,7 +88,7 @@ static int snd_pcm_null_state(snd_pcm_t *pcm)
return null->state;
}
-static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, ssize_t *delayp)
+static int snd_pcm_null_delay(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sframes_t *delayp)
{
*delayp = 0;
return 0;
@@ -149,7 +149,7 @@ static int snd_pcm_null_pause(snd_pcm_t *pcm, int enable)
return 0;
}
-static ssize_t snd_pcm_null_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_null_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_null_t *null = pcm->private;
switch (null->state) {
@@ -163,7 +163,7 @@ static ssize_t snd_pcm_null_rewind(snd_pcm_t *pcm, size_t frames)
}
}
-static ssize_t snd_pcm_null_fwd(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_fwd(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_null_t *null = pcm->private;
switch (null->state) {
@@ -177,7 +177,7 @@ static ssize_t snd_pcm_null_fwd(snd_pcm_t *pcm, size_t size)
}
}
-static ssize_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
{
snd_pcm_null_t *null = pcm->private;
if (null->state == SND_PCM_STATE_PREPARED &&
@@ -187,7 +187,7 @@ static ssize_t snd_pcm_null_writei(snd_pcm_t *pcm, const void *buffer ATTRIBUTE_
return snd_pcm_null_fwd(pcm, size);
}
-static ssize_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
{
snd_pcm_null_t *null = pcm->private;
if (null->state == SND_PCM_STATE_PREPARED &&
@@ -197,7 +197,7 @@ static ssize_t snd_pcm_null_writen(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED,
return snd_pcm_null_fwd(pcm, size);
}
-static ssize_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
{
snd_pcm_null_t *null = pcm->private;
if (null->state == SND_PCM_STATE_PREPARED &&
@@ -208,7 +208,7 @@ static ssize_t snd_pcm_null_readi(snd_pcm_t *pcm, void *buffer ATTRIBUTE_UNUSED,
return snd_pcm_null_fwd(pcm, size);
}
-static ssize_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED, snd_pcm_uframes_t size)
{
snd_pcm_null_t *null = pcm->private;
if (null->state == SND_PCM_STATE_PREPARED &&
@@ -219,12 +219,12 @@ static ssize_t snd_pcm_null_readn(snd_pcm_t *pcm, void **bufs ATTRIBUTE_UNUSED,
return snd_pcm_null_fwd(pcm, size);
}
-static ssize_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_null_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
return snd_pcm_null_fwd(pcm, size);
}
-static ssize_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_null_avail_update(snd_pcm_t *pcm)
{
return pcm->buffer_size;
}
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 0d126f11..154a53aa 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -25,18 +25,51 @@
#include "interval.h"
#include "mask.h"
-static inline unsigned int add(unsigned int a, unsigned int b)
-{
- if (a >= UINT_MAX - b)
- return UINT_MAX;
- return a + b;
-}
-
-static inline unsigned int sub(unsigned int a, unsigned int b)
-{
- if (a > b)
- return a - b;
- return 0;
+static void approx_sub(int a, int adir,
+ int b, int bdir,
+ int *c, int *cdir)
+{
+ adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
+ bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
+ *c = a - b;
+ *cdir = adir - bdir;
+ if (*cdir == -2) {
+ assert(*c > INT_MIN);
+ (*c)--;
+ } else if (*cdir == 2) {
+ assert(*c < INT_MAX);
+ (*c)++;
+ }
+}
+
+static int approx_lt(unsigned int a, int adir,
+ unsigned int b, int bdir)
+{
+ assert(a > 0 || adir >= 0);
+ assert(b > 0 || bdir >= 0);
+ if (adir < 0) {
+ a--;
+ adir = 1;
+ } else if (adir > 0)
+ adir = 1;
+ if (bdir < 0) {
+ b--;
+ bdir = 1;
+ } else if (bdir > 0)
+ bdir = 1;
+ return a < b || (a == b && adir < bdir);
+}
+
+/* Return 1 if max is nearer to best than min */
+static int approx_nearer(int min, int mindir,
+ int best, int bestdir,
+ int max, int maxdir)
+{
+ int dmin, dmindir;
+ int dmax, dmaxdir;
+ approx_sub(best, bestdir, min, mindir, &dmin, &dmindir);
+ approx_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
+ return approx_lt(dmax, dmaxdir, dmin, dmindir);
}
static inline int hw_is_mask(int var)
@@ -52,48 +85,48 @@ static inline int hw_is_interval(int var)
}
static inline mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
assert(hw_is_mask(var));
return (mask_t*)&params->masks[var - SND_PCM_HW_PARAM_FIRST_MASK];
}
static inline interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
assert(hw_is_interval(var));
return &params->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
}
static inline const mask_t *hw_param_mask_c(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
return (const mask_t *)hw_param_mask((snd_pcm_hw_params_t*) params, var);
}
static inline const interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t 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)
+void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var)
{
if (hw_is_mask(var)) {
- mask_all(hw_param_mask(params, var));
- params->appl_cmask |= 1 << var;
+ mask_any(hw_param_mask(params, var));
+ params->cmask |= 1 << var;
return;
}
if (hw_is_interval(var)) {
- interval_all(hw_param_interval(params, var));
- params->appl_cmask |= 1 << var;
+ interval_any(hw_param_interval(params, var));
+ params->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_t var)
{
_snd_pcm_hw_param_any(params, var);
return snd_pcm_hw_refine(pcm, params);
@@ -105,9 +138,6 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
memset(params, 0, sizeof(*params));
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;
}
@@ -122,18 +152,22 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
defined by PARAMS. Return -EINVAL otherwise
*/
int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var, int *dir)
{
if (hw_is_mask(var)) {
const mask_t *mask = hw_param_mask_c(params, var);
if (!mask_single(mask))
return -EINVAL;
+ if (dir)
+ *dir = 0;
return mask_value(mask);
}
if (hw_is_interval(var)) {
const interval_t *i = hw_param_interval_c(params, var);
if (!interval_single(i))
return -EINVAL;
+ if (dir)
+ *dir = i->openmin;
return interval_value(i);
}
assert(0);
@@ -142,13 +176,18 @@ int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
/* Return the minimum value for field PAR. */
unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var, int *dir)
{
if (hw_is_mask(var)) {
+ if (dir)
+ *dir = 0;
return mask_min(hw_param_mask_c(params, var));
}
if (hw_is_interval(var)) {
- return interval_min(hw_param_interval_c(params, var));
+ const interval_t *i = hw_param_interval_c(params, var);
+ if (dir)
+ *dir = i->openmin;
+ return interval_min(i);
}
assert(0);
return -EINVAL;
@@ -156,13 +195,18 @@ unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
/* Return the maximum value for field PAR. */
unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var, int *dir)
{
if (hw_is_mask(var)) {
+ if (dir)
+ *dir = 0;
return mask_max(hw_param_mask_c(params, var));
}
if (hw_is_interval(var)) {
- return interval_max(hw_param_interval_c(params, var));
+ const interval_t *i = hw_param_interval_c(params, var);
+ if (dir)
+ *dir = - (int) i->openmax;
+ return interval_max(i);
}
assert(0);
return -EINVAL;
@@ -172,7 +216,7 @@ unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
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_param_value_mask(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
assert(hw_is_mask(var));
return hw_param_mask_c(params, var);
@@ -182,17 +226,58 @@ const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
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_param_value_interval(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
assert(hw_is_interval(var));
return hw_param_interval_c(params, var);
}
-
/* --- Refinement functions --- */
-int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
- unsigned int var)
+int _snd_pcm_hw_param_refine_interval(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const interval_t *val)
+{
+ int changed;
+ assert(hw_is_interval(var));
+ changed = interval_refine(hw_param_interval(params, var), val);
+ if (changed)
+ params->cmask |= 1 << var;
+ return changed;
+}
+
+int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ int changed;
+ assert(hw_is_interval(var));
+ changed = interval_setinteger(hw_param_interval(params, var));
+ if (changed)
+ params->cmask |= 1 << var;
+ return changed;
+}
+
+/* Inside configuration space defined by PARAMS remove from PAR all
+ non integer values. Reduce configuration space accordingly.
+ Return -EINVAL if the configuration space is empty
+*/
+int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ int changed = _snd_pcm_hw_param_setinteger(params, var);
+ if (changed < 0)
+ return changed;
+ if (changed) {
+ int err = snd_pcm_hw_refine(pcm, params);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
{
int changed;
if (hw_is_mask(var))
@@ -203,12 +288,8 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -218,20 +299,21 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, int hw,
Return the minimum.
*/
int snd_pcm_hw_param_first(snd_pcm_t *pcm,
- snd_pcm_hw_params_t *params, unsigned int var)
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir)
{
- int changed = _snd_pcm_hw_param_first(params, 0, var);
+ int changed = _snd_pcm_hw_param_first(params, var);
if (changed < 0)
return changed;
if (changed) {
int err = snd_pcm_hw_refine(pcm, params);
assert(err >= 0);
}
- return snd_pcm_hw_param_value(params, var);
+ return snd_pcm_hw_param_value(params, var, dir);
}
-int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
- unsigned int var)
+int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
{
int changed;
if (hw_is_mask(var))
@@ -242,12 +324,8 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -257,36 +335,44 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, int hw,
Return the maximum.
*/
int snd_pcm_hw_param_last(snd_pcm_t *pcm,
- snd_pcm_hw_params_t *params, unsigned int var)
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir)
{
- int changed = _snd_pcm_hw_param_last(params, 0, var);
+ int changed = _snd_pcm_hw_param_last(params, var);
if (changed < 0)
return changed;
if (changed) {
int err = snd_pcm_hw_refine(pcm, params);
assert(err >= 0);
}
- return snd_pcm_hw_param_value(params, var);
+ return snd_pcm_hw_param_value(params, var, dir);
}
-int _snd_pcm_hw_param_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,
+ snd_pcm_hw_param_t var, unsigned int val, int dir)
{
int changed;
+ int open = 0;
+ if (dir) {
+ if (dir > 0) {
+ open = 1;
+ } else if (dir < 0) {
+ if (val > 0) {
+ open = 1;
+ val--;
+ }
+ }
+ }
if (hw_is_mask(var))
- changed = mask_refine_min(hw_param_mask(params, var), val);
+ changed = mask_refine_min(hw_param_mask(params, var), val + !!open);
else if (hw_is_interval(var))
- changed = interval_refine_min(hw_param_interval(params, var), val);
+ changed = interval_refine_min(hw_param_interval(params, var), val, open);
else {
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -295,9 +381,9 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, int hw,
Return new minimum or -EINVAL if the configuration space is empty
*/
int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var, unsigned int val, int *dir)
{
- int changed = _snd_pcm_hw_param_min(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
if (changed < 0)
return changed;
if (changed) {
@@ -305,39 +391,49 @@ int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
if (err < 0)
return err;
}
- return snd_pcm_hw_param_value_min(params, var);
+ return snd_pcm_hw_param_value_min(params, var, dir);
}
int snd_pcm_hw_param_min_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir)
{
snd_pcm_hw_params_t save;
int err;
save = *params;
- err = snd_pcm_hw_param_min(pcm, params, var, val);
+ err = snd_pcm_hw_param_min(pcm, params, var, val, dir);
if (err < 0)
*params = save;
return err;
}
-int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
- unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, unsigned int val, int dir)
{
int changed;
- 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);
+ int open = 0;
+ if (dir) {
+ if (dir < 0) {
+ open = 1;
+ } else if (dir > 0) {
+ open = 1;
+ val++;
+ }
+ }
+ if (hw_is_mask(var)) {
+ if (val == 0 && open) {
+ mask_none(hw_param_mask(params, var));
+ changed = -EINVAL;
+ } else
+ changed = mask_refine_max(hw_param_mask(params, var), val - !!open);
+ } else if (hw_is_interval(var))
+ changed = interval_refine_max(hw_param_interval(params, var), val, open);
else {
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -346,9 +442,9 @@ int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, int hw,
Return new maximum or -EINVAL if the configuration space is empty
*/
int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var, unsigned int val, int *dir)
{
- int changed = _snd_pcm_hw_param_max(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
if (changed < 0)
return changed;
if (changed) {
@@ -356,46 +452,72 @@ int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
if (err < 0)
return err;
}
- return snd_pcm_hw_param_value_max(params, var);
+ return snd_pcm_hw_param_value_max(params, var, dir);
}
int snd_pcm_hw_param_max_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir)
{
snd_pcm_hw_params_t save;
int err;
save = *params;
- err = snd_pcm_hw_param_max(pcm, params, var, val);
+ err = snd_pcm_hw_param_max(pcm, params, var, val, dir);
if (err < 0)
*params = save;
return err;
}
-int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
- unsigned int var,
- unsigned int min, unsigned int max)
+int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int min, int mindir,
+ unsigned int max, int maxdir)
{
int changed, c1, c2;
+ int openmin = 0, openmax = 0;
+ if (mindir) {
+ if (mindir > 0) {
+ openmin = 1;
+ } else if (mindir < 0) {
+ if (min > 0) {
+ openmin = 1;
+ min--;
+ }
+ }
+ }
+ if (maxdir) {
+ if (maxdir < 0) {
+ openmax = 1;
+ } else if (maxdir > 0) {
+ openmax = 1;
+ max++;
+ }
+ }
if (hw_is_mask(var)) {
mask_t *mask = hw_param_mask(params, var);
- c1 = mask_refine_min(mask, min);
- if (c1 < 0)
- changed = c1;
- else {
- c2 = mask_refine_max(mask, max);
- if (c2 < 0)
- changed = c2;
- else
- changed = (c1 || c2);
+ if (max == 0 && openmax) {
+ mask_none(mask);
+ changed = -EINVAL;
+ } else {
+ c1 = mask_refine_min(mask, min + !!openmin);
+ if (c1 < 0)
+ changed = c1;
+ else {
+ c2 = mask_refine_max(mask, max - !!openmax);
+ if (c2 < 0)
+ changed = c2;
+ else
+ changed = (c1 || c2);
+ }
}
}
else if (hw_is_interval(var)) {
interval_t *i = hw_param_interval(params, var);
- c1 = interval_refine_min(i, min);
+ c1 = interval_refine_min(i, min, openmin);
if (c1 < 0)
changed = c1;
else {
- c2 = interval_refine_max(i, max);
+ c2 = interval_refine_max(i, max, openmax);
if (c2 < 0)
changed = c2;
else
@@ -405,12 +527,8 @@ int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -419,10 +537,13 @@ int _snd_pcm_hw_param_minmax(snd_pcm_hw_params_t *params, int hw,
Return 0 or -EINVAL if the configuration space is empty
*/
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)
+ snd_pcm_hw_param_t var,
+ unsigned int *min, int *mindir,
+ unsigned int *max, int *maxdir)
{
- int changed = _snd_pcm_hw_param_minmax(params, 0, var, min, max);
+ int changed = _snd_pcm_hw_param_minmax(params, var,
+ *min, mindir ? *mindir : 0,
+ *max, maxdir ? *maxdir : 0);
if (changed < 0)
return changed;
if (changed) {
@@ -430,51 +551,82 @@ int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
if (err < 0)
return err;
}
+ *min = snd_pcm_hw_param_value_min(params, var, mindir);
+ *max = snd_pcm_hw_param_value_max(params, var, maxdir);
return 0;
}
int snd_pcm_hw_param_minmax_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var,
- unsigned int min, unsigned int max)
+ snd_pcm_hw_param_t var,
+ unsigned int *min, int *mindir,
+ unsigned int *max, int *maxdir)
{
snd_pcm_hw_params_t save;
int err;
save = *params;
- err = snd_pcm_hw_param_minmax(pcm, params, var, min, max);
+ err = snd_pcm_hw_param_minmax(pcm, params, var,
+ min, mindir,
+ max, maxdir);
if (err < 0)
*params = save;
return err;
}
-int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, int hw,
- unsigned int var, unsigned int val)
+int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, unsigned int val, int dir)
{
int changed;
- 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 {
+ if (hw_is_mask(var)) {
+ mask_t *m = hw_param_mask(params, var);
+ if (val == 0 && dir < 0) {
+ changed = -EINVAL;
+ mask_none(m);
+ } else {
+ if (dir > 0)
+ val++;
+ else if (dir < 0)
+ val--;
+ changed = mask_refine_set(hw_param_mask(params, var), val);
+ }
+ } else if (hw_is_interval(var)) {
+ interval_t *i = hw_param_interval(params, var);
+ if (val == 0 && dir < 0) {
+ changed = -EINVAL;
+ interval_none(i);
+ } else if (dir == 0)
+ changed = interval_refine_set(i, val);
+ else {
+ interval_t t;
+ t.openmin = 1;
+ t.openmax = 1;
+ t.empty = 0;
+ t.integer = 0;
+ if (dir < 0) {
+ t.min = val - 1;
+ t.max = val;
+ } else {
+ t.min = val;
+ t.max = val+1;
+ }
+ changed = interval_refine(i, &t);
+ }
+ } else {
assert(0);
return -EINVAL;
}
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
/* Inside configuration space defined by PARAMS remove from PAR all
- values < VAL and >= VAL +1. Reduce configuration space accordingly.
+ values != VAL. Reduce configuration space accordingly.
Return VAL or -EINVAL if the configuration space is empty
*/
int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var, unsigned int val, int dir)
{
- int changed = _snd_pcm_hw_param_set(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_set(params, var, val, dir);
if (changed < 0)
return changed;
if (changed) {
@@ -482,33 +634,29 @@ int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
if (err < 0)
return err;
}
- return snd_pcm_hw_param_value(params, var);
+ return snd_pcm_hw_param_value(params, var, 0);
}
int snd_pcm_hw_param_set_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var, unsigned int val, int dir)
{
snd_pcm_hw_params_t save;
int err;
save = *params;
- err = snd_pcm_hw_param_set(pcm, params, var, val);
+ err = snd_pcm_hw_param_set(pcm, params, var, val, dir);
if (err < 0)
*params = save;
return err;
}
-int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
- unsigned int var, const mask_t *val)
+int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, const mask_t *val)
{
int changed;
assert(hw_is_mask(var));
changed = mask_refine(hw_param_mask(params, var), val);
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
@@ -520,9 +668,9 @@ int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, int hw,
if the configuration space is empty
*/
int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, const mask_t *val)
+ snd_pcm_hw_param_t var, const mask_t *val)
{
- int changed = _snd_pcm_hw_param_mask(params, 0, var, val);
+ int changed = _snd_pcm_hw_param_mask(params, var, val);
if (changed < 0)
return changed;
if (changed) {
@@ -534,7 +682,7 @@ int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
}
int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- unsigned int var, const mask_t *val)
+ snd_pcm_hw_param_t var, const mask_t *val)
{
snd_pcm_hw_params_t save;
int err;
@@ -552,93 +700,180 @@ int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
Return the value found.
*/
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_param_t var, unsigned int best, int *dir)
{
snd_pcm_hw_params_t save;
int v;
- unsigned int max1 = val, min2 = add(val, 1);
- unsigned int hw_cmask;
+ unsigned int saved_min;
+ int last = 0;
+ unsigned int cmask;
+ int min, max;
+ int mindir, maxdir;
+ int valdir = dir ? *dir : 0;
+ /* FIXME */
+ if (best > INT_MAX)
+ best = INT_MAX;
+ min = max = best;
+ mindir = maxdir = valdir;
+ if (maxdir > 0)
+ maxdir = 0;
+ else if (maxdir == 0)
+ maxdir = -1;
+ else {
+ maxdir = 1;
+ max--;
+ }
save = *params;
- v = snd_pcm_hw_param_max(pcm, params, var, max1);
- if (v >= 0) {
- int v1;
+ saved_min = min;
+ min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
+ if (min >= 0) {
snd_pcm_hw_params_t params1;
- if (val == (unsigned int)v)
+ if (max < 0)
+ goto _end;
+ if ((unsigned int)min = saved_min && mindir == valdir)
goto _end;
params1 = save;
- v1 = snd_pcm_hw_param_min(pcm, &params1, var, min2);
- if (v1 < 0)
+ max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir);
+ if (max < 0)
goto _end;
- if (val - v > v1 - val) {
+ if (approx_nearer(max, maxdir, best, valdir, min, mindir)) {
*params = params1;
- v = v1;
+ last = 1;
}
} else {
*params = save;
- v = snd_pcm_hw_param_min(pcm, params, var, min2);
- assert(v >= 0);
+ max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
+ assert(max >= 0);
+ last = 1;
}
_end:
- hw_cmask = params->hw_cmask;
- v = snd_pcm_hw_param_set(pcm, params, var, v);
- params->hw_cmask |= hw_cmask;
+ cmask = params->cmask;
+ if (last)
+ v = snd_pcm_hw_param_last(pcm, params, var, dir);
+ else
+ v = snd_pcm_hw_param_first(pcm, params, var, dir);
+ params->cmask |= cmask;
assert(v >= 0);
return v;
}
/* Inside configuration space defined by PARAMS set PAR to the available value
- nearest to VAL after OLD (values less than VAL are returned first).
+ nearest to BEST after VAL (on equal difference values less than BEST are
+ returned first).
Reduce configuration space accordingly.
This function cannot be called for SND_PCM_HW_PARAM_ACCESS,
SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT.
Return the value found.
*/
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)
+ snd_pcm_hw_param_t var,
+ unsigned int best, int bestdir,
+ unsigned int val, int *dir)
{
snd_pcm_hw_params_t save;
int v;
- unsigned int max1, min2;
- int diff = old - val;
- if (diff < 0) {
- max1 = sub(old, 1);
- min2 = add(val, -diff);
+ int last = 0;
+ unsigned int cmask;
+ int min, max;
+ int mindir, maxdir;
+ int diff, diffdir;
+ int valdir = dir ? *dir : 0;
+ /* FIXME */
+ if (best > INT_MAX)
+ best = INT_MAX;
+ approx_sub(val, valdir, best, bestdir, &diff, &diffdir);
+ if (diff < 0 || (diff == 0 && diffdir < 0)) {
+ min = best - diff;
+ mindir = bestdir - diffdir;
+ max = val;
+ maxdir = bestdir - 1;
} else {
- max1 = sub(val, diff + 1);
- min2 = add(old, 1);
- }
+ min = val;
+ mindir = bestdir + 1;
+ max = best + diff;
+ maxdir = bestdir + diffdir + 1;
+ }
+ min += mindir / 2;
+ mindir %= 2;
+ max += maxdir / 2;
+ maxdir %= 2;
save = *params;
- v = snd_pcm_hw_param_max(pcm, params, var, max1);
- if (v >= 0) {
- int v1;
+ if (min >= 0 &&
+ (min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir)) >= 0) {
snd_pcm_hw_params_t params1;
- if (val == (unsigned int)v)
+ if (max < 0)
goto _end;
params1 = save;
- v1 = snd_pcm_hw_param_min(pcm, &params1, var, min2);
- if (v1 < 0)
+ max = snd_pcm_hw_param_max(pcm, &params1, var, max, &maxdir);
+ if (max < 0)
goto _end;
- if (val - v > v1 - val) {
+ if (approx_nearer(max, maxdir, best, bestdir, min, mindir)) {
*params = params1;
- v = v1;
+ last = 1;
}
} else {
+ if (max < 0)
+ return -EINVAL;
*params = save;
- v = snd_pcm_hw_param_min(pcm, params, var, min2);
- if (v < 0)
- return v;
+ max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
+ if (max < 0)
+ return max;
+ last = 1;
}
_end:
- v = snd_pcm_hw_param_set(pcm, params, var, v);
+ cmask = params->cmask;
+ if (last)
+ v = snd_pcm_hw_param_last(pcm, params, var, dir);
+ else
+ v = snd_pcm_hw_param_first(pcm, params, var, dir);
+ params->cmask |= cmask;
+ assert(v >= 0);
return v;
}
+void snd_pcm_hw_param_near_minmax(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int min, int *mindir,
+ unsigned int max, int *maxdir)
+{
+ snd_pcm_hw_params_t tmp;
+ int err;
+ if (!approx_lt(min, *mindir, max, *maxdir)) {
+ snd_pcm_hw_param_near(pcm, params, var, min, mindir);
+ return;
+ }
+ tmp = *params;
+ min = snd_pcm_hw_param_near(pcm, &tmp, var, min, mindir);
+ if (approx_lt(min, *mindir, max, *maxdir)) {
+ tmp = *params;
+ max = snd_pcm_hw_param_near(pcm, &tmp, var, max, maxdir);
+ } else {
+ max = min;
+ *maxdir = *mindir;
+ }
+ err = snd_pcm_hw_param_minmax(pcm, params, var, &min, mindir,
+ &max, maxdir);
+ assert(err >= 0);
+}
+
+void snd_pcm_hw_param_near_copy(snd_pcm_t *pcm,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *src)
+{
+ unsigned int min, max;
+ int mindir, maxdir;
+ min = snd_pcm_hw_param_value_min(src, var, &mindir);
+ max = snd_pcm_hw_param_value_max(src, var, &maxdir);
+ snd_pcm_hw_param_near_minmax(pcm, params, var,
+ min, &mindir, max, &maxdir);
+}
/* ---- end of refinement functions ---- */
int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
if (hw_is_mask(var))
return mask_empty(hw_param_mask_c(params, var));
@@ -648,6 +883,35 @@ int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params,
return -EINVAL;
}
+int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *params1)
+{
+ if (hw_is_mask(var))
+ return mask_always_eq(hw_param_mask_c(params, var),
+ hw_param_mask_c(params1, var));
+ if (hw_is_interval(var))
+ return interval_always_eq(hw_param_interval_c(params, var),
+ hw_param_interval_c(params1, var));
+ assert(0);
+ return -EINVAL;
+}
+
+int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *params1)
+{
+ if (hw_is_mask(var))
+ return mask_never_eq(hw_param_mask_c(params, var),
+ hw_param_mask_c(params1, var));
+ if (hw_is_interval(var))
+ return interval_never_eq(hw_param_interval_c(params, var),
+ hw_param_interval_c(params1, var));
+ assert(0);
+ return -EINVAL;
+}
+
+
/* Return rate numerator/denumerator obtainable for configuration space defined
by PARAMS */
int snd_pcm_hw_params_info_rate(const snd_pcm_hw_params_t *params,
@@ -692,43 +956,48 @@ int snd_pcm_hw_params_info_fifo_size(const snd_pcm_hw_params_t *params)
first subformat
min channels
min rate
- min fragment size
- max fragments
+ min period time
+ max buffer size
+ min tick time
*/
void snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
int err;
- unsigned int hw_cmask = params->hw_cmask;
+ unsigned int cmask = params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_ACCESS);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FORMAT);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_RATE);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_FRAGMENT_SIZE);
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- err = snd_pcm_hw_param_last(pcm, params, SND_PCM_HW_PARAM_FRAGMENTS);
+ err = snd_pcm_hw_param_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0);
assert(err >= 0);
- hw_cmask |= params->hw_cmask;
+ cmask |= params->cmask;
- params->hw_cmask = hw_cmask;
+ err = snd_pcm_hw_param_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0);
+ assert(err >= 0);
+ cmask |= params->cmask;
+
+ params->cmask = cmask;
}
/* Strategies */
@@ -740,7 +1009,7 @@ struct _snd_pcm_hw_strategy {
const snd_pcm_hw_strategy_t *strategy);
int (*next_value)(snd_pcm_hw_params_t *params,
unsigned int param,
- int value,
+ int value, int *dir,
snd_pcm_t *pcm,
const snd_pcm_hw_strategy_t *strategy);
int (*min_badness)(const snd_pcm_hw_params_t *params,
@@ -759,7 +1028,7 @@ struct _snd_pcm_hw_strategy_simple {
unsigned int order;
int (*next_value)(snd_pcm_hw_params_t *params,
unsigned int param,
- int value,
+ int value, int *dir,
snd_pcm_t *pcm,
const snd_pcm_hw_strategy_simple_t *par);
unsigned int (*min_badness)(const snd_pcm_hw_params_t *params,
@@ -782,7 +1051,7 @@ typedef struct _snd_pcm_hw_strategy_simple_choices {
} snd_pcm_hw_strategy_simple_choices_t;
int snd_pcm_hw_param_test(const snd_pcm_hw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_hw_param_t var, unsigned int val)
{
if (hw_is_mask(var)) {
const mask_t *mask = hw_param_mask_c(params, var);
@@ -797,7 +1066,7 @@ int snd_pcm_hw_param_test(const snd_pcm_hw_params_t *params,
}
unsigned int snd_pcm_hw_param_count(const snd_pcm_hw_params_t *params,
- unsigned int var)
+ snd_pcm_hw_param_t var)
{
if (hw_is_mask(var)) {
const mask_t *mask = hw_param_mask_c(params, var);
@@ -811,9 +1080,9 @@ unsigned int snd_pcm_hw_param_count(const snd_pcm_hw_params_t *params,
return 0;
}
-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 snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ const snd_pcm_hw_params_t *src)
{
int changed = 0;
if (hw_is_mask(var)) {
@@ -826,16 +1095,12 @@ int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params, int hw,
changed = interval_refine(d, s);
} else
assert(0);
- if (changed) {
- if (hw)
- params->hw_cmask |= 1 << var;
- else
- params->appl_cmask |= 1 << var;
- }
+ if (changed)
+ params->cmask |= 1 << var;
return changed;
}
-void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, unsigned int var,
+void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var,
const snd_pcm_hw_params_t *src)
{
if (hw_is_mask(var)) {
@@ -852,7 +1117,7 @@ void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, unsigned int var,
}
void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params,
- unsigned int var, FILE *fp)
+ snd_pcm_hw_param_t var, FILE *fp)
{
static const char *(*funcs[])(unsigned int k) = {
[SND_PCM_HW_PARAM_ACCESS] = snd_pcm_access_name,
@@ -905,7 +1170,7 @@ int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
{
snd_pcm_hw_params_t best_params;
int var;
- int value;
+ int value, dir;
unsigned int best_badness;
int badness = strategy->min_badness(params, badness_max, pcm, strategy);
snd_pcm_hw_params_t params1;
@@ -923,14 +1188,14 @@ int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
best_badness = UINT_MAX;
value = -1;
while (1) {
- unsigned int hw_cmask;
+ unsigned int cmask;
params1 = *params;
- value = strategy->next_value(&params1, var, value, pcm, strategy);
+ value = strategy->next_value(&params1, var, value, &dir, pcm, strategy);
if (value < 0)
break;
- hw_cmask = params1.hw_cmask;
+ cmask = params1.cmask;
badness = snd_pcm_hw_params_strategy(pcm, &params1, strategy, badness_min, badness_max);
- params1.hw_cmask |= hw_cmask;
+ params1.cmask |= cmask;
if (badness >= 0) {
if ((unsigned int) badness <= badness_min) {
*params = params1;
@@ -963,7 +1228,7 @@ int snd_pcm_hw_strategy_simple_choose_param(const snd_pcm_hw_params_t *params,
snd_pcm_t *pcm ATTRIBUTE_UNUSED,
const snd_pcm_hw_strategy_t *strategy)
{
- unsigned int var;
+ snd_pcm_hw_param_t var;
int best_var = -1;
const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
unsigned int min_choices = UINT_MAX;
@@ -989,14 +1254,14 @@ int snd_pcm_hw_strategy_simple_choose_param(const 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_hw_strategy_t *strategy)
+ snd_pcm_hw_param_t var,
+ int value, int *dir,
+ snd_pcm_t *pcm,
+ const snd_pcm_hw_strategy_t *strategy)
{
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]);
+ return pars[var].next_value(params, var, value, dir, pcm, &pars[var]);
}
@@ -1005,7 +1270,7 @@ int snd_pcm_hw_strategy_simple_min_badness(const snd_pcm_hw_params_t *params,
snd_pcm_t *pcm,
const snd_pcm_hw_strategy_t *strategy)
{
- unsigned int var;
+ snd_pcm_hw_param_t var;
unsigned int badness = 0;
const snd_pcm_hw_strategy_simple_t *pars = strategy->private;
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; ++var) {
@@ -1028,13 +1293,13 @@ void snd_pcm_hw_strategy_simple_near_free(snd_pcm_hw_strategy_simple_t *par)
}
unsigned int snd_pcm_hw_strategy_simple_near_min_badness(const snd_pcm_hw_params_t *params,
- unsigned int var,
+ snd_pcm_hw_param_t var,
snd_pcm_t *pcm,
const snd_pcm_hw_strategy_simple_t *par)
{
const snd_pcm_hw_strategy_simple_near_t *p = par->private;
snd_pcm_hw_params_t params1 = *params;
- int value = snd_pcm_hw_param_near(pcm, &params1, var, p->best);
+ int value = snd_pcm_hw_param_near(pcm, &params1, var, p->best, 0);
int diff;
assert(value >= 0);
diff = p->best - value;
@@ -1044,16 +1309,17 @@ unsigned int snd_pcm_hw_strategy_simple_near_min_badness(const snd_pcm_hw_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_hw_strategy_simple_t *par)
+ snd_pcm_hw_param_t var,
+ int value, int *dir,
+ snd_pcm_t *pcm,
+ const snd_pcm_hw_strategy_simple_t *par)
{
const snd_pcm_hw_strategy_simple_near_t *p = par->private;
- if (value < 0)
- return snd_pcm_hw_param_near(pcm, params, var, p->best);
- else
- return snd_pcm_hw_param_next(pcm, params, var, p->best, value);
+ if (value < 0) {
+ *dir = 0;
+ return snd_pcm_hw_param_near(pcm, params, var, p->best, dir);
+ } else
+ return snd_pcm_hw_param_next(pcm, params, var, p->best, 0, value, dir);
}
void snd_pcm_hw_strategy_simple_choices_free(snd_pcm_hw_strategy_simple_t *par)
@@ -1064,7 +1330,7 @@ void snd_pcm_hw_strategy_simple_choices_free(snd_pcm_hw_strategy_simple_t *par)
}
unsigned int snd_pcm_hw_strategy_simple_choices_min_badness(const snd_pcm_hw_params_t *params,
- unsigned int var,
+ snd_pcm_hw_param_t var,
snd_pcm_t *pcm ATTRIBUTE_UNUSED,
const snd_pcm_hw_strategy_simple_t *par)
{
@@ -1079,10 +1345,10 @@ unsigned int snd_pcm_hw_strategy_simple_choices_min_badness(const snd_pcm_hw_par
}
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_hw_strategy_simple_t *par)
+ snd_pcm_hw_param_t var,
+ int value, int *dir,
+ snd_pcm_t *pcm,
+ const snd_pcm_hw_strategy_simple_t *par)
{
const snd_pcm_hw_strategy_simple_choices_t *p = par->private;
unsigned int k = 0;
@@ -1098,11 +1364,12 @@ int snd_pcm_hw_strategy_simple_choices_next_value(snd_pcm_hw_params_t *params,
unsigned int v = p->choices[k].value;
if (snd_pcm_hw_param_test(params, var, v)) {
snd_pcm_hw_params_t save = *params;
- int err = snd_pcm_hw_param_set(pcm, params, var, v);
+ int err = snd_pcm_hw_param_set(pcm, params, var, v, 0);
if (err < 0) {
*params = save;
continue;
}
+ *dir = 0;
return v;
}
}
@@ -1145,7 +1412,7 @@ int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
int order,
- unsigned int var,
+ snd_pcm_hw_param_t var,
unsigned int best,
unsigned int mul)
{
@@ -1171,7 +1438,7 @@ int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy,
int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy,
int order,
- unsigned int var,
+ snd_pcm_hw_param_t var,
unsigned int count,
snd_pcm_hw_strategy_simple_choices_list_t *choices)
{
@@ -1201,7 +1468,7 @@ int snd_pcm_hw_params_try_explain_failure1(snd_pcm_t *pcm,
unsigned int depth,
FILE *fp)
{
- unsigned int var;
+ snd_pcm_hw_param_t var;
snd_pcm_hw_params_t i;
if (depth < 1)
return -ENOENT;
@@ -1229,7 +1496,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
{
snd_pcm_hw_params_t i, any;
int err;
- unsigned int var;
+ snd_pcm_hw_param_t var;
int done = 0;
assert(pcm && fail);
for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) {
@@ -1268,35 +1535,39 @@ struct _snd_pcm_hw_rule {
int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_mul(hw_param_interval(params, rule->var),
- hw_param_interval(params, rule->deps[0]),
- hw_param_interval(params, rule->deps[1]));
+ interval_t t;
+ interval_mul(hw_param_interval_c(params, rule->deps[0]),
+ hw_param_interval_c(params, rule->deps[1]), &t);
+ return interval_refine(hw_param_interval(params, rule->var), &t);
}
int snd_pcm_hw_rule_div(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_div(hw_param_interval(params, rule->var),
- hw_param_interval(params, rule->deps[0]),
- hw_param_interval(params, rule->deps[1]));
+ interval_t t;
+ interval_div(hw_param_interval_c(params, rule->deps[0]),
+ hw_param_interval_c(params, rule->deps[1]), &t);
+ return interval_refine(hw_param_interval(params, rule->var), &t);
}
int snd_pcm_hw_rule_muldivk(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_muldivk(hw_param_interval(params, rule->var),
- (unsigned long) rule->private,
- hw_param_interval(params, rule->deps[0]),
- hw_param_interval(params, rule->deps[1]));
+ interval_t t;
+ interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
+ hw_param_interval_c(params, rule->deps[1]),
+ (unsigned long) rule->private, &t);
+ return interval_refine(hw_param_interval(params, rule->var), &t);
}
int snd_pcm_hw_rule_mulkdiv(snd_pcm_hw_params_t *params,
snd_pcm_hw_rule_t *rule)
{
- return interval_mulkdiv(hw_param_interval(params, rule->var),
- (unsigned long) rule->private,
- hw_param_interval(params, rule->deps[0]),
- hw_param_interval(params, rule->deps[1]));
+ interval_t t;
+ interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
+ (unsigned long) rule->private,
+ hw_param_interval_c(params, rule->deps[1]), &t);
+ return interval_refine(hw_param_interval(params, rule->var), &t);
}
int snd_pcm_hw_rule_format(snd_pcm_hw_params_t *params,
@@ -1346,12 +1617,12 @@ int snd_pcm_hw_rule_sample_bits(snd_pcm_hw_params_t *params,
if (max < (unsigned)bits)
max = bits;
}
- c = interval_refine_min(i, min);
+ c = interval_refine_min(i, min, 0);
if (c < 0)
return c;
if (c)
changed = 1;
- c = interval_refine_max(i, max);
+ c = interval_refine_max(i, max, 0);
if (c < 0)
return c;
if (c)
@@ -1389,8 +1660,8 @@ static snd_pcm_hw_rule_t refine_rules[] = {
{
var: SND_PCM_HW_PARAM_FRAME_BITS,
func: snd_pcm_hw_rule_mulkdiv,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_BYTES,
- SND_PCM_HW_PARAM_FRAGMENT_SIZE, -1 },
+ deps: { SND_PCM_HW_PARAM_PERIOD_BYTES,
+ SND_PCM_HW_PARAM_PERIOD_SIZE, -1 },
private: (void*) 8,
},
{
@@ -1410,50 +1681,50 @@ static snd_pcm_hw_rule_t refine_rules[] = {
{
var: SND_PCM_HW_PARAM_RATE,
func: snd_pcm_hw_rule_mulkdiv,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
- SND_PCM_HW_PARAM_FRAGMENT_LENGTH, -1 },
+ deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
+ SND_PCM_HW_PARAM_PERIOD_TIME, -1 },
private: (void*) 1000000,
},
{
var: SND_PCM_HW_PARAM_RATE,
func: snd_pcm_hw_rule_mulkdiv,
deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
- SND_PCM_HW_PARAM_BUFFER_LENGTH, -1 },
+ SND_PCM_HW_PARAM_BUFFER_TIME, -1 },
private: (void*) 1000000,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENTS,
+ var: SND_PCM_HW_PARAM_PERIODS,
func: snd_pcm_hw_rule_div,
deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
- SND_PCM_HW_PARAM_FRAGMENT_SIZE, -1 },
+ SND_PCM_HW_PARAM_PERIOD_SIZE, -1 },
private: 0,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ var: SND_PCM_HW_PARAM_PERIOD_SIZE,
func: snd_pcm_hw_rule_div,
deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
- SND_PCM_HW_PARAM_FRAGMENTS, -1 },
+ SND_PCM_HW_PARAM_PERIODS, -1 },
private: 0,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ var: SND_PCM_HW_PARAM_PERIOD_SIZE,
func: snd_pcm_hw_rule_mulkdiv,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_BYTES,
+ deps: { SND_PCM_HW_PARAM_PERIOD_BYTES,
SND_PCM_HW_PARAM_FRAME_BITS, -1 },
private: (void*) 8,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ var: SND_PCM_HW_PARAM_PERIOD_SIZE,
func: snd_pcm_hw_rule_muldivk,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_LENGTH,
+ deps: { SND_PCM_HW_PARAM_PERIOD_TIME,
SND_PCM_HW_PARAM_RATE, -1 },
private: (void*) 1000000,
},
{
var: SND_PCM_HW_PARAM_BUFFER_SIZE,
func: snd_pcm_hw_rule_mul,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
- SND_PCM_HW_PARAM_FRAGMENTS, -1 },
+ deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
+ SND_PCM_HW_PARAM_PERIODS, -1 },
private: 0,
},
{
@@ -1466,14 +1737,14 @@ static snd_pcm_hw_rule_t refine_rules[] = {
{
var: SND_PCM_HW_PARAM_BUFFER_SIZE,
func: snd_pcm_hw_rule_muldivk,
- deps: { SND_PCM_HW_PARAM_BUFFER_LENGTH,
+ deps: { SND_PCM_HW_PARAM_BUFFER_TIME,
SND_PCM_HW_PARAM_RATE, -1 },
private: (void*) 1000000,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENT_BYTES,
+ var: SND_PCM_HW_PARAM_PERIOD_BYTES,
func: snd_pcm_hw_rule_muldivk,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
SND_PCM_HW_PARAM_FRAME_BITS, -1 },
private: (void*) 8,
},
@@ -1485,14 +1756,14 @@ static snd_pcm_hw_rule_t refine_rules[] = {
private: (void*) 8,
},
{
- var: SND_PCM_HW_PARAM_FRAGMENT_LENGTH,
+ var: SND_PCM_HW_PARAM_PERIOD_TIME,
func: snd_pcm_hw_rule_mulkdiv,
- deps: { SND_PCM_HW_PARAM_FRAGMENT_SIZE,
+ deps: { SND_PCM_HW_PARAM_PERIOD_SIZE,
SND_PCM_HW_PARAM_RATE, -1 },
private: (void*) 1000000,
},
{
- var: SND_PCM_HW_PARAM_BUFFER_LENGTH,
+ var: SND_PCM_HW_PARAM_BUFFER_TIME,
func: snd_pcm_hw_rule_mulkdiv,
deps: { SND_PCM_HW_PARAM_BUFFER_SIZE,
SND_PCM_HW_PARAM_RATE, -1 },
@@ -1515,49 +1786,53 @@ static mask_t refine_masks[SND_PCM_HW_PARAM_LAST_MASK - SND_PCM_HW_PARAM_FIRST_M
};
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] = {
+ [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,
+ openmin: 0, openmax: 0, integer: 1, empty: 0,
},
- [SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ [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,
+ openmin: 0, openmax: 0, integer: 1, empty: 0,
},
- [SND_PCM_HW_PARAM_FRAGMENT_LENGTH - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ [SND_PCM_HW_PARAM_CHANNELS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
min: 1, max: UINT_MAX,
- openmin: 0, openmax: 0, real: 0, empty: 0,
+ openmin: 0, openmax: 0, integer: 1, empty: 0,
},
- [SND_PCM_HW_PARAM_FRAGMENT_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ [SND_PCM_HW_PARAM_RATE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
min: 1, max: UINT_MAX,
- openmin: 0, openmax: 0, real: 0, empty: 0,
+ openmin: 0, openmax: 0, integer: 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_PERIOD_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 0, max: UINT_MAX,
+ openmin: 0, openmax: 0, integer: 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_PERIOD_SIZE - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 0, max: UINT_MAX,
+ openmin: 0, openmax: 0, integer: 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_PERIOD_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 0, max: UINT_MAX,
+ openmin: 0, openmax: 0, integer: 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_PERIODS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 0, max: UINT_MAX,
+ openmin: 0, openmax: 0, integer: 0, empty: 0,
},
- [SND_PCM_HW_PARAM_FRAME_BITS - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ [SND_PCM_HW_PARAM_BUFFER_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
min: 1, max: UINT_MAX,
- openmin: 0, openmax: 0, real: 0, empty: 0,
+ openmin: 0, openmax: 0, integer: 0, empty: 0,
},
- [SND_PCM_HW_PARAM_FRAGMENT_BYTES - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ [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,
+ openmin: 0, openmax: 0, integer: 1, 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,
+ openmin: 0, openmax: 0, integer: 1, empty: 0,
+ },
+ [SND_PCM_HW_PARAM_TICK_TIME - SND_PCM_HW_PARAM_FIRST_INTERVAL] = {
+ min: 0, max: UINT_MAX,
+ openmin: 0, openmax: 0, integer: 0, empty: 0,
},
};
@@ -1573,7 +1848,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
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))
+ if (!(params->cmask & (1 << k)))
continue;
err = mask_refine(hw_param_mask(params, k),
&refine_masks[k - SND_PCM_HW_PARAM_FIRST_MASK]);
@@ -1582,7 +1857,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
}
for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++) {
- if (!params->appl_cmask & (1 << k))
+ if (!(params->cmask & (1 << k)))
continue;
err = interval_refine(hw_param_interval(params, k),
&refine_intervals[k - SND_PCM_HW_PARAM_FIRST_INTERVAL]);
@@ -1593,9 +1868,8 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
for (k = 0; k < RULES; k++)
rstamps[k] = 0;
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++)
- vstamps[k] = (params->appl_cmask & (1 << k)) ? 1 : 0;
- params->appl_cmask = 0;
- params->hw_cmask = 0;
+ vstamps[k] = (params->cmask & (1 << k)) ? 1 : 0;
+ params->cmask = 0;
changed = 1;
while (changed) {
changed = 0;
@@ -1626,7 +1900,7 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
#endif
rstamps[k] = stamp;
if (err && r->var >= 0) {
- params->hw_cmask |= 1 << r->var;
+ params->cmask |= 1 << r->var;
vstamps[r->var] = stamp;
changed = 1;
}
@@ -1651,111 +1925,66 @@ int _snd_pcm_hw_refine(snd_pcm_hw_params_t *params)
return 0;
}
-int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
- snd_pcm_hw_params_t *sparams,
- int (*func)(snd_pcm_t *slave,
- snd_pcm_hw_params_t *sparams),
- snd_pcm_t *slave,
- unsigned int links)
-{
- unsigned int k;
- int err, error = 0;
- unsigned int client_from_slave = ~0U;
- unsigned int client_refine = ~0U;
- unsigned int slave_from_client = ~0U;
- unsigned int slave_refine = ~0U;
- unsigned int hw_cmask = params->hw_cmask;
-
- while (client_from_slave || client_refine) {
- for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
- int changed;
- if (!(links & (1 << k)))
- continue;
- if (!(client_from_slave & (1 << k)))
- continue;
- changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
- if (changed) {
- hw_cmask |= 1 << k;
- slave_from_client |= 1 << k;
- client_refine |= 1 << k;
- }
- if (changed < 0)
- error = changed;
- }
- client_from_slave = 0;
- if (error)
- break;
- if (client_refine) {
- params->appl_cmask = client_refine;
- client_refine = 0;
- err = _snd_pcm_hw_refine(params);
- hw_cmask |= params->hw_cmask;
- slave_from_client |= params->hw_cmask;
- if (err < 0) {
- error = err;
- break;
- }
- }
-
- for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
- int changed;
- if (!(links & (1 << k)))
- continue;
- if (!(slave_from_client & (1 << k)))
- continue;
- changed = _snd_pcm_hw_param_refine(sparams, 1, k, params);
- if (changed) {
- slave_refine |= 1 << k;
- client_from_slave |= 1 << k;
- }
- if (changed < 0)
- error = changed;
- }
- slave_from_client = 0;
- if (error)
- continue;
- if (slave_refine) {
- sparams->appl_cmask = slave_refine;
- slave_refine = 0;
- error = func(slave, sparams);
- client_from_slave |= sparams->hw_cmask;
- }
- }
- params->appl_cmask = 0;
- params->hw_cmask = hw_cmask;
- return error;
-}
-
-int snd_pcm_hw_params2(snd_pcm_hw_params_t *params,
- snd_pcm_hw_params_t *sparams,
- int (*func)(snd_pcm_t *slave,
- snd_pcm_hw_params_t *sparams),
- snd_pcm_t *slave,
- unsigned int links)
+int snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
+ unsigned int vars,
+ const snd_pcm_hw_params_t *src)
{
+ int changed, err = 0;
unsigned int k;
- int err;
for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
- int changed;
- if (!(links & (1 << k)))
+ if (!(vars & (1 << k)) ||
+ !((src->cmask & (1 << k))))
continue;
- changed = _snd_pcm_hw_param_refine(sparams, 0, k, params);
+ changed = snd_pcm_hw_param_refine(params, k, src);
if (changed < 0)
- return changed;
+ err = changed;
}
- sparams->appl_cmask = ~0U;
- err = func(slave, sparams);
- if (err >= 0)
- return err;
+ return err;
+}
- for (k = 0; k <= SND_PCM_HW_PARAM_LAST; ++k) {
- int changed;
- if (!(links & (1 << k)))
- continue;
- if (!(sparams->hw_cmask & (1 << k)))
- continue;
- changed = _snd_pcm_hw_param_refine(params, 1, k, sparams);
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+int snd_pcm_generic_hw_link(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long links)
+{
+ int err1, err = 0;
+ err = snd_pcm_hw_params_refine(sparams, links, params);
+ if (err >= 0) {
+ unsigned int cmask = sparams->cmask;
+ err = snd_pcm_hw_refine(slave, sparams);
+ sparams->cmask |= cmask;
+ }
+ err1 = snd_pcm_hw_params_refine(params, links, sparams);
+ if (err1 < 0)
+ err = err1;
+ sparams->cmask = 0;
+ return err;
+}
+
+int snd_pcm_hw_refine2(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ int (*func)(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long private),
+ snd_pcm_t *slave,
+ unsigned long private)
+{
+ int err = 0;
+ unsigned int cmask = 0;
+ while (params->cmask) {
+ err = func(params, sparams, slave, private);
+ cmask |= params->cmask;
+ if (err < 0)
+ break;
+ err = _snd_pcm_hw_refine(params);
+ cmask |= params->cmask;
+ if (err < 0)
+ break;
}
+ params->cmask = cmask;
return err;
}
@@ -1764,10 +1993,10 @@ 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->period_step = pcm->period_step;
+ params->sleep_min = pcm->sleep_min;
params->avail_min = pcm->avail_min;
params->xfer_align = pcm->xfer_align;
params->silence_threshold = pcm->silence_threshold;
@@ -1781,31 +2010,31 @@ 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->xrun_mode = SND_PCM_XRUN_STOP;
params->tstamp_mode = SND_PCM_TSTAMP_NONE;
- params->avail_min = pcm->fragment_size;
- params->xfer_align = pcm->fragment_size;
+ params->period_step = 1;
+ params->sleep_min = 0;
+ params->avail_min = pcm->period_size;
+ params->xfer_align = pcm->period_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)
+int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t 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_PERIOD_STEP:
+ return params->period_step;
+ case SND_PCM_SW_PARAM_SLEEP_MIN:
+ return params->sleep_min;
case SND_PCM_SW_PARAM_AVAIL_MIN:
return params->avail_min;
case SND_PCM_SW_PARAM_XFER_ALIGN:
@@ -1821,29 +2050,27 @@ int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var)
}
int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_sw_param_t 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_PERIOD_STEP:
+ params->period_step = val;
+ break;
+ case SND_PCM_SW_PARAM_SLEEP_MIN:
+ params->sleep_min = val;
+ break;
case SND_PCM_SW_PARAM_AVAIL_MIN:
assert(val > 0);
params->avail_min = val;
@@ -1868,25 +2095,17 @@ int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
}
int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
- unsigned int var, unsigned int val)
+ snd_pcm_sw_param_t 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;
@@ -1896,9 +2115,15 @@ int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
val = pcm->min_align;
params->avail_min = val;
break;
+ case SND_PCM_SW_PARAM_PERIOD_STEP:
+ params->period_step = val;
+ break;
+ case SND_PCM_SW_PARAM_SLEEP_MIN:
+ params->sleep_min = val;
+ break;
case SND_PCM_SW_PARAM_XFER_ALIGN:
{
- size_t r = val % pcm->min_align;
+ snd_pcm_uframes_t r = val % pcm->min_align;
if (r >= (pcm->min_align + 1) / 2)
val += pcm->min_align - r;
else
@@ -1926,24 +2151,24 @@ int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
}
void snd_pcm_sw_param_dump(const snd_pcm_sw_params_t *params,
- unsigned int var, FILE *fp)
+ snd_pcm_sw_param_t 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_PERIOD_STEP:
+ fprintf(fp, "%d", params->period_step);
+ break;
+ case SND_PCM_SW_PARAM_SLEEP_MIN:
+ fprintf(fp, "%d", params->sleep_min);
+ break;
case SND_PCM_SW_PARAM_AVAIL_MIN:
fprintf(fp, "%ld", (long) params->avail_min);
break;
@@ -1975,12 +2200,8 @@ int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp)
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;
+ return pcm->ops->hw_refine(pcm->op_arg, params);
}
/* Install one of the configurations present in configuration
@@ -1991,8 +2212,8 @@ int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
first subformat
min channels
min rate
- min fragment_size
- max fragments
+ min period_size
+ max periods
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)
@@ -2014,13 +2235,15 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
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->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0);
+ pcm->format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
+ pcm->subformat = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_SUBFORMAT, 0);
+ pcm->channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0);
+ pcm->rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
+ pcm->period_time = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_PERIOD_TIME, 0);
+ pcm->period_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0);
+ pcm->buffer_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0);
+ pcm->tick_time = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_TICK_TIME, 0);
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;
@@ -2030,7 +2253,6 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
min_align *= 2;
}
pcm->min_align = min_align;
- pcm->buffer_size = pcm->fragment_size * pcm->fragments;
pcm->info = params->info;
pcm->msbits = params->msbits;
@@ -2066,10 +2288,10 @@ int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *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->period_step = params->period_step;
+ pcm->sleep_min = params->sleep_min;
pcm->avail_min = params->avail_min;
pcm->xfer_align = params->xfer_align;
pcm->silence_threshold = params->silence_threshold;
diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c
index 5255493d..9f7ba854 100644
--- a/src/pcm/pcm_plug.c
+++ b/src/pcm/pcm_plug.c
@@ -21,7 +21,7 @@
#include "pcm_local.h"
#include "pcm_plugin.h"
-
+#include "interval.h"
typedef struct {
snd_pcm_t *req_slave;
@@ -191,82 +191,37 @@ static int snd_pcm_plug_slave_format(int format, const mask_t *format_mask)
(1 << SND_PCM_FORMAT_A_LAW) | \
(1 << SND_PCM_FORMAT_IMA_ADPCM))
-static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
- snd_pcm_hw_params_t *sparams)
+
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+static int snd_pcm_plug_hw_link(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long private ATTRIBUTE_UNUSED)
{
- snd_pcm_plug_t *plug = pcm->private;
- snd_pcm_t *slave = plug->req_slave;
- int err;
+ int rate_always, channels_always, format_always, access_always;
+ int rate_never, channels_never, format_never, access_never;
+ unsigned int links = (SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
const mask_t *format_mask, *sformat_mask;
- unsigned int rate_min, rate_max, srate_min, srate_max;
- unsigned int channels_min, channels_max, schannels_min, schannels_max;
+ mask_t *fmt_mask = alloca(mask_sizeof());
+ mask_t *sfmt_mask = alloca(mask_sizeof());
+ mask_t *access_mask = alloca(mask_sizeof());
+ int err;
unsigned int format;
- int same_rate, same_channels, same_format;
- snd_pcm_hw_params_t tmp;
- unsigned int links = (SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
- mask_t *tmp_mask = alloca(mask_sizeof());
- mask_t *accplug_mask = alloca(mask_sizeof());
- mask_t *mmap_mask = alloca(mask_sizeof());
- mask_t *fmtplug_mask = alloca(mask_sizeof());
- mask_load(accplug_mask, SND_PCM_ACCBIT_PLUGIN);
- mask_load(mmap_mask, SND_PCM_ACCBIT_MMAP);
- mask_load(fmtplug_mask, SND_PCM_FMTBIT_PLUG);
-
- err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
- if (err < 0)
- return err;
- err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_RATE, RATE_MIN);
- if (err < 0)
- return err;
- 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);
- err = snd_pcm_hw_refine2(params, sparams,
- snd_pcm_hw_refine, slave, links);
- if (err < 0)
- return err;
-
- 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_param_near(slave, &tmp,
- SND_PCM_HW_PARAM_RATE, rate_min);
- if (srate_min < rate_max) {
- tmp = *sparams;
- 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_param_minmax(slave, sparams,
- SND_PCM_HW_PARAM_RATE,
- srate_min, srate_max);
- assert(err >= 0);
-
- 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_param_near(slave, &tmp,
- SND_PCM_HW_PARAM_CHANNELS, channels_min);
- if (schannels_min < channels_max) {
- tmp = *sparams;
- 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_param_minmax(slave, sparams,
- SND_PCM_HW_PARAM_CHANNELS,
- schannels_min, schannels_max);
- assert(err >= 0);
-
+ unsigned int scmask = sparams->cmask;
+ snd_pcm_hw_param_near_copy(slave, sparams, SND_PCM_HW_PARAM_RATE,
+ params);
+ scmask |= sparams->cmask;
+ snd_pcm_hw_param_near_copy(slave, sparams, SND_PCM_HW_PARAM_CHANNELS,
+ params);
+ scmask |= sparams->cmask;
format_mask = snd_pcm_hw_param_value_mask(params,
SND_PCM_HW_PARAM_FORMAT);
sformat_mask = snd_pcm_hw_param_value_mask(sparams,
SND_PCM_HW_PARAM_FORMAT);
- mask_none(tmp_mask);
+ mask_none(sfmt_mask);
+ mask_none(fmt_mask);
for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
int f;
if (!mask_test(format_mask, format))
@@ -275,80 +230,134 @@ static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
f = format;
else {
f = snd_pcm_plug_slave_format(format, sformat_mask);
- if (f < 0) {
- mask_t *m = alloca(mask_sizeof());
- mask_all(m);
- mask_reset(m, format);
- err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT, m);
- if (err < 0)
- return err;
+ if (f < 0)
continue;
- }
}
- mask_set(tmp_mask, f);
+ mask_set(sfmt_mask, f);
+ mask_set(fmt_mask, format);
}
- err = _snd_pcm_hw_param_mask(sparams, 0,
- SND_PCM_HW_PARAM_FORMAT, tmp_mask);
+ err = _snd_pcm_hw_param_mask(params,
+ SND_PCM_HW_PARAM_FORMAT, fmt_mask);
+ if (err < 0)
+ return err;
+ err = _snd_pcm_hw_param_mask(sparams,
+ SND_PCM_HW_PARAM_FORMAT, sfmt_mask);
assert(err >= 0);
- sformat_mask = snd_pcm_hw_param_value_mask(sparams,
- SND_PCM_HW_PARAM_FORMAT);
- same_rate = (rate_min == rate_max &&
- rate_min == srate_min &&
- rate_min == srate_max);
- if (same_rate)
+ format_always = snd_pcm_hw_param_always_eq(params,
+ SND_PCM_HW_PARAM_FORMAT,
+ sparams);
+ format_never = (!format_always &&
+ snd_pcm_hw_param_never_eq(params,
+ SND_PCM_HW_PARAM_FORMAT,
+ sparams));
+
+ channels_always = snd_pcm_hw_param_always_eq(params,
+ SND_PCM_HW_PARAM_CHANNELS,
+ sparams);
+ channels_never = (!channels_always &&
+ snd_pcm_hw_param_never_eq(params,
+ SND_PCM_HW_PARAM_CHANNELS,
+ sparams));
+
+ rate_always = snd_pcm_hw_param_always_eq(params,
+ SND_PCM_HW_PARAM_RATE,
+ sparams);
+ rate_never = (!rate_always &&
+ snd_pcm_hw_param_never_eq(params,
+ SND_PCM_HW_PARAM_RATE,
+ sparams));
+ access_always = snd_pcm_hw_param_always_eq(params,
+ SND_PCM_HW_PARAM_ACCESS,
+ sparams);
+ access_never = (!access_always &&
+ snd_pcm_hw_param_never_eq(params,
+ SND_PCM_HW_PARAM_ACCESS,
+ sparams));
+
+ if (rate_always)
links |= (SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
SND_PCM_HW_PARBIT_BUFFER_SIZE);
- same_channels = (channels_min == channels_max &&
- channels_min == schannels_min &&
- channels_min == schannels_max);
- if (same_channels)
+ else {
+ interval_t t;
+ const interval_t *sbuffer_size, *buffer_size;
+ const interval_t *srate, *rate;
+ buffer_size = snd_pcm_hw_param_value_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE);
+ sbuffer_size = snd_pcm_hw_param_value_interval(sparams, SND_PCM_HW_PARAM_BUFFER_SIZE);
+ rate = snd_pcm_hw_param_value_interval(params, SND_PCM_HW_PARAM_RATE);
+ srate = snd_pcm_hw_param_value_interval(sparams, SND_PCM_HW_PARAM_RATE);
+ interval_muldiv(sbuffer_size, rate, srate, &t);
+ interval_round(&t);
+ err = _snd_pcm_hw_param_refine_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &t);
+ if (err < 0)
+ return err;
+ interval_muldiv(buffer_size, srate, rate, &t);
+ interval_round(&t);
+ err = _snd_pcm_hw_param_refine_interval(sparams, SND_PCM_HW_PARAM_BUFFER_SIZE, &t);
+ assert(err >= 0);
+ scmask |= sparams->cmask;
+ }
+ if (channels_always)
links |= SND_PCM_HW_PARBIT_CHANNELS;
- same_format = (mask_single(format_mask) &&
- mask_eq(format_mask, sformat_mask));
- if (same_format) {
+ if (format_always) {
links |= (SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_SAMPLE_BITS);
- if (same_channels) {
+ if (channels_always) {
links |= SND_PCM_HW_PARBIT_FRAME_BITS;
- if (same_rate)
- links |= (SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+ if (rate_always)
+ links |= (SND_PCM_HW_PARBIT_PERIOD_BYTES |
SND_PCM_HW_PARBIT_BUFFER_BYTES);
}
}
- if (same_rate && same_channels && same_format) {
- 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_param_mask(sparams, 0,
- SND_PCM_HW_PARAM_ACCESS,
- access_mask);
- else
- _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
- mmap_mask);
- } else {
- err = _snd_pcm_hw_param_mask(params, 1,
- SND_PCM_HW_PARAM_ACCESS,
- accplug_mask);
- if (err < 0)
- return err;
- err = _snd_pcm_hw_param_mask(params, 1,
- SND_PCM_HW_PARAM_FORMAT,
- fmtplug_mask);
- if (err < 0)
- return err;
- _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_ACCESS,
- mmap_mask);
- _snd_pcm_hw_param_mask(sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- fmtplug_mask);
- }
+ mask_load(access_mask, SND_PCM_ACCBIT_PLUGIN);
+ if (format_never || channels_never || rate_never) {
+ mask_t *mmap_mask = alloca(mask_sizeof());
+ mask_load(mmap_mask, SND_PCM_ACCBIT_MMAP);
+ _snd_pcm_hw_param_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
+ mmap_mask);
+ } else
+ mask_union(access_mask, snd_pcm_hw_param_value_mask(sparams, SND_PCM_HW_PARAM_ACCESS));
+ _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
+ access_mask);
+ sparams->cmask |= scmask;
+ return snd_pcm_generic_hw_link(params, sparams, slave, links);
+}
+
+static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams)
+{
+ snd_pcm_plug_t *plug = pcm->private;
+ snd_pcm_t *slave = plug->req_slave;
+ unsigned int cmask, lcmask;
+ int err;
+
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_CHANNELS, 1, 0);
+ if (err < 0)
+ return err;
+ err = _snd_pcm_hw_param_max(params, SND_PCM_HW_PARAM_CHANNELS, 1024, 0);
+ if (err < 0)
+ return err;
+ err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_RATE, RATE_MIN, 0);
+ if (err < 0)
+ return err;
+ err = _snd_pcm_hw_param_max(params, SND_PCM_HW_PARAM_RATE, RATE_MAX, 0);
+ if (err < 0)
+ return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
+
+ _snd_pcm_hw_params_any(sparams);
err = snd_pcm_hw_refine2(params, sparams,
- snd_pcm_hw_refine, slave, links);
+ snd_pcm_plug_hw_link, slave, 0);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -360,7 +369,19 @@ static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
static int snd_pcm_plug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_hw_params_t sparams;
- return snd_pcm_plug_hw_refine1(pcm, params, &sparams);
+ int err;
+#if 0
+ fprintf(stderr, "Enter: client =\n");
+ snd_pcm_hw_params_dump(params, stderr);
+#endif
+ err = snd_pcm_plug_hw_refine1(pcm, params, &sparams);
+#if 0
+ fprintf(stderr, "Exit: client =\n");
+ snd_pcm_hw_params_dump(params, stderr);
+ fprintf(stderr, "Exit: slave =\n");
+ snd_pcm_hw_params_dump(&sparams, stderr);
+#endif
+ return err;
}
static void snd_pcm_plug_clear(snd_pcm_t *pcm)
@@ -584,15 +605,15 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
int err = snd_pcm_plug_hw_refine1(pcm, params, &sparams);
assert(err >= 0);
- 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);
+ clt_params.access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0);
+ clt_params.format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
+ clt_params.channels = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0);
+ clt_params.rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
- 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);
+ slv_params.access = snd_pcm_hw_param_first(slave, &sparams, SND_PCM_HW_PARAM_ACCESS, 0);
+ slv_params.format = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_FORMAT, 0);
+ slv_params.channels = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_CHANNELS, 0);
+ slv_params.rate = snd_pcm_hw_param_value(&sparams, SND_PCM_HW_PARAM_RATE, 0);
snd_pcm_plug_clear(pcm);
err = snd_pcm_plug_insert_plugins(pcm, &clt_params, &slv_params);
@@ -612,7 +633,7 @@ static int snd_pcm_plug_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
{
snd_pcm_plug_t *plug = pcm->private;
snd_pcm_t *slave = plug->req_slave;
- size_t avail_min, xfer_align, silence_threshold, silence_size;
+ snd_pcm_uframes_t avail_min, xfer_align, silence_threshold, silence_size;
int err;
avail_min = params->avail_min;
xfer_align = params->xfer_align;
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
index 8fa3ccad..f98d08f7 100644
--- a/src/pcm/pcm_plugin.c
+++ b/src/pcm/pcm_plugin.c
@@ -88,10 +88,10 @@ int snd_pcm_plugin_state(snd_pcm_t *pcm)
return snd_pcm_state(plugin->slave);
}
-int snd_pcm_plugin_delay(snd_pcm_t *pcm, ssize_t *delayp)
+int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_plugin_t *plugin = pcm->private;
- ssize_t sd;
+ snd_pcm_sframes_t sd;
int err = snd_pcm_delay(plugin->slave, &sd);
if (err < 0)
return err;
@@ -157,18 +157,18 @@ int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable)
return snd_pcm_pause(plugin->slave, enable);
}
-ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames)
+snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_t *plugin = pcm->private;
- ssize_t n = snd_pcm_mmap_hw_avail(pcm);
+ snd_pcm_sframes_t n = snd_pcm_mmap_hw_avail(pcm);
assert(n >= 0);
if (n > 0) {
- if ((size_t)n > frames)
+ if ((snd_pcm_uframes_t)n > frames)
n = frames;
frames -= n;
}
if (frames > 0) {
- ssize_t err;
+ snd_pcm_sframes_t err;
/* FIXME: rate plugin */
if (plugin->slave_frames)
frames = plugin->slave_frames(pcm, frames);
@@ -188,11 +188,11 @@ ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames)
return n;
}
-ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t frames;
+ snd_pcm_sframes_t frames;
snd_pcm_areas_from_buf(pcm, areas, (void*)buffer);
frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
if (frames > 0)
@@ -200,11 +200,11 @@ ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
return frames;
}
-ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t frames;
+ snd_pcm_sframes_t frames;
snd_pcm_areas_from_bufs(pcm, areas, bufs);
frames = snd_pcm_write_areas(pcm, areas, 0, size, plugin->write);
if (frames > 0)
@@ -212,11 +212,11 @@ ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size)
return frames;
}
-ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t frames;
+ snd_pcm_sframes_t frames;
snd_pcm_areas_from_buf(pcm, areas, buffer);
frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
if (frames > 0)
@@ -224,11 +224,11 @@ ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size)
return frames;
}
-ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size)
+snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_channel_area_t areas[pcm->channels];
- ssize_t frames;
+ snd_pcm_sframes_t frames;
snd_pcm_areas_from_bufs(pcm, areas, bufs);
frames = snd_pcm_read_areas(pcm, areas, 0, size, plugin->read);
if (frames > 0)
@@ -236,14 +236,14 @@ ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size)
return frames;
}
-ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
+snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t client_size)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_t *slave = plugin->slave;
- size_t client_xfer = 0;
- size_t slave_xfer = 0;
- ssize_t err = 0;
- ssize_t slave_size;
+ snd_pcm_uframes_t client_xfer = 0;
+ snd_pcm_uframes_t slave_xfer = 0;
+ snd_pcm_sframes_t err = 0;
+ snd_pcm_sframes_t slave_size;
if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
snd_pcm_mmap_appl_forward(pcm, client_size);
// snd_pcm_plugin_avail_update(pcm);
@@ -253,11 +253,11 @@ ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
if (slave_size <= 0)
return slave_size;
while (client_xfer < client_size &&
- slave_xfer < (size_t)slave_size) {
- size_t slave_frames = slave_size - slave_xfer;
- size_t client_frames = client_size - client_xfer;
- size_t offset = snd_pcm_mmap_hw_offset(pcm);
- size_t cont = pcm->buffer_size - offset;
+ slave_xfer < (snd_pcm_uframes_t)slave_size) {
+ snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
+ snd_pcm_uframes_t client_frames = client_size - client_xfer;
+ snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+ snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < client_frames)
client_frames = cont;
err = plugin->write(pcm, pcm->running_areas, offset,
@@ -273,15 +273,15 @@ ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t client_size)
return err;
}
-ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
+snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
{
snd_pcm_plugin_t *plugin = pcm->private;
snd_pcm_t *slave = plugin->slave;
- size_t client_xfer;
- size_t slave_xfer = 0;
- ssize_t err = 0;
- size_t client_size;
- ssize_t slave_size = snd_pcm_avail_update(slave);
+ snd_pcm_uframes_t client_xfer;
+ snd_pcm_uframes_t slave_xfer = 0;
+ snd_pcm_sframes_t err = 0;
+ snd_pcm_uframes_t client_size;
+ snd_pcm_sframes_t slave_size = snd_pcm_avail_update(slave);
if (slave_size <= 0)
return slave_size;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK ||
@@ -291,12 +291,12 @@ ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
plugin->client_frames(pcm, slave_size) : slave_size;
client_xfer = snd_pcm_mmap_capture_avail(pcm);
client_size = pcm->buffer_size;
- while (slave_xfer < (size_t)slave_size &&
+ while (slave_xfer < (snd_pcm_uframes_t)slave_size &&
client_xfer < client_size) {
- size_t slave_frames = slave_size - slave_xfer;
- size_t client_frames = client_size - client_xfer;
- size_t offset = snd_pcm_mmap_hw_offset(pcm);
- size_t cont = pcm->buffer_size - offset;
+ snd_pcm_uframes_t slave_frames = slave_size - slave_xfer;
+ snd_pcm_uframes_t client_frames = client_size - client_xfer;
+ snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
+ snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < client_frames)
client_frames = cont;
err = plugin->read(pcm, pcm->running_areas, offset,
diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h
index 06d14cc0..ef723353 100644
--- a/src/pcm/pcm_plugin.h
+++ b/src/pcm/pcm_plugin.h
@@ -24,11 +24,11 @@ typedef struct {
int close_slave;
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);
+ snd_pcm_sframes_t (*client_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
+ snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
int (*init)(snd_pcm_t *pcm);
int shmid;
- size_t appl_ptr, hw_ptr;
+ snd_pcm_uframes_t appl_ptr, hw_ptr;
} snd_pcm_plugin_t;
int snd_pcm_plugin_close(snd_pcm_t *pcm);
@@ -41,19 +41,19 @@ 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);
int snd_pcm_plugin_state(snd_pcm_t *pcm);
-int snd_pcm_plugin_delay(snd_pcm_t *pcm, ssize_t *delayp);
+int snd_pcm_plugin_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
int snd_pcm_plugin_prepare(snd_pcm_t *pcm);
int snd_pcm_plugin_start(snd_pcm_t *pcm);
int snd_pcm_plugin_drop(snd_pcm_t *pcm);
int snd_pcm_plugin_drain(snd_pcm_t *pcm);
int snd_pcm_plugin_pause(snd_pcm_t *pcm, int enable);
-ssize_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, size_t frames);
-ssize_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
-ssize_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, size_t size);
-ssize_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, size_t size);
-ssize_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, size_t size);
-ssize_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_plugin_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm);
int snd_pcm_plugin_mmap_status(snd_pcm_t *pcm);
int snd_pcm_plugin_mmap_control(snd_pcm_t *pcm);
int snd_pcm_plugin_mmap(snd_pcm_t *pcm);
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
index 9f616ea1..351d853f 100644
--- a/src/pcm/pcm_rate.c
+++ b/src/pcm/pcm_rate.c
@@ -32,11 +32,11 @@ typedef struct {
unsigned int pos;
} rate_state_t;
-typedef size_t (*rate_f)(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset, size_t src_frames,
+typedef snd_pcm_uframes_t (*rate_f)(const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset, size_t *dst_framesp,
- size_t channels,
+ snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+ unsigned int channels,
int getidx, int putidx,
unsigned int arg,
rate_state_t *states);
@@ -53,11 +53,11 @@ typedef struct {
rate_state_t *states;
} snd_pcm_rate_t;
-static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset, size_t src_frames,
+static snd_pcm_uframes_t resample_expand(const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset, size_t *dst_framesp,
- size_t channels,
+ snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+ unsigned int channels,
int getidx, int putidx,
unsigned int get_threshold,
rate_state_t *states)
@@ -70,9 +70,9 @@ static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
void *get = get16_labels[getidx];
void *put = put16_labels[putidx];
unsigned int channel;
- size_t src_frames1 = 0;
- size_t dst_frames1 = 0;
- size_t dst_frames = *dst_framesp;
+ snd_pcm_uframes_t src_frames1 = 0;
+ snd_pcm_uframes_t dst_frames1 = 0;
+ snd_pcm_uframes_t dst_frames = *dst_framesp;
int16_t sample = 0;
if (src_frames == 0 ||
@@ -135,11 +135,11 @@ static size_t resample_expand(const snd_pcm_channel_area_t *src_areas,
return src_frames1;
}
-static size_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset, size_t src_frames,
+static snd_pcm_uframes_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
+ snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset, size_t *dst_framesp,
- size_t channels,
+ snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
+ unsigned int channels,
int getidx, int putidx,
unsigned int get_increment,
rate_state_t *states)
@@ -152,9 +152,9 @@ static size_t resample_shrink(const snd_pcm_channel_area_t *src_areas,
void *get = get16_labels[getidx];
void *put = put16_labels[putidx];
unsigned int channel;
- size_t src_frames1 = 0;
- size_t dst_frames1 = 0;
- size_t dst_frames = *dst_framesp;
+ snd_pcm_uframes_t src_frames1 = 0;
+ snd_pcm_uframes_t dst_frames1 = 0;
+ snd_pcm_uframes_t dst_frames = *dst_framesp;
int16_t sample = 0;
if (src_frames == 0 ||
@@ -238,52 +238,60 @@ static int snd_pcm_rate_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_rate_t *rate = pcm->private;
snd_pcm_t *slave = rate->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
mask_t *access_mask = alloca(mask_sizeof());
mask_t *format_mask = alloca(mask_sizeof());
mask_t *saccess_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_min(params, 1,
- SND_PCM_HW_PARAM_RATE, RATE_MIN);
+ err = _snd_pcm_hw_param_min(params,
+ SND_PCM_HW_PARAM_RATE, RATE_MIN, 0);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_max(params, 1,
- SND_PCM_HW_PARAM_RATE, RATE_MAX);
+ err = _snd_pcm_hw_param_max(params,
+ SND_PCM_HW_PARAM_RATE, RATE_MAX, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
+ snd_pcm_hw_param_near_copy(slave, &sparams,
+ SND_PCM_HW_PARAM_BUFFER_TIME,
+ params);
if (rate->sformat >= 0) {
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- rate->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ rate->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
} 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_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
- rate->srate);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_RATE,
+ rate->srate, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave, links);
+ snd_pcm_generic_hw_link, slave, links);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -297,45 +305,55 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
int err;
snd_pcm_hw_params_t sparams;
unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
unsigned int src_format, dst_format;
unsigned int src_rate, dst_rate;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (rate->sformat >= 0) {
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- rate->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ rate->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
} 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_param_set(&sparams, 0, SND_PCM_HW_PARAM_RATE,
- rate->srate);
+
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_RATE,
+ rate->srate, 0);
+
+ snd_pcm_hw_param_near_copy(slave, &sparams,
+ SND_PCM_HW_PARAM_BUFFER_TIME,
+ params);
- err = snd_pcm_hw_params2(params, &sparams,
- snd_pcm_hw_params, slave, links);
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 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_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
dst_format = slave->format;
- src_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+ src_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
dst_rate = slave->rate;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
src_rate = slave->rate;
- dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE);
+ dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0);
}
rate->get_idx = get_index(src_format, SND_PCM_FORMAT_S16);
rate->put_idx = put_index(SND_PCM_FORMAT_S16, dst_format);
@@ -349,7 +367,7 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
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_param_value(params, SND_PCM_HW_PARAM_CHANNELS) * sizeof(*rate->states));
+ rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*rate->states));
return 0;
}
@@ -357,7 +375,7 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
{
snd_pcm_rate_t *rate = pcm->private;
snd_pcm_t *slave = rate->plug.slave;
- size_t avail_min, xfer_align, silence_threshold, silence_size;
+ snd_pcm_uframes_t avail_min, xfer_align, silence_threshold, silence_size;
int err;
avail_min = params->avail_min;
xfer_align = params->xfer_align;
@@ -393,18 +411,18 @@ static int snd_pcm_rate_init(snd_pcm_t *pcm)
return 0;
}
-static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t client_offset,
- size_t client_size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t client_offset,
+ snd_pcm_uframes_t client_size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_rate_t *rate = pcm->private;
snd_pcm_t *slave = rate->plug.slave;
- size_t client_xfer = 0;
- size_t slave_xfer = 0;
- ssize_t err = 0;
- size_t slave_size;
+ snd_pcm_uframes_t client_xfer = 0;
+ snd_pcm_uframes_t slave_xfer = 0;
+ snd_pcm_sframes_t err = 0;
+ snd_pcm_uframes_t slave_size;
if (slave_sizep)
slave_size = *slave_sizep;
else
@@ -412,7 +430,7 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
assert(client_size > 0 && slave_size > 0);
while (client_xfer < client_size &&
slave_xfer < slave_size) {
- size_t src_frames, dst_frames;
+ snd_pcm_uframes_t src_frames, dst_frames;
src_frames = client_size - client_xfer;
dst_frames = snd_pcm_mmap_playback_xfer(slave, slave_size - slave_xfer);
src_frames = rate->func(areas, client_offset, src_frames,
@@ -426,7 +444,7 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, dst_frames);
if (err < 0)
break;
- assert((size_t)err == dst_frames);
+ assert((snd_pcm_uframes_t)err == dst_frames);
slave_xfer += dst_frames;
}
@@ -444,19 +462,19 @@ static ssize_t snd_pcm_rate_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t client_offset,
- size_t client_size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t client_offset,
+ snd_pcm_uframes_t client_size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_rate_t *rate = pcm->private;
snd_pcm_t *slave = rate->plug.slave;
- size_t client_xfer = 0;
- size_t slave_xfer = 0;
- ssize_t err = 0;
- size_t slave_size;
+ snd_pcm_uframes_t client_xfer = 0;
+ snd_pcm_uframes_t slave_xfer = 0;
+ snd_pcm_sframes_t err = 0;
+ snd_pcm_uframes_t slave_size;
if (slave_sizep)
slave_size = *slave_sizep;
else
@@ -464,7 +482,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
assert(client_size > 0 && slave_size > 0);
while (client_xfer < client_size &&
slave_xfer < slave_size) {
- size_t src_frames, dst_frames;
+ snd_pcm_uframes_t src_frames, dst_frames;
dst_frames = client_size - client_xfer;
src_frames = snd_pcm_mmap_capture_xfer(slave, slave_size - slave_xfer);
src_frames = rate->func(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
@@ -478,7 +496,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
err = snd_pcm_mmap_forward(slave, src_frames);
if (err < 0)
break;
- assert((size_t)err == src_frames);
+ assert((snd_pcm_uframes_t)err == src_frames);
slave_xfer += src_frames;
}
if (dst_frames > 0) {
@@ -495,7 +513,7 @@ static ssize_t snd_pcm_rate_read_areas(snd_pcm_t *pcm,
return err;
}
-ssize_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, ssize_t frames)
+snd_pcm_sframes_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
{
snd_pcm_rate_t *rate = pcm->private;
/* Round toward zero */
@@ -505,7 +523,7 @@ ssize_t snd_pcm_rate_client_frames(snd_pcm_t *pcm, ssize_t frames)
return muldiv_down(frames, rate->pitch, DIV);
}
-ssize_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, ssize_t frames)
+snd_pcm_sframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
{
snd_pcm_rate_t *rate = pcm->private;
/* Round toward zero */
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
index 15b7eb30..c9125cb4 100644
--- a/src/pcm/pcm_route.c
+++ b/src/pcm/pcm_route.c
@@ -50,16 +50,16 @@ typedef struct {
int conv_idx;
int src_size;
int dst_sfmt;
- size_t ndsts;
+ unsigned int ndsts;
ttable_dst_t *dsts;
} route_params_t;
typedef void (*route_f)(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_area,
- size_t dst_offset,
- size_t frames,
+ snd_pcm_uframes_t dst_offset,
+ snd_pcm_uframes_t frames,
const ttable_dst_t *ttable,
const route_params_t *params);
@@ -88,10 +88,10 @@ typedef struct {
static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED,
- size_t src_offset ATTRIBUTE_UNUSED,
+ snd_pcm_uframes_t src_offset ATTRIBUTE_UNUSED,
const snd_pcm_channel_area_t *dst_area,
- size_t dst_offset,
- size_t frames,
+ snd_pcm_uframes_t dst_offset,
+ snd_pcm_uframes_t frames,
const ttable_dst_t* ttable ATTRIBUTE_UNUSED,
const route_params_t *params)
{
@@ -105,10 +105,10 @@ static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED
}
static void route1_one(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_area,
- size_t dst_offset,
- size_t frames,
+ snd_pcm_uframes_t dst_offset,
+ snd_pcm_uframes_t frames,
const ttable_dst_t* ttable,
const route_params_t *params)
{
@@ -150,10 +150,10 @@ static void route1_one(const snd_pcm_channel_area_t *src_areas,
}
static void route1_many(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_area,
- size_t dst_offset,
- size_t frames,
+ snd_pcm_uframes_t dst_offset,
+ snd_pcm_uframes_t frames,
const ttable_dst_t* ttable,
const route_params_t *params)
{
@@ -383,14 +383,14 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
}
static void route_transfer(const snd_pcm_channel_area_t *src_areas,
- size_t src_offset,
+ snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas,
- size_t dst_offset,
- size_t dst_channels,
- size_t frames,
+ snd_pcm_uframes_t dst_offset,
+ snd_pcm_uframes_t dst_channels,
+ snd_pcm_uframes_t frames,
route_params_t *params)
{
- size_t dst_channel;
+ unsigned int dst_channel;
ttable_dst_t *dstp;
const snd_pcm_channel_area_t *dst_area;
@@ -411,7 +411,7 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
snd_pcm_route_t *route = pcm->private;
route_params_t *params = &route->params;
int err = 0;
- size_t dst_channel;
+ unsigned int dst_channel;
if (route->plug.close_slave)
err = snd_pcm_close(route->plug.slave);
if (params->dsts) {
@@ -430,56 +430,63 @@ static int snd_pcm_route_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_route_t *route = pcm->private;
snd_pcm_t *slave = route->plug.slave;
int err;
+ unsigned int cmask, lcmask;
snd_pcm_hw_params_t sparams;
unsigned int links = (SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
mask_t *access_mask = alloca(mask_sizeof());
mask_t *format_mask = alloca(mask_sizeof());
mask_t *saccess_mask = alloca(mask_sizeof());
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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
access_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_mask(params, 1, SND_PCM_HW_PARAM_FORMAT,
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT,
format_mask);
if (err < 0)
return err;
- err = _snd_pcm_hw_param_min(params, 1, SND_PCM_HW_PARAM_CHANNELS, 1);
+ err = _snd_pcm_hw_param_min(params, SND_PCM_HW_PARAM_CHANNELS, 1, 0);
if (err < 0)
return err;
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (route->sformat >= 0) {
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- route->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ route->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
} 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_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
- route->schannels);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+ route->schannels, 0);
} else {
links |= SND_PCM_HW_PARBIT_CHANNELS;
if (route->sformat < 0)
links |= (SND_PCM_HW_PARBIT_FRAME_BITS |
- SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+ SND_PCM_HW_PARBIT_PERIOD_BYTES |
SND_PCM_HW_PARBIT_BUFFER_BYTES);
}
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave, links);
+ snd_pcm_generic_hw_link, slave, links);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
@@ -492,49 +499,56 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
snd_pcm_t *slave = route->plug.slave;
int err;
snd_pcm_hw_params_t sparams;
- unsigned int links = (SND_PCM_HW_PARBIT_FRAGMENTS |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+ unsigned int links = (SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH);
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_TICK_TIME);
unsigned int src_format, dst_format;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
if (route->sformat >= 0) {
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_FORMAT,
- route->sformat);
- _snd_pcm_hw_param_set(&sparams, 0, SND_PCM_HW_PARAM_SUBFORMAT,
- SND_PCM_SUBFORMAT_STD);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_FORMAT,
+ route->sformat, 0);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_SUBFORMAT,
+ SND_PCM_SUBFORMAT_STD, 0);
} 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_param_set(&sparams, 0, SND_PCM_HW_PARAM_CHANNELS,
- route->schannels);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+ route->schannels, 0);
} else {
links |= SND_PCM_HW_PARBIT_CHANNELS;
if (route->sformat < 0)
links |= (SND_PCM_HW_PARBIT_FRAME_BITS |
- SND_PCM_HW_PARBIT_FRAGMENT_BYTES |
+ SND_PCM_HW_PARBIT_PERIOD_BYTES |
SND_PCM_HW_PARBIT_BUFFER_BYTES);
}
- err = snd_pcm_hw_params2(params, &sparams,
- snd_pcm_hw_params, slave, links);
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
if (err < 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_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ src_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
dst_format = slave->format;
} else {
src_format = slave->format;
- dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT);
+ dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0);
}
route->params.get_idx = get_index(src_format, SND_PCM_FORMAT_U16);
route->params.put_idx = put_index(SND_PCM_FORMAT_U32, dst_format);
@@ -552,28 +566,28 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
return 0;
}
-static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_route_t *route = pcm->private;
snd_pcm_t *slave = route->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_playback_xfer(slave, size - xfer);
route_transfer(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
slave->channels, frames, &route->params);
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
@@ -586,28 +600,28 @@ static ssize_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
return err;
}
-static ssize_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
+static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
const snd_pcm_channel_area_t *areas,
- size_t offset,
- size_t size,
- size_t *slave_sizep)
+ snd_pcm_uframes_t offset,
+ snd_pcm_uframes_t size,
+ snd_pcm_uframes_t *slave_sizep)
{
snd_pcm_route_t *route = pcm->private;
snd_pcm_t *slave = route->plug.slave;
- size_t xfer = 0;
- ssize_t err = 0;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_sframes_t err = 0;
if (slave_sizep && *slave_sizep < size)
size = *slave_sizep;
assert(size > 0);
while (xfer < size) {
- size_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
+ snd_pcm_uframes_t frames = snd_pcm_mmap_capture_xfer(slave, size - xfer);
route_transfer(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset,
pcm->channels, frames, &route->params);
err = snd_pcm_mmap_forward(slave, frames);
if (err < 0)
break;
- assert((size_t)err == frames);
+ assert((snd_pcm_uframes_t)err == frames);
offset += err;
xfer += err;
snd_pcm_mmap_hw_forward(pcm, err);
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c
index e649ffdf..ef7ac47e 100644
--- a/src/pcm/pcm_share.c
+++ b/src/pcm/pcm_share.c
@@ -69,16 +69,16 @@ typedef struct {
snd_pcm_t *pcm;
int format;
int rate;
- size_t channels_count;
- size_t open_count;
- size_t setup_count;
- size_t mmap_count;
- size_t prepared_count;
- size_t running_count;
- size_t safety_threshold;
- size_t silence_frames;
+ unsigned int channels_count;
+ unsigned int open_count;
+ unsigned int setup_count;
+ unsigned int mmap_count;
+ unsigned int prepared_count;
+ unsigned int running_count;
+ snd_pcm_uframes_t safety_threshold;
+ snd_pcm_uframes_t silence_frames;
snd_pcm_sw_params_t sw_params;
- size_t hw_ptr;
+ snd_pcm_uframes_t hw_ptr;
int poll[2];
int polling;
pthread_t thread;
@@ -91,18 +91,18 @@ typedef struct {
struct list_head list;
snd_pcm_t *pcm;
snd_pcm_share_slave_t *slave;
- size_t channels_count;
+ unsigned int channels_count;
int *slave_channels;
int xfer_mode;
int xrun_mode;
- size_t avail_min;
+ snd_pcm_uframes_t avail_min;
int async_sig;
pid_t async_pid;
int drain_silenced;
struct timeval trigger_time;
int state;
- size_t hw_ptr;
- size_t appl_ptr;
+ snd_pcm_uframes_t hw_ptr;
+ snd_pcm_uframes_t appl_ptr;
int ready;
int client_socket;
int slave_socket;
@@ -110,9 +110,9 @@ typedef struct {
static void _snd_pcm_share_stop(snd_pcm_t *pcm, int state);
-static size_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
{
- ssize_t avail;
+ snd_pcm_sframes_t avail;
snd_pcm_t *pcm = slave->pcm;
avail = slave->hw_ptr - *pcm->appl_ptr;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
@@ -124,15 +124,15 @@ static size_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
/* Warning: take the mutex before to call this */
/* Return number of frames to mmap_forward the slave */
-static size_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
{
struct list_head *i;
- size_t buffer_size, boundary;
- size_t slave_appl_ptr;
- ssize_t frames, safety_frames;
- ssize_t min_frames, max_frames;
- size_t avail, slave_avail;
- size_t slave_hw_avail;
+ snd_pcm_uframes_t buffer_size, boundary;
+ snd_pcm_uframes_t slave_appl_ptr;
+ snd_pcm_sframes_t frames, safety_frames;
+ snd_pcm_sframes_t min_frames, max_frames;
+ snd_pcm_uframes_t avail, slave_avail;
+ snd_pcm_uframes_t slave_hw_avail;
slave_avail = snd_pcm_share_slave_avail(slave);
boundary = slave->pcm->boundary;
buffer_size = slave->pcm->buffer_size;
@@ -187,17 +187,17 @@ static size_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
- draining silencing
- return distance in frames to next event
*/
-static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
+static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_t *spcm = slave->pcm;
- size_t buffer_size = spcm->buffer_size;
+ snd_pcm_uframes_t buffer_size = spcm->buffer_size;
int ready = 1, running = 0;
- size_t avail = 0, slave_avail;
- ssize_t hw_avail;
- size_t missing = INT_MAX;
- ssize_t ready_missing;
+ snd_pcm_uframes_t avail = 0, slave_avail;
+ snd_pcm_sframes_t hw_avail;
+ snd_pcm_uframes_t missing = INT_MAX;
+ snd_pcm_sframes_t ready_missing;
// printf("state=%d hw_ptr=%d appl_ptr=%d slave appl_ptr=%d safety=%d silence=%d\n", share->state, slave->hw_ptr, share->appl_ptr, *slave->pcm->appl_ptr, slave->safety_threshold, slave->silence_frames);
switch (share->state) {
case SND_PCM_STATE_RUNNING:
@@ -219,11 +219,11 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
slave_avail = snd_pcm_share_slave_avail(slave);
if (avail < slave_avail) {
/* Some frames need still to be transferred */
- ssize_t slave_hw_avail = buffer_size - slave_avail;
- ssize_t safety_missing = slave_hw_avail - slave->safety_threshold;
+ snd_pcm_sframes_t slave_hw_avail = buffer_size - slave_avail;
+ snd_pcm_sframes_t safety_missing = slave_hw_avail - slave->safety_threshold;
if (safety_missing < 0) {
- ssize_t err;
- ssize_t frames = slave_avail - avail;
+ snd_pcm_sframes_t err;
+ snd_pcm_sframes_t frames = slave_avail - avail;
if (-safety_missing <= frames) {
frames = -safety_missing;
missing = 1;
@@ -245,7 +245,7 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
_snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
break;
}
- if ((size_t)hw_avail < missing)
+ if ((snd_pcm_uframes_t)hw_avail < missing)
missing = hw_avail;
running = 1;
ready = 0;
@@ -257,13 +257,13 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
_snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
break;
}
- if ((size_t)hw_avail < missing)
+ if ((snd_pcm_uframes_t)hw_avail < missing)
missing = hw_avail;
}
ready_missing = share->avail_min - avail;
if (ready_missing > 0) {
ready = 0;
- if ((size_t)ready_missing < missing)
+ if ((snd_pcm_uframes_t)ready_missing < missing)
missing = ready_missing;
}
running = 1;
@@ -293,12 +293,12 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
!share->drain_silenced) {
/* drain silencing */
if (avail >= slave->silence_frames) {
- size_t offset = share->appl_ptr % buffer_size;
- size_t xfer = 0;
- size_t size = slave->silence_frames;
+ snd_pcm_uframes_t offset = share->appl_ptr % buffer_size;
+ snd_pcm_uframes_t xfer = 0;
+ snd_pcm_uframes_t size = slave->silence_frames;
while (xfer < size) {
- size_t frames = size - xfer;
- size_t cont = buffer_size - offset;
+ snd_pcm_uframes_t frames = size - xfer;
+ snd_pcm_uframes_t cont = buffer_size - offset;
if (cont < frames)
frames = cont;
snd_pcm_areas_silence(pcm->running_areas, offset, pcm->channels, frames, pcm->format);
@@ -309,7 +309,7 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
}
share->drain_silenced = 1;
} else {
- size_t silence_missing;
+ snd_pcm_uframes_t silence_missing;
silence_missing = slave->silence_frames - avail;
if (silence_missing < missing)
missing = silence_missing;
@@ -319,17 +319,17 @@ static size_t _snd_pcm_share_missing(snd_pcm_t *pcm, int slave_xrun)
return missing;
}
-static size_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *slave)
+static snd_pcm_uframes_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *slave)
{
- size_t missing = INT_MAX;
+ snd_pcm_uframes_t missing = INT_MAX;
struct list_head *i;
- ssize_t avail = snd_pcm_avail_update(slave->pcm);
+ snd_pcm_sframes_t avail = snd_pcm_avail_update(slave->pcm);
int slave_xrun = (avail == -EPIPE);
slave->hw_ptr = *slave->pcm->hw_ptr;
for (i = slave->clients.next; i != &slave->clients; i = i->next) {
snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
snd_pcm_t *pcm = share->pcm;
- size_t m = _snd_pcm_share_missing(pcm, slave_xrun);
+ snd_pcm_uframes_t m = _snd_pcm_share_missing(pcm, slave_xrun);
if (m < missing)
missing = m;
}
@@ -350,25 +350,25 @@ void *snd_pcm_share_slave_thread(void *data)
err = pipe(slave->poll);
assert(err >= 0);
while (slave->open_count > 0) {
- size_t missing;
+ snd_pcm_uframes_t missing;
// printf("begin min_missing\n");
missing = _snd_pcm_share_slave_missing(slave);
// printf("min_missing=%d\n", missing);
if (missing < INT_MAX) {
- size_t hw_ptr;
- ssize_t avail_min;
+ snd_pcm_uframes_t hw_ptr;
+ snd_pcm_sframes_t avail_min;
hw_ptr = slave->hw_ptr + missing;
- hw_ptr += spcm->fragment_size - 1;
+ hw_ptr += spcm->period_size - 1;
if (hw_ptr >= spcm->boundary)
hw_ptr -= spcm->boundary;
- hw_ptr -= hw_ptr % spcm->fragment_size;
+ hw_ptr -= hw_ptr % spcm->period_size;
avail_min = hw_ptr - *spcm->appl_ptr;
if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
avail_min += spcm->buffer_size;
if (avail_min < 0)
avail_min += spcm->boundary;
// printf("avail_min=%d\n", avail_min);
- if ((size_t)avail_min != spcm->avail_min) {
+ if ((snd_pcm_uframes_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);
@@ -395,8 +395,8 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm)
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_t *spcm = slave->pcm;
- size_t missing;
- ssize_t avail = snd_pcm_avail_update(spcm);
+ snd_pcm_uframes_t missing;
+ snd_pcm_sframes_t avail = snd_pcm_avail_update(spcm);
slave->hw_ptr = *slave->pcm->hw_ptr;
missing = _snd_pcm_share_missing(pcm, avail == -EPIPE);
if (!slave->polling) {
@@ -404,20 +404,20 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm)
return;
}
if (missing < INT_MAX) {
- size_t hw_ptr;
- ssize_t avail_min;
+ snd_pcm_uframes_t hw_ptr;
+ snd_pcm_sframes_t avail_min;
int err;
hw_ptr = slave->hw_ptr + missing;
- hw_ptr += spcm->fragment_size - 1;
+ hw_ptr += spcm->period_size - 1;
if (hw_ptr >= spcm->boundary)
hw_ptr -= spcm->boundary;
- hw_ptr -= hw_ptr % spcm->fragment_size;
+ hw_ptr -= hw_ptr % spcm->period_size;
avail_min = hw_ptr - *spcm->appl_ptr;
if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
avail_min += spcm->buffer_size;
if (avail_min < 0)
avail_min += spcm->boundary;
- if ((size_t)avail_min < spcm->avail_min) {
+ if ((snd_pcm_uframes_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);
@@ -461,57 +461,64 @@ static int snd_pcm_share_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
snd_pcm_share_slave_t *slave = share->slave;
snd_pcm_hw_params_t sparams;
int err;
+ unsigned int cmask, lcmask;
mask_t *access_mask = alloca(mask_sizeof());
const mask_t *mmap_mask;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_CHANNELS,
- share->channels_count);
+ cmask = params->cmask;
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
+ share->channels_count, 0);
if (err < 0)
return err;
if (slave->format >= 0) {
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
- slave->format);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT,
+ slave->format, 0);
if (err < 0)
return err;
}
if (slave->rate >= 0) {
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
- slave->rate);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_RATE,
+ slave->rate, 0);
if (err < 0)
return err;
}
+ lcmask = params->cmask;
+ params->cmask |= cmask;
_snd_pcm_hw_params_any(&sparams);
- _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_CHANNELS,
- slave->channels_count);
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+ slave->channels_count, 0);
err = snd_pcm_hw_refine2(params, &sparams,
- snd_pcm_hw_refine, slave->pcm,
+ snd_pcm_generic_hw_link, slave->pcm,
SND_PCM_HW_PARBIT_FORMAT |
SND_PCM_HW_PARBIT_SUBFORMAT |
SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH |
- SND_PCM_HW_PARBIT_FRAGMENTS);
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_TICK_TIME);
if (err < 0)
return err;
mmap_mask = snd_pcm_hw_param_value_mask(&sparams, SND_PCM_HW_PARAM_ACCESS);
- mask_all(access_mask);
+ mask_any(access_mask);
mask_reset(access_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
if (!mask_test(mmap_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED))
mask_reset(access_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_param_mask(params, 1, SND_PCM_HW_PARAM_ACCESS,
+ err = _snd_pcm_hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS,
access_mask);
+ params->cmask |= lcmask;
if (err < 0)
return err;
params->info |= SND_PCM_INFO_DOUBLE;
@@ -527,24 +534,29 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
Pthread_mutex_lock(&slave->mutex);
if (slave->setup_count > 1 ||
(slave->setup_count == 1 && !pcm->setup)) {
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FORMAT,
- spcm->format);
+ params->cmask = 0;
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_FORMAT,
+ spcm->format, 0);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_SUBFORMAT,
- spcm->subformat);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_SUBFORMAT,
+ spcm->subformat, 0);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_RATE,
- spcm->rate);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_RATE,
+ spcm->rate, 0);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENT_SIZE,
- spcm->fragment_size);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_PERIOD_TIME,
+ spcm->period_time, 0);
if (err < 0)
goto _err;
- err = _snd_pcm_hw_param_set(params, 1, SND_PCM_HW_PARAM_FRAGMENTS,
- spcm->fragments);
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
+ spcm->buffer_size, 0);
+ if (err < 0)
+ goto _err;
+ err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_TICK_TIME,
+ spcm->tick_time, 0);
_err:
if (err < 0) {
ERR("slave is already running with different setup");
@@ -553,30 +565,38 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
}
} else {
snd_pcm_hw_params_t sparams;
+ unsigned int links;
mask_t *saccess_mask = alloca(mask_sizeof());
mask_load(saccess_mask, SND_PCM_ACCBIT_MMAP);
+ links = SND_PCM_HW_PARBIT_FORMAT |
+ SND_PCM_HW_PARBIT_SUBFORMAT |
+ SND_PCM_HW_PARBIT_RATE |
+ SND_PCM_HW_PARBIT_PERIOD_SIZE |
+ SND_PCM_HW_PARBIT_PERIOD_TIME |
+ SND_PCM_HW_PARBIT_BUFFER_SIZE |
+ SND_PCM_HW_PARBIT_BUFFER_TIME |
+ SND_PCM_HW_PARBIT_PERIODS |
+ SND_PCM_HW_PARBIT_TICK_TIME;
_snd_pcm_hw_params_any(&sparams);
- _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_CHANNELS,
- share->channels_count);
- err = snd_pcm_hw_params2(params, &sparams,
- snd_pcm_hw_params, slave->pcm,
- SND_PCM_HW_PARBIT_FORMAT |
- SND_PCM_HW_PARBIT_SUBFORMAT |
- SND_PCM_HW_PARBIT_RATE |
- SND_PCM_HW_PARBIT_FRAGMENT_SIZE |
- SND_PCM_HW_PARBIT_FRAGMENT_LENGTH |
- SND_PCM_HW_PARBIT_BUFFER_SIZE |
- SND_PCM_HW_PARBIT_BUFFER_LENGTH |
- SND_PCM_HW_PARBIT_FRAGMENTS);
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
+ saccess_mask);
+ _snd_pcm_hw_param_set(&sparams, SND_PCM_HW_PARAM_CHANNELS,
+ share->channels_count, 0);
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = snd_pcm_hw_params(slave->pcm, &sparams);
+ params->cmask = 0;
+ sparams.cmask = ~0U;
+ snd_pcm_hw_params_refine(params, links, &sparams);
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;
- slave->safety_threshold -= slave->safety_threshold % slave->pcm->fragment_size;
+ slave->safety_threshold += slave->pcm->period_size - 1;
+ slave->safety_threshold -= slave->safety_threshold % slave->pcm->period_size;
slave->silence_frames = slave->safety_threshold;
if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->channels, slave->pcm->buffer_size, slave->pcm->format);
@@ -598,7 +618,7 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
int err = 0;
- ssize_t sd = 0, d = 0;
+ snd_pcm_sframes_t sd = 0, d = 0;
Pthread_mutex_lock(&slave->mutex);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
status->avail = snd_pcm_mmap_playback_avail(pcm);
@@ -630,12 +650,12 @@ static int snd_pcm_share_state(snd_pcm_t *pcm)
return share->state;
}
-static int _snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int _snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
int err = 0;
- ssize_t sd;
+ snd_pcm_sframes_t sd;
switch (share->state) {
case SND_PCM_STATE_XRUN:
return -EPIPE;
@@ -655,7 +675,7 @@ static int _snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
return 0;
}
-static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
@@ -666,11 +686,11 @@ static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
return err;
}
-static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
- ssize_t avail;
+ snd_pcm_sframes_t avail;
Pthread_mutex_lock(&slave->mutex);
if (share->state == SND_PCM_STATE_RUNNING) {
avail = snd_pcm_avail_update(slave->pcm);
@@ -682,24 +702,24 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
}
Pthread_mutex_unlock(&slave->mutex);
avail = snd_pcm_mmap_avail(pcm);
- if ((size_t)avail > pcm->buffer_size)
+ if ((snd_pcm_uframes_t)avail > pcm->buffer_size)
return -EPIPE;
return avail;
}
/* Call it with mutex held */
-static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
- ssize_t ret = 0;
- ssize_t frames;
+ snd_pcm_sframes_t ret = 0;
+ snd_pcm_sframes_t frames;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
share->state == SND_PCM_STATE_RUNNING) {
frames = *slave->pcm->appl_ptr - share->appl_ptr;
- if (frames > (ssize_t)pcm->buffer_size)
+ if (frames > (snd_pcm_sframes_t)pcm->buffer_size)
frames -= pcm->boundary;
- else if (frames < -(ssize_t)pcm->buffer_size)
+ else if (frames < -(snd_pcm_sframes_t)pcm->buffer_size)
frames += pcm->boundary;
if (frames > 0) {
/* Latecomer PCM */
@@ -710,9 +730,9 @@ static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
}
snd_pcm_mmap_appl_forward(pcm, size);
if (share->state == SND_PCM_STATE_RUNNING) {
- ssize_t frames = _snd_pcm_share_slave_forward(slave);
+ snd_pcm_sframes_t frames = _snd_pcm_share_slave_forward(slave);
if (frames > 0) {
- ssize_t err;
+ snd_pcm_sframes_t err;
err = snd_pcm_mmap_forward(slave->pcm, frames);
assert(err == frames);
}
@@ -721,11 +741,11 @@ static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
return size;
}
-static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
- ssize_t ret;
+ snd_pcm_sframes_t ret;
Pthread_mutex_lock(&slave->mutex);
ret = _snd_pcm_share_mmap_forward(pcm, size);
Pthread_mutex_unlock(&slave->mutex);
@@ -776,14 +796,14 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
Pthread_mutex_lock(&slave->mutex);
share->state = SND_PCM_STATE_RUNNING;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
- size_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
- size_t xfer = 0;
+ snd_pcm_uframes_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
+ snd_pcm_uframes_t xfer = 0;
if (hw_avail == 0) {
err = -EPIPE;
goto _end;
}
if (slave->running_count) {
- ssize_t sd;
+ snd_pcm_sframes_t sd;
err = snd_pcm_delay(slave->pcm, &sd);
if (err < 0)
goto _end;
@@ -795,9 +815,9 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
share->hw_ptr = *slave->pcm->hw_ptr;
share->appl_ptr = *slave->pcm->appl_ptr;
while (xfer < hw_avail) {
- size_t frames = hw_avail - xfer;
- size_t offset = snd_pcm_mmap_offset(pcm);
- size_t cont = pcm->buffer_size - offset;
+ snd_pcm_uframes_t frames = hw_avail - xfer;
+ snd_pcm_uframes_t offset = snd_pcm_mmap_offset(pcm);
+ snd_pcm_uframes_t cont = pcm->buffer_size - offset;
if (cont < frames)
frames = cont;
snd_pcm_areas_copy(pcm->stopped_areas, xfer,
@@ -841,11 +861,11 @@ static int snd_pcm_share_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *in
return err;
}
-static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t _snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
- ssize_t n;
+ snd_pcm_sframes_t n;
switch (share->state) {
case SND_PCM_STATE_RUNNING:
break;
@@ -865,7 +885,7 @@ static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
n = snd_pcm_mmap_hw_avail(pcm);
assert(n >= 0);
if (n > 0) {
- if ((size_t)n > frames)
+ if ((snd_pcm_uframes_t)n > frames)
n = frames;
frames -= n;
}
@@ -881,11 +901,11 @@ static ssize_t _snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
return n;
}
-static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private;
snd_pcm_share_slave_t *slave = share->slave;
- ssize_t ret;
+ snd_pcm_sframes_t ret;
Pthread_mutex_lock(&slave->mutex);
ret = _snd_pcm_share_rewind(pcm, frames);
Pthread_mutex_unlock(&slave->mutex);
@@ -909,7 +929,7 @@ static void _snd_pcm_share_stop(snd_pcm_t *pcm, int state)
pcm->format);
} else if (slave->running_count > 1) {
int err;
- ssize_t delay;
+ snd_pcm_sframes_t delay;
snd_pcm_areas_silence(pcm->running_areas, 0, pcm->channels,
pcm->buffer_size, pcm->format);
err = snd_pcm_delay(slave->pcm, &delay);
@@ -1106,8 +1126,8 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
int sformat, int srate,
- size_t schannels_count,
- size_t channels_count, int *channels_map,
+ unsigned int schannels_count,
+ unsigned int channels_count, int *channels_map,
int stream, int mode)
{
snd_pcm_t *pcm;
@@ -1291,9 +1311,9 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
int err;
unsigned int idx;
int *channels_map;
- size_t channels_count = 0;
+ unsigned int channels_count = 0;
long schannels_count = -1;
- size_t schannel_max = 0;
+ unsigned int schannel_max = 0;
int sformat = -1;
long srate = -1;
diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c
index aecec8c6..c6b1e5bb 100644
--- a/src/pcm/pcm_shm.c
+++ b/src/pcm/pcm_shm.c
@@ -168,6 +168,27 @@ static int _snd_pcm_shm_hw_refine(snd_pcm_t *pcm,
return err;
}
+/* Accumulate to params->cmask */
+/* Reset sparams->cmask */
+int snd_pcm_shm_hw_link(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_params_t *sparams,
+ snd_pcm_t *slave,
+ unsigned long links)
+{
+ int err1, err = 0;
+ err = snd_pcm_hw_params_refine(sparams, links, params);
+ if (err >= 0) {
+ unsigned int cmask = sparams->cmask;
+ err = _snd_pcm_shm_hw_refine(slave, sparams);
+ sparams->cmask |= cmask;
+ }
+ err1 = snd_pcm_hw_params_refine(params, links, sparams);
+ if (err1 < 0)
+ err = err1;
+ sparams->cmask = 0;
+ return err;
+}
+
static int snd_pcm_shm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_hw_params_t sparams;
@@ -178,10 +199,10 @@ static int snd_pcm_shm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
!mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED))
mask_intersect(saccess_mask, access_mask);
_snd_pcm_hw_params_any(&sparams);
- _snd_pcm_hw_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
return snd_pcm_hw_refine2(params, &sparams,
- _snd_pcm_shm_hw_refine, pcm,
+ snd_pcm_shm_hw_link, pcm,
~SND_PCM_HW_PARBIT_ACCESS);
}
@@ -201,18 +222,27 @@ static int _snd_pcm_shm_hw_params(snd_pcm_t *pcm,
static int snd_pcm_shm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_hw_params_t sparams;
+ unsigned int links = ~SND_PCM_HW_PARBIT_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());
+ int err;
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_param_mask(&sparams, 0, SND_PCM_HW_PARAM_ACCESS,
+ _snd_pcm_hw_param_mask(&sparams, SND_PCM_HW_PARAM_ACCESS,
saccess_mask);
- return snd_pcm_hw_params2(params, &sparams,
- _snd_pcm_shm_hw_params, pcm,
- ~SND_PCM_HW_PARBIT_ACCESS);
+ err = snd_pcm_hw_params_refine(&sparams, links, params);
+ assert(err >= 0);
+ err = _snd_pcm_hw_refine(&sparams);
+ assert(err >= 0);
+ err = _snd_pcm_shm_hw_params(pcm, &sparams);
+ if (err < 0) {
+ snd_pcm_hw_params_refine(params, links, &sparams);
+ return err;
+ }
+ return 0;
}
static int snd_pcm_shm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
@@ -310,7 +340,7 @@ static int snd_pcm_shm_state(snd_pcm_t *pcm)
return snd_pcm_shm_action(pcm);
}
-static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp)
+static int snd_pcm_shm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
snd_pcm_shm_t *shm = pcm->private;
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -323,7 +353,7 @@ static int snd_pcm_shm_delay(snd_pcm_t *pcm, ssize_t *delayp)
return err;
}
-static ssize_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
+static snd_pcm_sframes_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
{
snd_pcm_shm_t *shm = pcm->private;
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -390,7 +420,7 @@ static int snd_pcm_shm_pause(snd_pcm_t *pcm, int enable)
return snd_pcm_shm_action(pcm);
}
-static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames)
+static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_shm_t *shm = pcm->private;
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
@@ -399,7 +429,7 @@ static ssize_t snd_pcm_shm_rewind(snd_pcm_t *pcm, size_t frames)
return snd_pcm_shm_action(pcm);
}
-static ssize_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, size_t size)
+static snd_pcm_sframes_t snd_pcm_shm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{
snd_pcm_shm_t *shm = pcm->private;
volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
diff --git a/src/rawmidi/rawmidi_hw.c b/src/rawmidi/rawmidi_hw.c
index a5b5ec95..c11432ac 100644
--- a/src/rawmidi/rawmidi_hw.c
+++ b/src/rawmidi/rawmidi_hw.c
@@ -245,7 +245,7 @@ int snd_rawmidi_hw_open(snd_rawmidi_t **handlep, char *name, int card, int devic
snd_ctl_close(ctl);
return ret;
}
- if (info.subdevice != subdevice) {
+ if (info.subdevice != (unsigned int) subdevice) {
close(fd);
goto __again;
}