mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
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:
parent
7b06e6f762
commit
cc90e32557
29 changed files with 2433 additions and 1906 deletions
1
TODO
1
TODO
|
|
@ -1,3 +1,4 @@
|
|||
H change functions that take a FILE* to take a char * and a maximum size
|
||||
M think about xrun recovery helpers
|
||||
M add abstraction layer to timer, hwdep
|
||||
L move OSS emulation to user space? (pseudo device driver and daemon)
|
||||
|
|
|
|||
171
include/pcm.h
171
include/pcm.h
|
|
@ -47,8 +47,8 @@ int snd_pcm_open(snd_pcm_t **pcm, char *name,
|
|||
/* Obsolete functions */
|
||||
#define snd_pcm_write snd_pcm_writei
|
||||
#define snd_pcm_read snd_pcm_readi
|
||||
ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
|
||||
ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
|
||||
snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count);
|
||||
snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count);
|
||||
|
||||
|
||||
snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
|
||||
|
|
@ -69,12 +69,12 @@ int snd_pcm_drop(snd_pcm_t *pcm);
|
|||
int snd_pcm_drain(snd_pcm_t *pcm);
|
||||
int snd_pcm_pause(snd_pcm_t *pcm, int enable);
|
||||
int snd_pcm_state(snd_pcm_t *pcm);
|
||||
int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp);
|
||||
ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames);
|
||||
ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
|
||||
ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size);
|
||||
ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size);
|
||||
ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size);
|
||||
int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
|
||||
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
|
||||
int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp);
|
||||
int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp);
|
||||
|
|
@ -85,13 +85,13 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
|
|||
int snd_pcm_unlink(snd_pcm_t *pcm);
|
||||
|
||||
int snd_pcm_wait(snd_pcm_t *pcm, int timeout);
|
||||
ssize_t snd_pcm_avail_update(snd_pcm_t *pcm);
|
||||
int snd_pcm_set_avail_min(snd_pcm_t *pcm, size_t size);
|
||||
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
|
||||
int snd_pcm_set_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t size);
|
||||
|
||||
typedef struct _mask mask_t;
|
||||
size_t mask_sizeof();
|
||||
void mask_none(mask_t *mask);
|
||||
void mask_all(mask_t *mask);
|
||||
void mask_any(mask_t *mask);
|
||||
void mask_load(mask_t *mask, unsigned int msk);
|
||||
int mask_empty(const mask_t *mask);
|
||||
void mask_set(mask_t *mask, unsigned int val);
|
||||
|
|
@ -99,48 +99,59 @@ void mask_reset(mask_t *mask, unsigned int val);
|
|||
void mask_copy(mask_t *mask, const mask_t *v);
|
||||
int mask_test(const mask_t *mask, unsigned int val);
|
||||
void mask_intersect(mask_t *mask, const mask_t *v);
|
||||
void mask_union(mask_t *mask, const mask_t *v);
|
||||
int mask_eq(const mask_t *a, const mask_t *b);
|
||||
int mask_single(const mask_t *mask);
|
||||
|
||||
int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
|
||||
int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var);
|
||||
int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var);
|
||||
int snd_pcm_hw_param_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int par);
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
int snd_pcm_hw_param_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int par);
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var, unsigned int val,
|
||||
int *dir);
|
||||
int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int val, int *dir);
|
||||
int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var, unsigned int val, int *dir);
|
||||
int snd_pcm_hw_param_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int min, unsigned int max);
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int *min, int *mindir,
|
||||
unsigned int *max, int *maxdir);
|
||||
int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var, unsigned int val, int dir);
|
||||
int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, const mask_t *mask);
|
||||
snd_pcm_hw_param_t var, const mask_t *mask);
|
||||
int snd_pcm_hw_param_min_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int val, int *dir);
|
||||
int snd_pcm_hw_param_max_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int val, int *dir);
|
||||
int snd_pcm_hw_param_minmax_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int min, unsigned int max);
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int *min, int *mindir,
|
||||
unsigned int *max, int *maxdir);
|
||||
int snd_pcm_hw_param_set_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, unsigned int val);
|
||||
snd_pcm_hw_param_t var, unsigned int val, int dir);
|
||||
int snd_pcm_hw_param_mask_try(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
||||
unsigned int var, const mask_t *mask);
|
||||
snd_pcm_hw_param_t var, const mask_t *mask);
|
||||
int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
const mask_t *snd_pcm_hw_param_value_mask(const snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var);
|
||||
const interval_t *snd_pcm_hw_param_value_interval(const snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var);
|
||||
unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
|
||||
unsigned int var);
|
||||
snd_pcm_hw_param_t var, int *dir);
|
||||
int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm,
|
||||
snd_pcm_hw_params_t *fail,
|
||||
snd_pcm_hw_params_t *success,
|
||||
|
|
@ -174,73 +185,73 @@ int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp,
|
|||
unsigned int badness_min,
|
||||
unsigned int badness_max);
|
||||
int snd_pcm_hw_strategy_simple_near(snd_pcm_hw_strategy_t *strategy, int order,
|
||||
unsigned int param,
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int best,
|
||||
unsigned int mul);
|
||||
int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int order,
|
||||
unsigned int param,
|
||||
snd_pcm_hw_param_t var,
|
||||
unsigned int count,
|
||||
snd_pcm_hw_strategy_simple_choices_list_t *choices);
|
||||
|
||||
#define SND_PCM_SW_PARAM_START_MODE 0
|
||||
#define SND_PCM_SW_PARAM_READY_MODE 1
|
||||
#define SND_PCM_SW_PARAM_XRUN_MODE 2
|
||||
#define SND_PCM_SW_PARAM_SILENCE_MODE 3
|
||||
#define SND_PCM_SW_PARAM_TSTAMP_MODE 4
|
||||
#define SND_PCM_SW_PARAM_AVAIL_MIN 5
|
||||
#define SND_PCM_SW_PARAM_XFER_ALIGN 6
|
||||
#define SND_PCM_SW_PARAM_SILENCE_THRESHOLD 7
|
||||
#define SND_PCM_SW_PARAM_SILENCE_SIZE 8
|
||||
#define SND_PCM_SW_PARAM_LAST 8
|
||||
typedef enum _snd_pcm_sw_param {
|
||||
SND_PCM_SW_PARAM_START_MODE,
|
||||
SND_PCM_SW_PARAM_XRUN_MODE,
|
||||
SND_PCM_SW_PARAM_TSTAMP_MODE,
|
||||
SND_PCM_SW_PARAM_PERIOD_STEP,
|
||||
SND_PCM_SW_PARAM_SLEEP_MIN,
|
||||
SND_PCM_SW_PARAM_AVAIL_MIN,
|
||||
SND_PCM_SW_PARAM_XFER_ALIGN,
|
||||
SND_PCM_SW_PARAM_SILENCE_THRESHOLD,
|
||||
SND_PCM_SW_PARAM_SILENCE_SIZE,
|
||||
SND_PCM_SW_PARAM_LAST = SND_PCM_SW_PARAM_SILENCE_SIZE,
|
||||
} snd_pcm_sw_param_t;
|
||||
|
||||
int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
|
||||
int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
|
||||
int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int var, unsigned int val);
|
||||
int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, unsigned int var);
|
||||
int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
|
||||
int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val);
|
||||
int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var);
|
||||
int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp);
|
||||
|
||||
/* mmap */
|
||||
const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm);
|
||||
const snd_pcm_channel_area_t *snd_pcm_mmap_running_areas(snd_pcm_t *pcm);
|
||||
const snd_pcm_channel_area_t *snd_pcm_mmap_stopped_areas(snd_pcm_t *pcm);
|
||||
ssize_t snd_pcm_mmap_forward(snd_pcm_t *pcm, size_t size);
|
||||
size_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
|
||||
size_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, size_t size);
|
||||
ssize_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, size_t size);
|
||||
ssize_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, size_t size);
|
||||
ssize_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, size_t size);
|
||||
ssize_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, size_t size);
|
||||
snd_pcm_sframes_t snd_pcm_mmap_forward(snd_pcm_t *pcm, snd_pcm_uframes_t size);
|
||||
snd_pcm_uframes_t snd_pcm_mmap_offset(snd_pcm_t *pcm);
|
||||
snd_pcm_uframes_t snd_pcm_mmap_xfer(snd_pcm_t *pcm, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
|
||||
|
||||
const char *snd_pcm_stream_name(unsigned int stream);
|
||||
const char *snd_pcm_hw_param_name(unsigned int params);
|
||||
const char *snd_pcm_sw_param_name(unsigned int params);
|
||||
const char *snd_pcm_access_name(unsigned int access);
|
||||
const char *snd_pcm_format_name(unsigned int format);
|
||||
const char *snd_pcm_subformat_name(unsigned int subformat);
|
||||
const char *snd_pcm_format_description(unsigned int format);
|
||||
const char *snd_pcm_stream_name(snd_pcm_stream_t stream);
|
||||
const char *snd_pcm_hw_param_name(snd_pcm_hw_param_t var);
|
||||
const char *snd_pcm_sw_param_name(snd_pcm_sw_param_t var);
|
||||
const char *snd_pcm_access_name(snd_pcm_access_t access);
|
||||
const char *snd_pcm_format_name(snd_pcm_format_t format);
|
||||
const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat);
|
||||
const char *snd_pcm_format_description(snd_pcm_format_t format);
|
||||
int snd_pcm_format_value(const char* name);
|
||||
const char *snd_pcm_start_mode_name(unsigned int mode);
|
||||
const char *snd_pcm_ready_mode_name(unsigned int mode);
|
||||
const char *snd_pcm_xrun_mode_name(unsigned int mode);
|
||||
const char *snd_pcm_silence_mode_name(unsigned int mode);
|
||||
const char *snd_pcm_tstamp_mode_name(unsigned int mode);
|
||||
const char *snd_pcm_state_name(unsigned int state);
|
||||
const char *snd_pcm_start_mode_name(snd_pcm_start_t mode);
|
||||
const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode);
|
||||
const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode);
|
||||
const char *snd_pcm_state_name(snd_pcm_state_t state);
|
||||
|
||||
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
|
||||
size_t samples, int format);
|
||||
int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
|
||||
size_t vcount, size_t frames, int format);
|
||||
int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset,
|
||||
const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
|
||||
size_t samples, int format);
|
||||
int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, size_t src_offset,
|
||||
const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
|
||||
size_t channels, size_t frames, int format);
|
||||
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
|
||||
unsigned int samples, int format);
|
||||
int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames, int format);
|
||||
int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset,
|
||||
const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset,
|
||||
unsigned int samples, int format);
|
||||
int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset,
|
||||
const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset,
|
||||
unsigned int channels, snd_pcm_uframes_t frames, int format);
|
||||
|
||||
ssize_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
|
||||
ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, ssize_t frames);
|
||||
ssize_t snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
|
||||
ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, ssize_t samples);
|
||||
snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
|
||||
ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
|
||||
int snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes);
|
||||
ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples);
|
||||
|
||||
|
||||
/* misc */
|
||||
|
|
@ -259,7 +270,7 @@ u_int8_t snd_pcm_format_silence(int format);
|
|||
u_int16_t snd_pcm_format_silence_16(int format);
|
||||
u_int32_t snd_pcm_format_silence_32(int format);
|
||||
u_int64_t snd_pcm_format_silence_64(int format);
|
||||
ssize_t snd_pcm_format_set_silence(int format, void *buf, size_t count);
|
||||
int snd_pcm_format_set_silence(int format, void *buf, unsigned int samples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
166
src/pcm/pcm.c
166
src/pcm/pcm.c
|
|
@ -106,7 +106,7 @@ int snd_pcm_state(snd_pcm_t *pcm)
|
|||
return pcm->fast_ops->state(pcm->fast_op_arg);
|
||||
}
|
||||
|
||||
int snd_pcm_delay(snd_pcm_t *pcm, ssize_t *delayp)
|
||||
int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(pcm->setup);
|
||||
|
|
@ -156,7 +156,7 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
|
|||
}
|
||||
|
||||
|
||||
ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
|
||||
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(pcm->setup);
|
||||
|
|
@ -164,7 +164,7 @@ ssize_t snd_pcm_rewind(snd_pcm_t *pcm, size_t frames)
|
|||
return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
|
||||
snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(size == 0 || buffer);
|
||||
|
|
@ -173,7 +173,7 @@ ssize_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, size_t size)
|
|||
return _snd_pcm_writei(pcm, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
|
||||
snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(size == 0 || bufs);
|
||||
|
|
@ -182,7 +182,7 @@ ssize_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, size_t size)
|
|||
return _snd_pcm_writen(pcm, bufs, size);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
|
||||
snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(size == 0 || buffer);
|
||||
|
|
@ -191,7 +191,7 @@ ssize_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, size_t size)
|
|||
return _snd_pcm_readi(pcm, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
|
||||
snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
assert(pcm);
|
||||
assert(size == 0 || bufs);
|
||||
|
|
@ -200,7 +200,7 @@ ssize_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, size_t size)
|
|||
return _snd_pcm_readn(pcm, bufs, size);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
|
||||
snd_pcm_sframes_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
|
||||
{
|
||||
void **bufs;
|
||||
int k;
|
||||
|
|
@ -215,7 +215,7 @@ ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, int count)
|
|||
return snd_pcm_writen(pcm, bufs, vector[0].iov_len);
|
||||
}
|
||||
|
||||
ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
|
||||
snd_pcm_sframes_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, int count)
|
||||
{
|
||||
void **bufs;
|
||||
int k;
|
||||
|
|
@ -310,25 +310,26 @@ char *snd_pcm_hw_param_names[] = {
|
|||
HW_PARAM(ACCESS),
|
||||
HW_PARAM(FORMAT),
|
||||
HW_PARAM(SUBFORMAT),
|
||||
HW_PARAM(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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) | \
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
1462
src/pcm/pcm_params.c
1462
src/pcm/pcm_params.c
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue