Promoted plugin helpers to general use

This commit is contained in:
Abramo Bagnara 2001-01-26 09:56:30 +00:00
parent 406587a531
commit c07201926b
9 changed files with 272 additions and 236 deletions

View file

@ -51,17 +51,12 @@ IMA compatability project proceedings, Vol 2, Issue 2, May 1992.
#include "pcm_local.h" #include "pcm_local.h"
#include "pcm_plugin.h" #include "pcm_plugin.h"
typedef struct {
int pred_val; /* Calculated predicted value */
int step_idx; /* Previous StepSize lookup index */
} adpcm_state_t;
typedef void (*adpcm_f)(const snd_pcm_channel_area_t *src_areas, typedef void (*adpcm_f)(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int getputidx, unsigned int channels, snd_pcm_uframes_t frames, int getputidx,
adpcm_state_t *states); snd_pcm_adpcm_state_t *states);
typedef struct { typedef struct {
/* This field need to be the first */ /* This field need to be the first */
@ -69,7 +64,7 @@ typedef struct {
int getput_idx; int getput_idx;
adpcm_f func; adpcm_f func;
int sformat; int sformat;
adpcm_state_t *states; snd_pcm_adpcm_state_t *states;
} snd_pcm_adpcm_t; } snd_pcm_adpcm_t;
/* First table lookup for Ima-ADPCM quantizer */ /* First table lookup for Ima-ADPCM quantizer */
@ -88,7 +83,7 @@ static short StepSize[89] = {
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
}; };
static char adpcm_encoder(int sl, adpcm_state_t * state) static char adpcm_encoder(int sl, snd_pcm_adpcm_state_t * state)
{ {
short diff; /* Difference between sl and predicted sample */ short diff; /* Difference between sl and predicted sample */
short pred_diff; /* Predicted difference to next sample */ short pred_diff; /* Predicted difference to next sample */
@ -149,7 +144,7 @@ static char adpcm_encoder(int sl, adpcm_state_t * state)
} }
static int adpcm_decoder(unsigned char code, adpcm_state_t * state) static int adpcm_decoder(unsigned char code, snd_pcm_adpcm_state_t * state)
{ {
short pred_diff; /* Predicted difference to next sample */ short pred_diff; /* Predicted difference to next sample */
short step; /* holds previous StepSize value */ short step; /* holds previous StepSize value */
@ -195,12 +190,12 @@ static int adpcm_decoder(unsigned char code, adpcm_state_t * state)
return (state->pred_val); return (state->pred_val);
} }
static void adpcm_decode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_adpcm_decode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int putidx, unsigned int channels, snd_pcm_uframes_t frames, int putidx,
adpcm_state_t *states) snd_pcm_adpcm_state_t *states)
{ {
#define PUT16_LABELS #define PUT16_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -256,12 +251,12 @@ static void adpcm_decode(const snd_pcm_channel_area_t *src_areas,
} }
} }
static void adpcm_encode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_adpcm_encode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int getidx, unsigned int channels, snd_pcm_uframes_t frames, int getidx,
adpcm_state_t *states) snd_pcm_adpcm_state_t *states)
{ {
#define GET16_LABELS #define GET16_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -422,19 +417,19 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) { if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
adpcm->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16); adpcm->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
adpcm->func = adpcm_encode; adpcm->func = snd_pcm_adpcm_encode;
} else { } else {
adpcm->getput_idx = put_index(SND_PCM_FORMAT_S16, adpcm->sformat); adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
adpcm->func = adpcm_decode; adpcm->func = snd_pcm_adpcm_decode;
} }
} else { } else {
if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) { 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, 0)); adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
adpcm->func = adpcm_decode; adpcm->func = snd_pcm_adpcm_decode;
} else { } else {
adpcm->getput_idx = get_index(adpcm->sformat, SND_PCM_FORMAT_S16); adpcm->getput_idx = snd_pcm_linear_get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
adpcm->func = adpcm_encode; adpcm->func = snd_pcm_adpcm_encode;
} }
} }
assert(!adpcm->states); assert(!adpcm->states);

View file

@ -120,11 +120,11 @@ static int alaw_to_s16(unsigned char a_val)
return ((a_val & 0x80) ? t : -t); return ((a_val & 0x80) ? t : -t);
} }
static void alaw_decode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_alaw_decode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int putidx) unsigned int channels, snd_pcm_uframes_t frames, int putidx)
{ {
#define PUT16_LABELS #define PUT16_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -165,7 +165,7 @@ static void alaw_decode(const snd_pcm_channel_area_t *src_areas,
} }
} }
static void alaw_encode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_alaw_encode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
@ -315,19 +315,19 @@ static int snd_pcm_alaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) { if (alaw->sformat == SND_PCM_FORMAT_A_LAW) {
alaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16); alaw->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
alaw->func = alaw_encode; alaw->func = snd_pcm_alaw_encode;
} else { } else {
alaw->getput_idx = put_index(SND_PCM_FORMAT_S16, alaw->sformat); alaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, alaw->sformat);
alaw->func = alaw_decode; alaw->func = snd_pcm_alaw_decode;
} }
} else { } else {
if (alaw->sformat == SND_PCM_FORMAT_A_LAW) { 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, 0)); alaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
alaw->func = alaw_decode; alaw->func = snd_pcm_alaw_decode;
} else { } else {
alaw->getput_idx = get_index(alaw->sformat, SND_PCM_FORMAT_S16); alaw->getput_idx = snd_pcm_linear_get_index(alaw->sformat, SND_PCM_FORMAT_S16);
alaw->func = alaw_encode; alaw->func = snd_pcm_alaw_encode;
} }
} }
return 0; return 0;

View file

@ -30,7 +30,64 @@ typedef struct {
int sformat; int sformat;
} snd_pcm_linear_t; } snd_pcm_linear_t;
static void linear_transfer(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset, int snd_pcm_linear_convert_index(int src_format, int dst_format)
{
int src_endian, dst_endian, sign, src_width, dst_width;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
#ifdef SND_LITTLE_ENDIAN
src_endian = snd_pcm_format_big_endian(src_format);
dst_endian = snd_pcm_format_big_endian(dst_format);
#else
src_endian = snd_pcm_format_little_endian(src_format);
dst_endian = snd_pcm_format_little_endian(dst_format);
#endif
if (src_endian < 0)
src_endian = 0;
if (dst_endian < 0)
dst_endian = 0;
src_width = snd_pcm_format_width(src_format) / 8 - 1;
dst_width = snd_pcm_format_width(dst_format) / 8 - 1;
return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
}
int snd_pcm_linear_get_index(int src_format, int dst_format)
{
int sign, width, endian;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
width = snd_pcm_format_width(src_format) / 8 - 1;
#ifdef SND_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(src_format);
#else
endian = snd_pcm_format_little_endian(src_format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
}
int snd_pcm_linear_put_index(int src_format, int dst_format)
{
int sign, width, endian;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
width = snd_pcm_format_width(dst_format) / 8 - 1;
#ifdef SND_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(dst_format);
#else
endian = snd_pcm_format_little_endian(dst_format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
}
void snd_pcm_linear_convert(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, const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int convidx) unsigned int channels, snd_pcm_uframes_t frames, int convidx)
{ {
@ -167,11 +224,11 @@ static int snd_pcm_linear_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
if (err < 0) if (err < 0)
return err; return err;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
linear->conv_idx = conv_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), linear->conv_idx = snd_pcm_linear_convert_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0),
linear->sformat); linear->sformat);
else else
linear->conv_idx = conv_index(linear->sformat, linear->conv_idx = snd_pcm_linear_convert_index(linear->sformat,
snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0)); snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
return 0; return 0;
} }
@ -190,9 +247,9 @@ static snd_pcm_sframes_t snd_pcm_linear_write_areas(snd_pcm_t *pcm,
assert(size > 0); assert(size > 0);
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_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_linear_convert(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
pcm->channels, frames, linear->conv_idx); pcm->channels, frames, linear->conv_idx);
err = snd_pcm_mmap_forward(slave, frames); err = snd_pcm_mmap_forward(slave, frames);
if (err < 0) if (err < 0)
break; break;
@ -224,9 +281,9 @@ static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm,
assert(size > 0); assert(size > 0);
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_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), snd_pcm_linear_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset, areas, offset,
pcm->channels, frames, linear->conv_idx); pcm->channels, frames, linear->conv_idx);
err = snd_pcm_mmap_forward(slave, frames); err = snd_pcm_mmap_forward(slave, frames);
if (err < 0) if (err < 0)
break; break;

View file

@ -137,11 +137,11 @@ static int ulaw_to_s16(unsigned char u_val)
return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84)); return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
} }
static void mulaw_decode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_mulaw_decode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int putidx) unsigned int channels, snd_pcm_uframes_t frames, int putidx)
{ {
#define PUT16_LABELS #define PUT16_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -182,11 +182,11 @@ static void mulaw_decode(const snd_pcm_channel_area_t *src_areas,
} }
} }
static void mulaw_encode(const snd_pcm_channel_area_t *src_areas, void snd_pcm_mulaw_encode(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
unsigned int channels, snd_pcm_uframes_t frames, int getidx) unsigned int channels, snd_pcm_uframes_t frames, int getidx)
{ {
#define GET16_LABELS #define GET16_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -330,19 +330,19 @@ static int snd_pcm_mulaw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) { if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) {
mulaw->getput_idx = get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16); mulaw->getput_idx = snd_pcm_linear_get_index(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0), SND_PCM_FORMAT_S16);
mulaw->func = mulaw_encode; mulaw->func = snd_pcm_mulaw_encode;
} else { } else {
mulaw->getput_idx = put_index(SND_PCM_FORMAT_S16, mulaw->sformat); mulaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, mulaw->sformat);
mulaw->func = mulaw_decode; mulaw->func = snd_pcm_mulaw_decode;
} }
} else { } else {
if (mulaw->sformat == SND_PCM_FORMAT_MU_LAW) { 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, 0)); mulaw->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0));
mulaw->func = mulaw_decode; mulaw->func = snd_pcm_mulaw_decode;
} else { } else {
mulaw->getput_idx = get_index(mulaw->sformat, SND_PCM_FORMAT_S16); mulaw->getput_idx = snd_pcm_linear_get_index(mulaw->sformat, SND_PCM_FORMAT_S16);
mulaw->func = mulaw_encode; mulaw->func = snd_pcm_mulaw_encode;
} }
} }
return 0; return 0;

View file

@ -27,7 +27,7 @@ typedef struct {
snd_pcm_t *req_slave; snd_pcm_t *req_slave;
int close_slave; int close_slave;
snd_pcm_t *slave; snd_pcm_t *slave;
ttable_entry_t *ttable; snd_pcm_route_ttable_entry_t *ttable;
unsigned int tt_ssize, tt_cused, tt_sused; unsigned int tt_ssize, tt_cused, tt_sused;
} snd_pcm_plug_t; } snd_pcm_plug_t;
@ -229,7 +229,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
{ {
snd_pcm_plug_t *plug = pcm->private; snd_pcm_plug_t *plug = pcm->private;
unsigned int tt_ssize, tt_cused, tt_sused; unsigned int tt_ssize, tt_cused, tt_sused;
ttable_entry_t *ttable; snd_pcm_route_ttable_entry_t *ttable;
int err; int err;
assert(snd_pcm_format_linear(slv->format)); assert(snd_pcm_format_linear(slv->format));
if (clt->channels == slv->channels) if (clt->channels == slv->channels)
@ -259,7 +259,7 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
n = slv->channels; n = slv->channels;
} }
while (n-- > 0) { while (n-- > 0) {
ttable_entry_t v = FULL; snd_pcm_route_ttable_entry_t v = FULL;
if (pcm->stream == SND_PCM_STREAM_PLAYBACK && if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
clt->channels > slv->channels) { clt->channels > slv->channels) {
int srcs = clt->channels / slv->channels; int srcs = clt->channels / slv->channels;
@ -656,7 +656,7 @@ snd_pcm_ops_t snd_pcm_plug_ops = {
int snd_pcm_plug_open(snd_pcm_t **pcmp, int snd_pcm_plug_open(snd_pcm_t **pcmp,
char *name, char *name,
ttable_entry_t *ttable, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_ssize, unsigned int tt_ssize,
unsigned int tt_cused, unsigned int tt_sused, unsigned int tt_cused, unsigned int tt_sused,
snd_pcm_t *slave, int close_slave) snd_pcm_t *slave, int close_slave)
@ -718,7 +718,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, char *name,
int err; int err;
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *tt = NULL; snd_config_t *tt = NULL;
ttable_entry_t *ttable = NULL; snd_pcm_route_ttable_entry_t *ttable = NULL;
unsigned int cused, sused; unsigned int cused, sused;
snd_config_foreach(i, conf) { snd_config_foreach(i, conf) {
snd_config_t *n = snd_config_entry(i); snd_config_t *n = snd_config_entry(i);

View file

@ -358,63 +358,6 @@ int snd_pcm_plugin_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
return snd_pcm_hw_params(plugin->slave, params); return snd_pcm_hw_params(plugin->slave, params);
} }
int conv_index(int src_format, int dst_format)
{
int src_endian, dst_endian, sign, src_width, dst_width;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
#ifdef SND_LITTLE_ENDIAN
src_endian = snd_pcm_format_big_endian(src_format);
dst_endian = snd_pcm_format_big_endian(dst_format);
#else
src_endian = snd_pcm_format_little_endian(src_format);
dst_endian = snd_pcm_format_little_endian(dst_format);
#endif
if (src_endian < 0)
src_endian = 0;
if (dst_endian < 0)
dst_endian = 0;
src_width = snd_pcm_format_width(src_format) / 8 - 1;
dst_width = snd_pcm_format_width(dst_format) / 8 - 1;
return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
}
int get_index(int src_format, int dst_format)
{
int sign, width, endian;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
width = snd_pcm_format_width(src_format) / 8 - 1;
#ifdef SND_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(src_format);
#else
endian = snd_pcm_format_little_endian(src_format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
}
int put_index(int src_format, int dst_format)
{
int sign, width, endian;
sign = (snd_pcm_format_signed(src_format) !=
snd_pcm_format_signed(dst_format));
width = snd_pcm_format_width(dst_format) / 8 - 1;
#ifdef SND_LITTLE_ENDIAN
endian = snd_pcm_format_big_endian(dst_format);
#else
endian = snd_pcm_format_little_endian(dst_format);
#endif
if (endian < 0)
endian = 0;
return width * 4 + endian * 2 + sign;
}
snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = { snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
status: snd_pcm_plugin_status, status: snd_pcm_plugin_status,
state: snd_pcm_plugin_state, state: snd_pcm_plugin_state,

View file

@ -62,9 +62,6 @@ int snd_pcm_plugin_munmap_status(snd_pcm_t *pcm);
int snd_pcm_plugin_munmap_control(snd_pcm_t *pcm); int snd_pcm_plugin_munmap_control(snd_pcm_t *pcm);
int snd_pcm_plugin_munmap(snd_pcm_t *pcm); int snd_pcm_plugin_munmap(snd_pcm_t *pcm);
int snd_pcm_plugin_poll_descriptor(snd_pcm_t *pcm); int snd_pcm_plugin_poll_descriptor(snd_pcm_t *pcm);
int get_index(int src_format, int dst_format);
int put_index(int src_format, int dst_format);
int conv_index(int src_format, int dst_format);
int snd_pcm_plugin_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); int snd_pcm_plugin_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); int snd_pcm_plugin_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
@ -86,27 +83,30 @@ extern snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
#define ROUTE_PLUGIN_RESOLUTION 16 #define ROUTE_PLUGIN_RESOLUTION 16
#if ROUTE_PLUGIN_FLOAT #if ROUTE_PLUGIN_FLOAT
typedef float ttable_entry_t; typedef float snd_pcm_route_ttable_entry_t;
#define HALF 0.5 #define HALF 0.5
#define FULL 1.0 #define FULL 1.0
#else #else
typedef int ttable_entry_t; typedef int snd_pcm_route_ttable_entry_t;
#define HALF (ROUTE_PLUGIN_RESOLUTION / 2) #define HALF (ROUTE_PLUGIN_RESOLUTION / 2)
#define FULL ROUTE_PLUGIN_RESOLUTION #define FULL ROUTE_PLUGIN_RESOLUTION
#endif #endif
int snd_pcm_linear_get_index(int src_format, int dst_format);
int snd_pcm_linear_put_index(int src_format, int dst_format);
int snd_pcm_linear_convert_index(int src_format, int dst_format);
int snd_pcm_copy_open(snd_pcm_t **pcmp, char *name, snd_pcm_t *slave, int close_slave); int snd_pcm_copy_open(snd_pcm_t **pcmp, char *name, snd_pcm_t *slave, int close_slave);
int snd_pcm_linear_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave); int snd_pcm_linear_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_mulaw_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave); int snd_pcm_mulaw_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_alaw_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave); int snd_pcm_alaw_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_adpcm_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave); int snd_pcm_adpcm_open(snd_pcm_t **pcmp, char *name, int sformat, snd_pcm_t *slave, int close_slave);
int snd_pcm_route_load_ttable(snd_config_t *tt, ttable_entry_t *ttable, int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_csize, unsigned int tt_ssize, unsigned int tt_csize, unsigned int tt_ssize,
unsigned int *tt_cused, unsigned int *tt_sused, unsigned int *tt_cused, unsigned int *tt_sused,
int schannels); int schannels);
int snd_pcm_route_open(snd_pcm_t **pcmp, char *name, int snd_pcm_route_open(snd_pcm_t **pcmp, char *name,
int sformat, unsigned int schannels, int sformat, unsigned int schannels,
ttable_entry_t *ttable, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_ssize, unsigned int tt_ssize,
unsigned int tt_cused, unsigned int tt_sused, unsigned int tt_cused, unsigned int tt_sused,
snd_pcm_t *slave, int close_slave); snd_pcm_t *slave, int close_slave);
@ -118,3 +118,44 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp, char *name, int sformat, int srate, snd_
(1 << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \ (1 << SND_PCM_ACCESS_MMAP_NONINTERLEAVED) | \
(1 << SND_PCM_ACCESS_RW_NONINTERLEAVED)) (1 << SND_PCM_ACCESS_RW_NONINTERLEAVED))
void snd_pcm_linear_convert(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);
void snd_pcm_alaw_decode(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 putidx);
void snd_pcm_alaw_encode(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 getidx);
void snd_pcm_mulaw_decode(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 putidx);
void snd_pcm_mulaw_encode(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 getidx);
typedef struct _snd_pcm_adpcm_state {
int pred_val; /* Calculated predicted value */
int step_idx; /* Previous StepSize lookup index */
} snd_pcm_adpcm_state_t;
void snd_pcm_adpcm_decode(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 putidx,
snd_pcm_adpcm_state_t *states);
void snd_pcm_adpcm_encode(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 getidx,
snd_pcm_adpcm_state_t *states);

View file

@ -31,7 +31,7 @@ typedef struct {
int16_t sample; int16_t sample;
int sum; int sum;
unsigned int pos; unsigned int pos;
} rate_state_t; } snd_pcm_rate_state_t;
typedef snd_pcm_uframes_t (*rate_f)(const snd_pcm_channel_area_t *src_areas, 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, snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
@ -40,7 +40,7 @@ typedef snd_pcm_uframes_t (*rate_f)(const snd_pcm_channel_area_t *src_areas,
unsigned int channels, unsigned int channels,
int getidx, int putidx, int getidx, int putidx,
unsigned int arg, unsigned int arg,
rate_state_t *states); snd_pcm_rate_state_t *states);
typedef struct { typedef struct {
/* This field need to be the first */ /* This field need to be the first */
@ -51,17 +51,17 @@ typedef struct {
rate_f func; rate_f func;
int sformat; int sformat;
int srate; int srate;
rate_state_t *states; snd_pcm_rate_state_t *states;
} snd_pcm_rate_t; } snd_pcm_rate_t;
static snd_pcm_uframes_t resample_expand(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t snd_pcm_rate_expand(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames, snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp, snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
unsigned int channels, unsigned int channels,
int getidx, int putidx, int getidx, int putidx,
unsigned int get_threshold, unsigned int get_threshold,
rate_state_t *states) snd_pcm_rate_state_t *states)
{ {
#define GET16_LABELS #define GET16_LABELS
#define PUT16_LABELS #define PUT16_LABELS
@ -136,14 +136,14 @@ static snd_pcm_uframes_t resample_expand(const snd_pcm_channel_area_t *src_areas
return src_frames1; return src_frames1;
} }
static snd_pcm_uframes_t resample_shrink(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t snd_pcm_rate_shrink(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames, snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_frames,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp, snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t *dst_framesp,
unsigned int channels, unsigned int channels,
int getidx, int putidx, int getidx, int putidx,
unsigned int get_increment, unsigned int get_increment,
rate_state_t *states) snd_pcm_rate_state_t *states)
{ {
#define GET16_LABELS #define GET16_LABELS
#define PUT16_LABELS #define PUT16_LABELS
@ -367,13 +367,13 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
src_rate = slave->rate; src_rate = slave->rate;
dst_rate = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0); 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->get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_S16);
rate->put_idx = put_index(SND_PCM_FORMAT_S16, dst_format); rate->put_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, dst_format);
if (src_rate < dst_rate) { if (src_rate < dst_rate) {
rate->func = resample_expand; rate->func = snd_pcm_rate_expand;
/* pitch is get_threshold */ /* pitch is get_threshold */
} else { } else {
rate->func = resample_shrink; rate->func = snd_pcm_rate_shrink;
/* pitch is get_increment */ /* pitch is get_increment */
} }
rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate; rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate;
@ -412,7 +412,7 @@ static int snd_pcm_rate_init(snd_pcm_t *pcm)
for (k = 0; k < pcm->channels; ++k) { for (k = 0; k < pcm->channels; ++k) {
rate->states[k].sum = 0; rate->states[k].sum = 0;
rate->states[k].sample = 0; rate->states[k].sample = 0;
if (rate->func == resample_expand) { if (rate->func == snd_pcm_rate_expand) {
/* Get a sample on entry */ /* Get a sample on entry */
rate->states[k].pos = rate->pitch + DIV; rate->states[k].pos = rate->pitch + DIV;
} else { } else {

View file

@ -39,9 +39,9 @@ typedef struct {
#if ROUTE_PLUGIN_FLOAT #if ROUTE_PLUGIN_FLOAT
float as_float; float as_float;
#endif #endif
} ttable_src_t; } snd_pcm_route_ttable_src_t;
typedef struct ttable_dst ttable_dst_t; typedef struct snd_pcm_route_ttable_dst snd_pcm_route_ttable_dst_t;
typedef struct { typedef struct {
enum {UINT32=0, UINT64=1, FLOAT=2} sum_idx; enum {UINT32=0, UINT64=1, FLOAT=2} sum_idx;
@ -51,8 +51,8 @@ typedef struct {
int src_size; int src_size;
int dst_sfmt; int dst_sfmt;
unsigned int ndsts; unsigned int ndsts;
ttable_dst_t *dsts; snd_pcm_route_ttable_dst_t *dsts;
} route_params_t; } snd_pcm_route_params_t;
typedef void (*route_f)(const snd_pcm_channel_area_t *src_areas, typedef void (*route_f)(const snd_pcm_channel_area_t *src_areas,
@ -60,13 +60,13 @@ typedef void (*route_f)(const snd_pcm_channel_area_t *src_areas,
const snd_pcm_channel_area_t *dst_area, const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
snd_pcm_uframes_t frames, snd_pcm_uframes_t frames,
const ttable_dst_t *ttable, const snd_pcm_route_ttable_dst_t *ttable,
const route_params_t *params); const snd_pcm_route_params_t *params);
struct ttable_dst { struct snd_pcm_route_ttable_dst {
int att; /* Attenuated */ int att; /* Attenuated */
unsigned int nsrcs; unsigned int nsrcs;
ttable_src_t* srcs; snd_pcm_route_ttable_src_t* srcs;
route_f func; route_f func;
}; };
@ -83,17 +83,17 @@ typedef struct {
snd_pcm_plugin_t plug; snd_pcm_plugin_t plug;
int sformat; int sformat;
int schannels; int schannels;
route_params_t params; snd_pcm_route_params_t params;
} snd_pcm_route_t; } snd_pcm_route_t;
static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED, void snd_pcm_route_convert1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED,
snd_pcm_uframes_t src_offset ATTRIBUTE_UNUSED, snd_pcm_uframes_t src_offset ATTRIBUTE_UNUSED,
const snd_pcm_channel_area_t *dst_area, const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
snd_pcm_uframes_t frames, snd_pcm_uframes_t frames,
const ttable_dst_t* ttable ATTRIBUTE_UNUSED, const snd_pcm_route_ttable_dst_t* ttable ATTRIBUTE_UNUSED,
const route_params_t *params) const snd_pcm_route_params_t *params)
{ {
#if 0 #if 0
if (dst_area->wanted) if (dst_area->wanted)
@ -104,13 +104,13 @@ static void route1_zero(const snd_pcm_channel_area_t *src_areas ATTRIBUTE_UNUSED
#endif #endif
} }
static void route1_one(const snd_pcm_channel_area_t *src_areas, void snd_pcm_route_convert1_one(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_area, const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
snd_pcm_uframes_t frames, snd_pcm_uframes_t frames,
const ttable_dst_t* ttable, const snd_pcm_route_ttable_dst_t* ttable,
const route_params_t *params) const snd_pcm_route_params_t *params)
{ {
#define CONV_LABELS #define CONV_LABELS
#include "plugin_ops.h" #include "plugin_ops.h"
@ -126,7 +126,7 @@ static void route1_one(const snd_pcm_channel_area_t *src_areas,
break; break;
} }
if (srcidx == ttable->nsrcs) { if (srcidx == ttable->nsrcs) {
route1_zero(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params); snd_pcm_route_convert1_zero(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params);
return; return;
} }
@ -149,13 +149,13 @@ static void route1_one(const snd_pcm_channel_area_t *src_areas,
} }
} }
static void route1_many(const snd_pcm_channel_area_t *src_areas, void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_area, const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
snd_pcm_uframes_t frames, snd_pcm_uframes_t frames,
const ttable_dst_t* ttable, const snd_pcm_route_ttable_dst_t* ttable,
const route_params_t *params) const snd_pcm_route_params_t *params)
{ {
#define GET_LABELS #define GET_LABELS
#define PUT32_LABELS #define PUT32_LABELS
@ -208,7 +208,7 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
int dst_step; int dst_step;
char *srcs[nsrcs]; char *srcs[nsrcs];
int src_steps[nsrcs]; int src_steps[nsrcs];
ttable_src_t src_tt[nsrcs]; snd_pcm_route_ttable_src_t src_tt[nsrcs];
u_int32_t sample = 0; u_int32_t sample = 0;
int srcidx, srcidx1 = 0; int srcidx, srcidx1 = 0;
for (srcidx = 0; srcidx < nsrcs; ++srcidx) { for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
@ -224,10 +224,10 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
} }
nsrcs = srcidx1; nsrcs = srcidx1;
if (nsrcs == 0) { if (nsrcs == 0) {
route1_zero(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params); snd_pcm_route_convert1_zero(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params);
return; return;
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) { } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
route1_one(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params); snd_pcm_route_convert1_one(src_areas, src_offset, dst_area, dst_offset, frames, ttable, params);
return; return;
} }
@ -243,7 +243,7 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
dst_step = snd_pcm_channel_area_step(dst_area); dst_step = snd_pcm_channel_area_step(dst_area);
while (frames-- > 0) { while (frames-- > 0) {
ttable_src_t *ttp = src_tt; snd_pcm_route_ttable_src_t *ttp = src_tt;
sum_t sum; sum_t sum;
/* Zero sum */ /* Zero sum */
@ -382,23 +382,23 @@ static void route1_many(const snd_pcm_channel_area_t *src_areas,
} }
} }
static void route_transfer(const snd_pcm_channel_area_t *src_areas, void snd_pcm_route_convert(const snd_pcm_channel_area_t *src_areas,
snd_pcm_uframes_t src_offset, snd_pcm_uframes_t src_offset,
const snd_pcm_channel_area_t *dst_areas, const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
snd_pcm_uframes_t dst_channels, snd_pcm_uframes_t dst_channels,
snd_pcm_uframes_t frames, snd_pcm_uframes_t frames,
route_params_t *params) snd_pcm_route_params_t *params)
{ {
unsigned int dst_channel; unsigned int dst_channel;
ttable_dst_t *dstp; snd_pcm_route_ttable_dst_t *dstp;
const snd_pcm_channel_area_t *dst_area; const snd_pcm_channel_area_t *dst_area;
dstp = params->dsts; dstp = params->dsts;
dst_area = dst_areas; dst_area = dst_areas;
for (dst_channel = 0; dst_channel < dst_channels; ++dst_channel) { for (dst_channel = 0; dst_channel < dst_channels; ++dst_channel) {
if (dst_channel >= params->ndsts) if (dst_channel >= params->ndsts)
route1_zero(src_areas, src_offset, dst_area, dst_offset, frames, dstp, params); snd_pcm_route_convert1_zero(src_areas, src_offset, dst_area, dst_offset, frames, dstp, params);
else else
dstp->func(src_areas, src_offset, dst_area, dst_offset, frames, dstp, params); dstp->func(src_areas, src_offset, dst_area, dst_offset, frames, dstp, params);
dstp++; dstp++;
@ -409,7 +409,7 @@ static void route_transfer(const snd_pcm_channel_area_t *src_areas,
static int snd_pcm_route_close(snd_pcm_t *pcm) static int snd_pcm_route_close(snd_pcm_t *pcm)
{ {
snd_pcm_route_t *route = pcm->private; snd_pcm_route_t *route = pcm->private;
route_params_t *params = &route->params; snd_pcm_route_params_t *params = &route->params;
int err = 0; int err = 0;
unsigned int dst_channel; unsigned int dst_channel;
if (route->plug.close_slave) if (route->plug.close_slave)
@ -550,9 +550,9 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
src_format = slave->format; src_format = slave->format;
dst_format = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_FORMAT, 0); 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.get_idx = snd_pcm_linear_get_index(src_format, SND_PCM_FORMAT_U16);
route->params.put_idx = put_index(SND_PCM_FORMAT_U32, dst_format); route->params.put_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_U32, dst_format);
route->params.conv_idx = conv_index(src_format, dst_format); route->params.conv_idx = snd_pcm_linear_convert_index(src_format, dst_format);
route->params.src_size = snd_pcm_format_width(src_format) / 8; route->params.src_size = snd_pcm_format_width(src_format) / 8;
route->params.dst_sfmt = dst_format; route->params.dst_sfmt = dst_format;
#if ROUTE_PLUGIN_FLOAT #if ROUTE_PLUGIN_FLOAT
@ -567,10 +567,10 @@ static int snd_pcm_route_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
} }
static snd_pcm_sframes_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, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset, snd_pcm_uframes_t offset,
snd_pcm_uframes_t size, snd_pcm_uframes_t size,
snd_pcm_uframes_t *slave_sizep) snd_pcm_uframes_t *slave_sizep)
{ {
snd_pcm_route_t *route = pcm->private; snd_pcm_route_t *route = pcm->private;
snd_pcm_t *slave = route->plug.slave; snd_pcm_t *slave = route->plug.slave;
@ -581,9 +581,9 @@ static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
assert(size > 0); assert(size > 0);
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_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_route_convert(areas, offset,
snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave), snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
slave->channels, frames, &route->params); slave->channels, frames, &route->params);
err = snd_pcm_mmap_forward(slave, frames); err = snd_pcm_mmap_forward(slave, frames);
if (err < 0) if (err < 0)
break; break;
@ -601,10 +601,10 @@ static snd_pcm_sframes_t snd_pcm_route_write_areas(snd_pcm_t *pcm,
} }
static snd_pcm_sframes_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, const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset, snd_pcm_uframes_t offset,
snd_pcm_uframes_t size, snd_pcm_uframes_t size,
snd_pcm_uframes_t *slave_sizep) snd_pcm_uframes_t *slave_sizep)
{ {
snd_pcm_route_t *route = pcm->private; snd_pcm_route_t *route = pcm->private;
snd_pcm_t *slave = route->plug.slave; snd_pcm_t *slave = route->plug.slave;
@ -615,9 +615,9 @@ static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm,
assert(size > 0); assert(size > 0);
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_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), snd_pcm_route_convert(snd_pcm_mmap_areas(slave), snd_pcm_mmap_offset(slave),
areas, offset, areas, offset,
pcm->channels, frames, &route->params); pcm->channels, frames, &route->params);
err = snd_pcm_mmap_forward(slave, frames); err = snd_pcm_mmap_forward(slave, frames);
if (err < 0) if (err < 0)
break; break;
@ -645,14 +645,14 @@ static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_format_name(route->sformat)); snd_pcm_format_name(route->sformat));
snd_output_puts(out, "Transformation table:\n"); snd_output_puts(out, "Transformation table:\n");
for (dst = 0; dst < route->params.ndsts; dst++) { for (dst = 0; dst < route->params.ndsts; dst++) {
ttable_dst_t *d = &route->params.dsts[dst]; snd_pcm_route_ttable_dst_t *d = &route->params.dsts[dst];
unsigned int src; unsigned int src;
if (d->nsrcs == 0) if (d->nsrcs == 0)
continue; continue;
snd_output_printf(out, "%d <- ", dst); snd_output_printf(out, "%d <- ", dst);
src = 0; src = 0;
while (1) { while (1) {
ttable_src_t *s = &d->srcs[src]; snd_pcm_route_ttable_src_t *s = &d->srcs[src];
if (d->att) if (d->att)
snd_output_printf(out, "%d*%g", s->channel, s->as_float); snd_output_printf(out, "%d*%g", s->channel, s->as_float);
else else
@ -688,13 +688,13 @@ snd_pcm_ops_t snd_pcm_route_ops = {
munmap: snd_pcm_plugin_munmap, munmap: snd_pcm_plugin_munmap,
}; };
int route_load_ttable(route_params_t *params, int stream, int route_load_ttable(snd_pcm_route_params_t *params, int stream,
unsigned int tt_ssize, unsigned int tt_ssize,
ttable_entry_t *ttable, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_cused, unsigned int tt_sused) unsigned int tt_cused, unsigned int tt_sused)
{ {
unsigned int src_channel, dst_channel; unsigned int src_channel, dst_channel;
ttable_dst_t *dptr; snd_pcm_route_ttable_dst_t *dptr;
unsigned int sused, dused, smul, dmul; unsigned int sused, dused, smul, dmul;
if (stream == SND_PCM_STREAM_PLAYBACK) { if (stream == SND_PCM_STREAM_PLAYBACK) {
sused = tt_cused; sused = tt_cused;
@ -713,12 +713,12 @@ int route_load_ttable(route_params_t *params, int stream,
return -ENOMEM; return -ENOMEM;
params->dsts = dptr; params->dsts = dptr;
for (dst_channel = 0; dst_channel < dused; ++dst_channel) { for (dst_channel = 0; dst_channel < dused; ++dst_channel) {
ttable_entry_t t = 0; snd_pcm_route_ttable_entry_t t = 0;
int att = 0; int att = 0;
int nsrcs = 0; int nsrcs = 0;
ttable_src_t srcs[sused]; snd_pcm_route_ttable_src_t srcs[sused];
for (src_channel = 0; src_channel < sused; ++src_channel) { for (src_channel = 0; src_channel < sused; ++src_channel) {
ttable_entry_t v; snd_pcm_route_ttable_entry_t v;
v = ttable[src_channel * smul + dst_channel * dmul]; v = ttable[src_channel * smul + dst_channel * dmul];
assert(v >= 0 && v <= FULL); assert(v >= 0 && v <= FULL);
if (v != 0) { if (v != 0) {
@ -742,11 +742,11 @@ int route_load_ttable(route_params_t *params, int stream,
dptr->att = att; dptr->att = att;
dptr->nsrcs = nsrcs; dptr->nsrcs = nsrcs;
if (nsrcs == 0) if (nsrcs == 0)
dptr->func = route1_zero; dptr->func = snd_pcm_route_convert1_zero;
else if (nsrcs == 1 && !att) else if (nsrcs == 1 && !att)
dptr->func = route1_one; dptr->func = snd_pcm_route_convert1_one;
else else
dptr->func = route1_many; dptr->func = snd_pcm_route_convert1_many;
if (nsrcs > 0) { if (nsrcs > 0) {
dptr->srcs = calloc(nsrcs, sizeof(*srcs)); dptr->srcs = calloc(nsrcs, sizeof(*srcs));
if (!dptr->srcs) if (!dptr->srcs)
@ -762,7 +762,7 @@ int route_load_ttable(route_params_t *params, int stream,
int snd_pcm_route_open(snd_pcm_t **pcmp, char *name, int snd_pcm_route_open(snd_pcm_t **pcmp, char *name,
int sformat, unsigned int schannels, int sformat, unsigned int schannels,
ttable_entry_t *ttable, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_ssize, unsigned int tt_ssize,
unsigned int tt_cused, unsigned int tt_sused, unsigned int tt_cused, unsigned int tt_sused,
snd_pcm_t *slave, int close_slave) snd_pcm_t *slave, int close_slave)
@ -812,7 +812,7 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, char *name,
return 0; return 0;
} }
int snd_pcm_route_load_ttable(snd_config_t *tt, ttable_entry_t *ttable, int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_csize, unsigned int tt_ssize, unsigned int tt_csize, unsigned int tt_ssize,
unsigned int *tt_cused, unsigned int *tt_sused, unsigned int *tt_cused, unsigned int *tt_sused,
int schannels) int schannels)
@ -885,7 +885,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, char *name,
int sformat = -1; int sformat = -1;
long schannels = -1; long schannels = -1;
snd_config_t *tt = NULL; snd_config_t *tt = NULL;
ttable_entry_t ttable[MAX_CHANNELS*MAX_CHANNELS]; snd_pcm_route_ttable_entry_t ttable[MAX_CHANNELS*MAX_CHANNELS];
unsigned int cused, sused; unsigned int cused, sused;
snd_config_foreach(i, conf) { snd_config_foreach(i, conf) {
snd_config_t *n = snd_config_entry(i); snd_config_t *n = snd_config_entry(i);