mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
improved stream linking and plugin code cleanups
- added link/unlink/link_fd fast_ops callbacks - moved code from snd_pcm_link to pcm_hw.c - moved "empty" routines pointing to slave to pcm_generic.c - introduced snd_pcm_generic_t
This commit is contained in:
parent
9501520606
commit
836987aa99
25 changed files with 767 additions and 957 deletions
|
|
@ -42,8 +42,7 @@ typedef enum _snd_pcm_file_format {
|
|||
} snd_pcm_file_format_t;
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *slave;
|
||||
int close_slave;
|
||||
snd_pcm_generic_t gen;
|
||||
char *fname;
|
||||
int fd;
|
||||
int format;
|
||||
|
|
@ -115,81 +114,17 @@ static void snd_pcm_file_add_frames(snd_pcm_t *pcm,
|
|||
static int snd_pcm_file_close(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
int err = 0;
|
||||
if (file->close_slave)
|
||||
err = snd_pcm_close(file->slave);
|
||||
if (file->fname) {
|
||||
free((void *)file->fname);
|
||||
close(file->fd);
|
||||
}
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_file_nonblock(snd_pcm_t *pcm, int nonblock)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_nonblock(file->slave, nonblock);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_async(file->slave, sig, pid);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_poll_descriptors_revents(file->slave, pfds, nfds, revents);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_info(file->slave, info);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_channel_info(file->slave, info);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_status(file->slave, status);
|
||||
}
|
||||
|
||||
static snd_pcm_state_t snd_pcm_file_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_state(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_hwsync(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_hwsync(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_delay(file->slave, delayp);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_prepare(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_prepare(file->slave);
|
||||
return snd_pcm_generic_close(pcm);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_reset(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
int err = snd_pcm_reset(file->slave);
|
||||
int err = snd_pcm_reset(file->gen.slave);
|
||||
if (err >= 0) {
|
||||
/* FIXME: Questionable here */
|
||||
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||
|
|
@ -198,16 +133,10 @@ static int snd_pcm_file_reset(snd_pcm_t *pcm)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_file_start(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_start(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_drop(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
int err = snd_pcm_drop(file->slave);
|
||||
int err = snd_pcm_drop(file->gen.slave);
|
||||
if (err >= 0) {
|
||||
/* FIXME: Questionable here */
|
||||
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||
|
|
@ -219,7 +148,7 @@ static int snd_pcm_file_drop(snd_pcm_t *pcm)
|
|||
static int snd_pcm_file_drain(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
int err = snd_pcm_drain(file->slave);
|
||||
int err = snd_pcm_drain(file->gen.slave);
|
||||
if (err >= 0) {
|
||||
snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
|
||||
assert(file->wbuf_used_bytes == 0);
|
||||
|
|
@ -227,12 +156,6 @@ static int snd_pcm_file_drain(snd_pcm_t *pcm)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_file_pause(snd_pcm_t *pcm, int enable)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_pause(file->slave, enable);
|
||||
}
|
||||
|
||||
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_data;
|
||||
|
|
@ -242,7 +165,7 @@ static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
|
|||
n = snd_pcm_frames_to_bytes(pcm, frames);
|
||||
if (n > file->wbuf_used_bytes)
|
||||
frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
|
||||
err = snd_pcm_rewind(file->slave, frames);
|
||||
err = snd_pcm_rewind(file->gen.slave, frames);
|
||||
if (err > 0) {
|
||||
n = snd_pcm_frames_to_bytes(pcm, err);
|
||||
file->wbuf_used_bytes -= n;
|
||||
|
|
@ -259,7 +182,7 @@ static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
|
|||
n = snd_pcm_frames_to_bytes(pcm, frames);
|
||||
if (file->wbuf_used_bytes + n > file->wbuf_size_bytes)
|
||||
frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
|
||||
err = INTERNAL(snd_pcm_forward)(file->slave, frames);
|
||||
err = INTERNAL(snd_pcm_forward)(file->gen.slave, frames);
|
||||
if (err > 0) {
|
||||
snd_pcm_uframes_t n = snd_pcm_frames_to_bytes(pcm, err);
|
||||
file->wbuf_used_bytes += n;
|
||||
|
|
@ -267,25 +190,11 @@ static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t
|
|||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_file_resume(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_resume(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_poll_ask(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
if (file->slave->fast_ops->poll_ask)
|
||||
return file->slave->fast_ops->poll_ask(file->slave->fast_op_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_data;
|
||||
snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n = snd_pcm_writei(file->slave, buffer, size);
|
||||
snd_pcm_sframes_t n = snd_pcm_writei(file->gen.slave, buffer, size);
|
||||
if (n > 0) {
|
||||
snd_pcm_areas_from_buf(pcm, areas, (void*) buffer);
|
||||
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
|
|
@ -297,7 +206,7 @@ static snd_pcm_sframes_t snd_pcm_file_writen(snd_pcm_t *pcm, void **bufs, snd_pc
|
|||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
|
||||
snd_pcm_sframes_t n = snd_pcm_writen(file->gen.slave, bufs, size);
|
||||
if (n > 0) {
|
||||
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
||||
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
|
|
@ -309,7 +218,7 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc
|
|||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n = snd_pcm_readi(file->slave, buffer, size);
|
||||
snd_pcm_sframes_t n = snd_pcm_readi(file->gen.slave, buffer, size);
|
||||
if (n > 0) {
|
||||
snd_pcm_areas_from_buf(pcm, areas, buffer);
|
||||
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
|
|
@ -321,7 +230,7 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm
|
|||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n = snd_pcm_writen(file->slave, bufs, size);
|
||||
snd_pcm_sframes_t n = snd_pcm_writen(file->gen.slave, bufs, size);
|
||||
if (n > 0) {
|
||||
snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
||||
snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
|
|
@ -339,26 +248,14 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm,
|
|||
const snd_pcm_channel_area_t *areas;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
snd_pcm_mmap_begin(file->slave, &areas, &ofs, &siz);
|
||||
snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz);
|
||||
assert(ofs == offset && siz == size);
|
||||
result = snd_pcm_mmap_commit(file->slave, ofs, siz);
|
||||
result = snd_pcm_mmap_commit(file->gen.slave, ofs, siz);
|
||||
if (result > 0)
|
||||
snd_pcm_file_add_frames(pcm, areas, ofs, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_file_avail_update(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_avail_update(file->slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_hw_refine(file->slave, params);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
|
|
@ -369,14 +266,14 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
|
|||
file->wbuf = 0;
|
||||
file->wbuf_areas = 0;
|
||||
}
|
||||
return snd_pcm_hw_free(file->slave);
|
||||
return snd_pcm_hw_free(file->gen.slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
unsigned int channel;
|
||||
snd_pcm_t *slave = file->slave;
|
||||
snd_pcm_t *slave = file->gen.slave;
|
||||
int err = _snd_pcm_hw_params(slave, params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
@ -404,16 +301,10 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
return snd_pcm_sw_params(file->slave, params);
|
||||
}
|
||||
|
||||
static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
snd_pcm_t *slave = file->slave;
|
||||
snd_pcm_t *slave = file->gen.slave;
|
||||
pcm->running_areas = slave->running_areas;
|
||||
pcm->stopped_areas = slave->stopped_areas;
|
||||
pcm->mmap_channels = slave->mmap_channels;
|
||||
|
|
@ -442,45 +333,48 @@ static void snd_pcm_file_dump(snd_pcm_t *pcm, snd_output_t *out)
|
|||
snd_pcm_dump_setup(pcm, out);
|
||||
}
|
||||
snd_output_printf(out, "Slave: ");
|
||||
snd_pcm_dump(file->slave, out);
|
||||
snd_pcm_dump(file->gen.slave, out);
|
||||
}
|
||||
|
||||
static snd_pcm_ops_t snd_pcm_file_ops = {
|
||||
.close = snd_pcm_file_close,
|
||||
.info = snd_pcm_file_info,
|
||||
.hw_refine = snd_pcm_file_hw_refine,
|
||||
.hw_params = snd_pcm_file_hw_params,
|
||||
.info = snd_pcm_generic_info,
|
||||
.hw_refine = snd_pcm_generic_hw_refine,
|
||||
.hw_params = snd_pcm_generic_hw_params,
|
||||
.hw_free = snd_pcm_file_hw_free,
|
||||
.sw_params = snd_pcm_file_sw_params,
|
||||
.channel_info = snd_pcm_file_channel_info,
|
||||
.sw_params = snd_pcm_generic_sw_params,
|
||||
.channel_info = snd_pcm_generic_channel_info,
|
||||
.dump = snd_pcm_file_dump,
|
||||
.nonblock = snd_pcm_file_nonblock,
|
||||
.async = snd_pcm_file_async,
|
||||
.poll_revents = snd_pcm_file_poll_revents,
|
||||
.nonblock = snd_pcm_generic_nonblock,
|
||||
.async = snd_pcm_generic_async,
|
||||
.poll_revents = snd_pcm_generic_poll_revents,
|
||||
.mmap = snd_pcm_file_mmap,
|
||||
.munmap = snd_pcm_file_munmap,
|
||||
};
|
||||
|
||||
static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
|
||||
.status = snd_pcm_file_status,
|
||||
.state = snd_pcm_file_state,
|
||||
.hwsync = snd_pcm_file_hwsync,
|
||||
.delay = snd_pcm_file_delay,
|
||||
.prepare = snd_pcm_file_prepare,
|
||||
.status = snd_pcm_generic_status,
|
||||
.state = snd_pcm_generic_state,
|
||||
.hwsync = snd_pcm_generic_hwsync,
|
||||
.delay = snd_pcm_generic_delay,
|
||||
.prepare = snd_pcm_generic_prepare,
|
||||
.reset = snd_pcm_file_reset,
|
||||
.start = snd_pcm_file_start,
|
||||
.start = snd_pcm_generic_start,
|
||||
.drop = snd_pcm_file_drop,
|
||||
.drain = snd_pcm_file_drain,
|
||||
.pause = snd_pcm_file_pause,
|
||||
.pause = snd_pcm_generic_pause,
|
||||
.rewind = snd_pcm_file_rewind,
|
||||
.forward = snd_pcm_file_forward,
|
||||
.resume = snd_pcm_file_resume,
|
||||
.poll_ask = snd_pcm_file_poll_ask,
|
||||
.resume = snd_pcm_generic_resume,
|
||||
.poll_ask = snd_pcm_generic_poll_ask,
|
||||
.link_fd = snd_pcm_generic_link_fd,
|
||||
.link = snd_pcm_generic_link,
|
||||
.unlink = snd_pcm_generic_unlink,
|
||||
.writei = snd_pcm_file_writei,
|
||||
.writen = snd_pcm_file_writen,
|
||||
.readi = snd_pcm_file_readi,
|
||||
.readn = snd_pcm_file_readn,
|
||||
.avail_update = snd_pcm_file_avail_update,
|
||||
.avail_update = snd_pcm_generic_avail_update,
|
||||
.mmap_commit = snd_pcm_file_mmap_commit,
|
||||
};
|
||||
|
||||
|
|
@ -532,8 +426,8 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
|
|||
file->fname = strdup(fname);
|
||||
file->fd = fd;
|
||||
file->format = format;
|
||||
file->slave = slave;
|
||||
file->close_slave = close_slave;
|
||||
file->gen.slave = slave;
|
||||
file->gen.close_slave = close_slave;
|
||||
|
||||
err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
|
||||
if (err < 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue