ctrl->cmd = 0;
pcm = client->device.pcm.handle;
switch (cmd) {
+ case SND_PCM_IOCTL_CARD:
+ ctrl->result = 0;
+ ctrl->u.card = snd_pcm_card(pcm);
+ break;
case SND_PCM_IOCTL_ASYNC:
ctrl->result = snd_pcm_async(pcm, ctrl->u.async.sig, ctrl->u.async.pid);
break;
case SND_CTL_IOCTL_CLOSE:
client->ops->close(client);
break;
+ case SND_PCM_IOCTL_CARD:
+ ctrl->result = 0;
+ return shm_ack_fd(client, snd_ctl_card(ctl));
case SND_PCM_IOCTL_POLL_DESCRIPTOR:
ctrl->result = 0;
return shm_ack_fd(client, snd_ctl_poll_descriptor(ctl));
#include "../src/pcm/pcm_local.h"
-#define SND_PCM_IOCTL_STATE _IO ('A', 0xf0)
-#define SND_PCM_IOCTL_MMAP _IO ('A', 0xf1)
-#define SND_PCM_IOCTL_MUNMAP _IO ('A', 0xf4)
-#define SND_PCM_IOCTL_MMAP_FORWARD _IO ('A', 0xf7)
-#define SND_PCM_IOCTL_AVAIL_UPDATE _IO ('A', 0xf8)
-#define SND_PCM_IOCTL_ASYNC _IO ('A', 0xf9)
-#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xfa)
-#define SND_PCM_IOCTL_POLL_DESCRIPTOR _IO ('A', 0xfc)
-#define SND_PCM_IOCTL_SET_AVAIL_MIN _IO ('A', 0xfd)
+#define SND_PCM_IOCTL_CARD _IO ('A', 0xf0)
+#define SND_PCM_IOCTL_STATE _IO ('A', 0xf1)
+#define SND_PCM_IOCTL_MMAP _IO ('A', 0xf2)
+#define SND_PCM_IOCTL_MUNMAP _IO ('A', 0xf3)
+#define SND_PCM_IOCTL_MMAP_FORWARD _IO ('A', 0xf4)
+#define SND_PCM_IOCTL_AVAIL_UPDATE _IO ('A', 0xf5)
+#define SND_PCM_IOCTL_ASYNC _IO ('A', 0xf6)
+#define SND_PCM_IOCTL_CLOSE _IO ('A', 0xf7)
+#define SND_PCM_IOCTL_POLL_DESCRIPTOR _IO ('A', 0xf8)
+#define SND_PCM_IOCTL_SET_AVAIL_MIN _IO ('A', 0xf9)
typedef struct {
long result;
size_t hw_ptr;
size_t appl_ptr;
union {
+ int card;
struct {
int sig;
pid_t pid;
#define PCM_SHM_SIZE sizeof(snd_pcm_shm_ctrl_t)
-#define SND_CTL_IOCTL_READ _IOR('U', 0xf0, snd_ctl_event_t)
-#define SND_CTL_IOCTL_CLOSE _IO ('U', 0xf1)
-#define SND_CTL_IOCTL_POLL_DESCRIPTOR _IO ('U', 0xf2)
+#define SND_CTL_IOCTL_CARD _IO ('U', 0xf0)
+#define SND_CTL_IOCTL_READ _IOR('U', 0xf1, snd_ctl_event_t)
+#define SND_CTL_IOCTL_CLOSE _IO ('U', 0xf2)
+#define SND_CTL_IOCTL_POLL_DESCRIPTOR _IO ('U', 0xf3)
typedef struct {
int result;
snd_ctl_type_t snd_ctl_type(snd_ctl_t *handle);
int snd_ctl_open(snd_ctl_t **handle, char *name);
int snd_ctl_close(snd_ctl_t *handle);
+int snd_ctl_card(snd_ctl_t *handle);
int snd_ctl_poll_descriptor(snd_ctl_t *handle);
int snd_ctl_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info);
int snd_ctl_clist(snd_ctl_t *handle, snd_control_list_t * list);
int snd_mixer_open(snd_mixer_t **handle, char *name);
int snd_mixer_close(snd_mixer_t *handle);
+int snd_mixer_card(snd_mixer_t *handle);
int snd_mixer_poll_descriptor(snd_mixer_t *handle);
#ifdef __cplusplus
snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
int snd_pcm_close(snd_pcm_t *pcm);
+int snd_pcm_card(snd_pcm_t *pcm);
int snd_pcm_poll_descriptor(snd_pcm_t *pcm);
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_rawmidi_open(snd_rawmidi_t **handle, char *name, int streams, int mode);
int snd_rawmidi_close(snd_rawmidi_t *handle);
+int snd_rawmidi_card(snd_rawmidi_t *handle);
int snd_rawmidi_poll_descriptor(snd_rawmidi_t *handle);
int snd_rawmidi_nonblock(snd_rawmidi_t *handle, int nonblock);
int snd_rawmidi_info(snd_rawmidi_t *handle, snd_rawmidi_info_t * info);
return res;
}
+int snd_ctl_card(snd_ctl_t *ctl)
+{
+ assert(ctl);
+ return ctl->ops->card(ctl);
+}
+
int snd_ctl_poll_descriptor(snd_ctl_t *ctl)
{
assert(ctl);
return res;
}
+static int snd_ctl_hw_card(snd_ctl_t *handle)
+{
+ snd_ctl_hw_t *hw = handle->private;
+ return hw->card;
+}
+
static int snd_ctl_hw_poll_descriptor(snd_ctl_t *handle)
{
snd_ctl_hw_t *hw = handle->private;
snd_ctl_ops_t snd_ctl_hw_ops = {
close: snd_ctl_hw_close,
+ card: snd_ctl_hw_card,
poll_descriptor: snd_ctl_hw_poll_descriptor,
hw_info: snd_ctl_hw_hw_info,
clist: snd_ctl_hw_clist,
typedef struct {
int (*close)(snd_ctl_t *handle);
+ int (*card)(snd_ctl_t *handle);
int (*poll_descriptor)(snd_ctl_t *handle);
int (*hw_info)(snd_ctl_t *handle, snd_ctl_hw_info_t *info);
int (*clist)(snd_ctl_t *handle, snd_control_list_t *list);
return result;
}
+static int snd_ctl_shm_card(snd_ctl_t *ctl)
+{
+ snd_ctl_shm_t *shm = ctl->private;
+ snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
+ int card, err;
+ ctrl->cmd = SND_CTL_IOCTL_CARD;
+ err = snd_ctl_shm_action_fd(ctl, &card);
+ if (err < 0)
+ return err;
+ return card;
+}
+
static int snd_ctl_shm_poll_descriptor(snd_ctl_t *ctl)
{
snd_ctl_shm_t *shm = ctl->private;
snd_ctl_ops_t snd_ctl_shm_ops = {
close: snd_ctl_shm_close,
+ card: snd_ctl_shm_card,
poll_descriptor: snd_ctl_shm_poll_descriptor,
hw_info: snd_ctl_shm_hw_info,
clist: snd_ctl_shm_clist,
return snd_pcm_readn(pcm, bufs, vector[0].iov_len);
}
+int snd_pcm_card(snd_pcm_t *pcm)
+{
+ assert(pcm);
+ return pcm->ops->card(pcm->op_arg);
+}
+
/* FIXME */
#define snd_pcm_link_descriptor snd_pcm_poll_descriptor
snd_pcm_ops_t snd_pcm_adpcm_ops = {
close: snd_pcm_adpcm_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_adpcm_hw_refine,
hw_params: snd_pcm_adpcm_hw_params,
snd_pcm_ops_t snd_pcm_alaw_ops = {
close: snd_pcm_plugin_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_alaw_hw_refine,
hw_params: snd_pcm_alaw_hw_params,
snd_pcm_ops_t snd_pcm_copy_ops = {
close: snd_pcm_plugin_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_copy_hw_refine,
hw_params: snd_pcm_copy_hw_params,
return 0;
}
+static int snd_pcm_file_card(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private;
+ return snd_pcm_card(file->slave);
+}
+
static int snd_pcm_file_nonblock(snd_pcm_t *pcm, int nonblock)
{
snd_pcm_file_t *file = pcm->private;
snd_pcm_ops_t snd_pcm_file_ops = {
close: snd_pcm_file_close,
+ card: snd_pcm_file_card,
info: snd_pcm_file_info,
hw_refine: snd_pcm_file_hw_refine,
hw_params: snd_pcm_file_hw_params,
return 0;
}
+static int snd_pcm_hw_card(snd_pcm_t *pcm)
+{
+ snd_pcm_hw_t *hw = pcm->private;
+ return hw->card;
+}
+
static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
{
snd_pcm_hw_t *hw = pcm->private;
snd_pcm_ops_t snd_pcm_hw_ops = {
close: snd_pcm_hw_close,
+ card: snd_pcm_hw_card,
info: snd_pcm_hw_info,
hw_refine: snd_pcm_hw_hw_refine,
hw_params: snd_pcm_hw_hw_params,
snd_pcm_ops_t snd_pcm_linear_ops = {
close: snd_pcm_plugin_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_linear_hw_refine,
hw_params: snd_pcm_linear_hw_params,
typedef struct {
int (*close)(snd_pcm_t *pcm);
+ int (*card)(snd_pcm_t *pcm);
int (*nonblock)(snd_pcm_t *pcm, int nonblock);
int (*async)(snd_pcm_t *pcm, int sig, pid_t pid);
int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
snd_pcm_ops_t snd_pcm_mulaw_ops = {
close: snd_pcm_plugin_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_mulaw_hw_refine,
hw_params: snd_pcm_mulaw_hw_params,
return ret;
}
+static int snd_pcm_multi_card(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return -ENOENT; /* not available */
+}
+
static int snd_pcm_multi_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{
return 0;
snd_pcm_ops_t snd_pcm_multi_ops = {
close: snd_pcm_multi_close,
+ card: snd_pcm_multi_card,
info: snd_pcm_multi_info,
hw_refine: snd_pcm_multi_hw_refine,
hw_params: snd_pcm_multi_hw_params,
return 0;
}
+static int snd_pcm_null_card(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return -ENOENT; /* not available */
+}
+
static int snd_pcm_null_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{
return 0;
snd_pcm_ops_t snd_pcm_null_ops = {
close: snd_pcm_null_close,
+ card: snd_pcm_null_card,
info: snd_pcm_null_info,
hw_refine: snd_pcm_null_hw_refine,
hw_params: snd_pcm_null_hw_params,
return result;
}
+static int snd_pcm_plug_card(snd_pcm_t *pcm)
+{
+ snd_pcm_plug_t *plug = pcm->private;
+ return snd_pcm_card(plug->slave);
+}
+
static int snd_pcm_plug_nonblock(snd_pcm_t *pcm, int nonblock)
{
snd_pcm_plug_t *plug = pcm->private;
snd_pcm_ops_t snd_pcm_plug_ops = {
close: snd_pcm_plug_close,
+ card: snd_pcm_plug_card,
info: snd_pcm_plug_info,
hw_refine: snd_pcm_plug_hw_refine,
hw_params: snd_pcm_plug_hw_params,
return 0;
}
+int snd_pcm_plugin_card(snd_pcm_t *pcm)
+{
+ snd_pcm_plugin_t *plugin = pcm->private;
+ return snd_pcm_card(plugin->slave);
+}
+
int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock)
{
snd_pcm_plugin_t *plugin = pcm->private;
} snd_pcm_plugin_t;
int snd_pcm_plugin_close(snd_pcm_t *pcm);
+int snd_pcm_plugin_card(snd_pcm_t *pcm);
int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid);
int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
snd_pcm_ops_t snd_pcm_rate_ops = {
close: snd_pcm_rate_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_rate_hw_refine,
hw_params: snd_pcm_rate_hw_params,
snd_pcm_ops_t snd_pcm_route_ops = {
close: snd_pcm_route_close,
+ card: snd_pcm_plugin_card,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_route_hw_refine,
hw_params: snd_pcm_route_hw_params,
}
}
+static int snd_pcm_share_card(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return -ENOENT; /* not available */
+}
+
static int snd_pcm_share_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{
return 0;
snd_pcm_ops_t snd_pcm_share_ops = {
close: snd_pcm_share_close,
+ card: snd_pcm_share_card,
info: snd_pcm_share_info,
hw_refine: snd_pcm_share_hw_refine,
hw_params: snd_pcm_share_hw_params,
return ctrl->result;
}
+static int snd_pcm_shm_card(snd_pcm_t *pcm)
+{
+ snd_pcm_shm_t *shm = pcm->private;
+ volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
+ int err;
+ ctrl->cmd = SND_PCM_IOCTL_CARD;
+ err = snd_pcm_shm_action(pcm);
+ if (err < 0)
+ return err;
+ return ctrl->u.card;
+}
+
static int snd_pcm_shm_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
{
return 0;
snd_pcm_ops_t snd_pcm_shm_ops = {
close: snd_pcm_shm_close,
+ card: snd_pcm_shm_card,
info: snd_pcm_shm_info,
hw_refine: snd_pcm_shm_hw_refine,
hw_params: snd_pcm_shm_hw_params,
return 0;
}
+int snd_rawmidi_card(snd_rawmidi_t *rmidi)
+{
+ assert(rmidi);
+ return rmidi->ops->card(rmidi);
+}
+
int snd_rawmidi_poll_descriptor(snd_rawmidi_t *rmidi)
{
assert(rmidi);
return 0;
}
+static int snd_rawmidi_hw_card(snd_rawmidi_t *rmidi)
+{
+ snd_rawmidi_hw_t *hw = rmidi->private;
+ return hw->card;
+}
+
static int snd_rawmidi_hw_nonblock(snd_rawmidi_t *rmidi, int nonblock)
{
snd_rawmidi_hw_t *hw = rmidi->private;
snd_rawmidi_ops_t snd_rawmidi_hw_ops = {
close: snd_rawmidi_hw_close,
+ card: snd_rawmidi_hw_card,
nonblock: snd_rawmidi_hw_nonblock,
info: snd_rawmidi_hw_info,
params: snd_rawmidi_hw_params,
typedef struct {
int (*close)(snd_rawmidi_t *rawmidi);
+ int (*card)(snd_rawmidi_t *rawmidi);
int (*nonblock)(snd_rawmidi_t *rawmidi, int nonblock);
int (*info)(snd_rawmidi_t *rawmidi, snd_rawmidi_info_t *info);
int (*params)(snd_rawmidi_t *rawmidi, snd_rawmidi_params_t *params);