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
This commit is contained in:
Abramo Bagnara 2001-01-15 11:06:53 +00:00
parent 7b06e6f762
commit cc90e32557
29 changed files with 2433 additions and 1906 deletions

1
TODO
View file

@ -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)

View file

@ -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
}

View file

@ -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

View file

@ -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);

View file

@ -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)
{
i->real = 1;
if (i->integer)
return 0;
if (i->openmin && i->openmax && i->min == i->max)
return -EINVAL;
i->integer = 1;
return 1;
}
INLINE int interval_eq(const interval_t *i1, const interval_t *i2)
INLINE void interval_round(interval_t *i)
{
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;
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_never_eq(const interval_t *i1, const interval_t *i2)
{
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)));
}

View file

@ -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

View file

@ -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;
}

View file

@ -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(CHANNELS),
HW_PARAM(RATE),
HW_PARAM(FRAGMENT_LENGTH),
HW_PARAM(FRAGMENT_SIZE),
HW_PARAM(FRAGMENTS),
HW_PARAM(BUFFER_LENGTH),
HW_PARAM(BUFFER_SIZE),
HW_PARAM(SAMPLE_BITS),
HW_PARAM(FRAME_BITS),
HW_PARAM(FRAGMENT_BYTES),
HW_PARAM(CHANNELS),
HW_PARAM(RATE),
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(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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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);
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 ssize_t (*snd_pcm_xfer_areas_func_t)(snd_pcm_t *pcm,
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) | \

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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,

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}