At Sun, 23 Jun 2013 01:25:19 +0100, alex.d.wiggins@gmail.com wrote:
From: Alex Wiggins alex.d.wiggins@gmail.com
Added 4 user variables to control the OSS period and buffer config:
- period_size_allowany (boolean): if not set then queries OSS for period size (by using SNDCTL_DSP_GETBLKSIZE), if set to true then allows any power of 2 period size;
I'd suggest to put an underscore between "allow" and "any". Or, instead of adding a flag...
- period_size (integer): sets the OSS period size (SND_PCM_IOPLUG_HW_PERIOD_BYTES);
... handle allowany when period_size < 0, for example.
Takashi
periods (integer): sets the number of OSS periods (SND_PCM_IOPLUG_HW_PERIODS);
buffer_size (integer): sets the OSS buffer size (SND_PCM_IOPLUG_HW_BUFFER_BYTES).
Note that ALSA performs sanity checks to prevent conflicts.
Signed-off-by: Alex Wiggins alex.d.wiggins@gmail.com
diff --git a/oss/pcm_oss.c b/oss/pcm_oss.c index 6d8dea4..7131e54 100644 --- a/oss/pcm_oss.c +++ b/oss/pcm_oss.c @@ -60,6 +60,13 @@ typedef struct snd_pcm_oss { unsigned int period_shift; unsigned int periods; unsigned int frame_bytes;
- /* user variables set using ALSA config files */
- /* included here as this snd_pcm_oss_t struct
is stored in io->private_data */
- int user_period_size_allowany;
- long int user_period_size;
- long int user_periods;
- long int user_buffer_size;
} snd_pcm_oss_t;
static snd_pcm_sframes_t oss_write(snd_pcm_ioplug_t *io, @@ -406,6 +413,7 @@ static int oss_hw_constraint(snd_pcm_oss_t *oss) unsigned int nchannels; unsigned int channel[6]; /* period and buffer bytes must be power of two */
- /* minimum: 2^8 = 256; maximum: 2^23 = 8388608 */ static const unsigned int bytes_list[] = { 1U<<8, 1U<<9, 1U<<10, 1U<<11, 1U<<12, 1U<<13, 1U<<14, 1U<<15, 1U<<16, 1U<<17, 1U<<18, 1U<<19, 1U<<20, 1U<<21, 1U<<22, 1U<<23
@@ -498,20 +506,96 @@ static int oss_hw_constraint(snd_pcm_oss_t *oss) if (err < 0) return err;
- /* period size (in power of two) */
- err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
ARRAY_SIZE(bytes_list), bytes_list);
- if (err < 0)
return err;
- /* periods */
- err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 1024);
- if (err < 0)
return err;
- /* buffer size (in power of two) */
- err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES,
ARRAY_SIZE(bytes_list), bytes_list);
- if (err < 0)
return err;
- /* period and buffer sizes: default behaviour below is to
query period size from OSS */
- /* consider user set paramaters
(period_size_allowany; period_size; periods; buffer_size) */
- /* note: ALSA performs sanity checks
to prevent conflicting parameters */
- /* period_size_allowany and period_size */
- if (oss->user_period_size_allowany) {
/* period_size_allowany flag set:
allow any power of 2 period size */
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_PERIOD_BYTES,
ARRAY_SIZE(bytes_list), bytes_list);
if (err < 0)
return err;
- } else {
if (oss->user_period_size > 0) {
/* period_size set to positive value:
use user set period size */
const unsigned int user_period_size
= oss->user_period_size;
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_PERIOD_BYTES, 1,
&user_period_size);
} else {
/* query OSS for period size (called fragment size) */
unsigned int fragsize;
if (ioctl(oss->fd, SNDCTL_DSP_GETBLKSIZE, &fragsize)
< 0)
fprintf(stderr,
+"*** alsa-plugins-oss: error querying SNDCTL_DSP_GETBLKSIZE.\n");
/* note: second query of SNDCTL_DSP_GETBLKSIZE
can give different result
(i.e. 4096 instead of 2048) */
/* in oss_audio_core.c getblksize function,
4096 is the default return value:
so second time probably not reliable */
/* period size (in power of two) */
unsigned int x = fragsize;
/* check if fragsize is a power of two */
if ((x != 0) && ((x & (~x + 1)) == x))
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_PERIOD_BYTES,
1, &fragsize);
else
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_PERIOD_BYTES,
ARRAY_SIZE(bytes_list), bytes_list);
if (err < 0)
return err;
}
}
/* periods (number of periods per buffer) */
if (oss->user_periods > 0) {
/* force number of periods to user set periods */
const unsigned int user_periods = oss->user_periods;
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_PERIODS, 1, &user_periods);
if (err < 0)
return err;
} else {
/* allow any number of periods between 2 and 1024 inclusive
(ALSA can choose) */
err = snd_pcm_ioplug_set_param_minmax(io,
SND_PCM_IOPLUG_HW_PERIODS, 2, 1024);
if (err < 0)
return err;
}
/* buffer_size */
if (oss->user_buffer_size > 0) {
/* force buffer size to user set buffer_size */
const unsigned int user_buffer_size = oss->user_buffer_size;
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_BUFFER_BYTES, 1, &user_buffer_size);
if (err < 0)
return err;
} else {
/* buffer size (in power of two) */
err = snd_pcm_ioplug_set_param_list(io,
SND_PCM_IOPLUG_HW_BUFFER_BYTES,
ARRAY_SIZE(bytes_list), bytes_list);
if (err < 0)
return err;
}
return 0;
} @@ -556,6 +640,11 @@ SND_PCM_PLUGIN_DEFINE_FUNC(oss) const char *device = "/dev/dsp"; int err; snd_pcm_oss_t *oss;
/* default values for user variables*/
int user_period_size_allowany = 0;
long int user_period_size = 0;
long int user_periods = 0;
long int user_buffer_size = 0;
snd_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i);
@@ -571,6 +660,39 @@ SND_PCM_PLUGIN_DEFINE_FUNC(oss) } continue; }
/* user variables */
if (strcmp(id, "period_size_allowany") == 0) {
if (snd_config_get_bool(n) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
} else
user_period_size_allowany =
snd_config_get_bool(n);
continue;
}
if (strcmp(id, "period_size") == 0) {
if (snd_config_get_integer(n, &user_period_size) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "periods") == 0) {
if (snd_config_get_integer(n, &user_periods) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
if (strcmp(id, "buffer_size") == 0) {
if (snd_config_get_integer(n, &user_buffer_size) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
continue;
}
- SNDERR("Unknown field %s", id); return -EINVAL; }
@@ -595,6 +717,12 @@ SND_PCM_PLUGIN_DEFINE_FUNC(oss) goto error; }
- /* save user variables from ALSA config files */
- oss->user_period_size_allowany = user_period_size_allowany;
- oss->user_period_size = user_period_size;
- oss->user_periods = user_periods;
- oss->user_buffer_size = user_buffer_size;
- oss->io.version = SND_PCM_IOPLUG_VERSION; oss->io.name = "ALSA <-> OSS PCM I/O Plugin"; oss->io.poll_fd = oss->fd;
-- 1.8.3.1