]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Add snd_pcm_hw_params_get/set_export_buffer()
authorTakashi Iwai <tiwai@suse.de>
Thu, 19 May 2005 16:59:04 +0000 (16:59 +0000)
committerTakashi Iwai <tiwai@suse.de>
Thu, 19 May 2005 16:59:04 +0000 (16:59 +0000)
Add snd_pcm_hw_params_get/set_export_buffer() API functions.
They control to ensure the buffer export to other processes.
If this flag is set, the local buffer of a plugin is exported over IPC shm.
Otherwise the buffer can be handled only locally (no shm).

Also fixed Version file for 1.0.9.

include/pcm.h
include/sound/asound.h
src/Versions
src/pcm/pcm.c
src/pcm/pcm_local.h
src/pcm/pcm_mmap.c
src/pcm/pcm_shm.c

index fe0a4ca002df2e46de328d03929dbd5b73e80105..d814a43e612d94e3fc32bc09852fc145259f9ddd 100644 (file)
@@ -585,6 +585,8 @@ int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params
 int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
 int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
 int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
+int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
+int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
 
 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
 int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
index 9f7cef871de769f3d9da6d84bc65d118164ca468..443d4982424f52cd6480142f7a7f75bf94a604bb 100644 (file)
@@ -344,6 +344,7 @@ enum sndrv_pcm_hw_param {
 };
 
 #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0)  /* avoid rate resampling */
+#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER      (1<<1)  /* export buffer */
 
 struct sndrv_interval {
        unsigned int min, max;
index 793025f877bea4906a0b1d381ee5695e7b8067fb..37aecaf90885a2b2f8bf3b60635081f1e9b01d69 100644 (file)
@@ -179,6 +179,8 @@ ALSA_1.0.9 {
 
     snd_pcm_hw_params_set_rate_resample;
     snd_pcm_hw_params_get_rate_resample;
+    snd_pcm_hw_params_set_export_buffer;
+    snd_pcm_hw_params_get_export_buffer;
 
     snd_pcm_ioplug_create;
     snd_pcm_ioplug_delete;
@@ -215,4 +217,4 @@ ALSA_1.0.9 {
     snd_timer_ginfo_get_resolution_max;
     snd_timer_ginfo_get_clients;
 
-} ALSA_1.0.5;
+} ALSA_1.0.8;
index 69e7a53018181357239b85d0059e0594772d0f28..39c8f008885a9d3d4ff14ac005972b07fa915279 100644 (file)
@@ -3959,6 +3959,36 @@ int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
        return 0;
 }
 
+/**
+ * \brief Restrict a configuration space to allow the buffer accessible from outside
+ * \param pcm PCM handle
+ * \param params Configuration space
+ * \param val 0 = disable, 1 = enable (default) exporting buffer
+ * \return 0 otherwise a negative error code
+ */
+int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
+{
+       assert(pcm && params);
+       if (val)
+               params->flags |= SND_PCM_HW_PARAMS_EXPORT_BUFFER;
+       else
+               params->flags &= ~SND_PCM_HW_PARAMS_EXPORT_BUFFER;
+       return snd_pcm_hw_refine(pcm, params);
+}
+
+/**
+ * \brief Extract buffer accessibility from a configuration space
+ * \param pcm PCM handle
+ * \param *val 0 = disable, 1 = enable exporting buffer
+ * \return 0 otherwise a negative error code
+ */
+int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
+{
+       assert(pcm && params && val);
+       *val = params->flags & SND_PCM_HW_PARAMS_EXPORT_BUFFER ? 1 : 0;
+       return 0;
+}
+
 /**
  * \brief Extract period time from a configuration space
  * \param params Configuration space
index d174ca925dee1a78ce9dcce8c6c83c27d672ee08..15464a6327c05659a696c4e09f38fc9a03ddcf5e 100644 (file)
@@ -92,11 +92,8 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
 /** device can do a kind of synchronized start */
 #define SND_PCM_INFO_SYNC_START SNDRV_PCM_INFO_SYNC_START
 
-#ifndef SNDRV_PCM_HW_PARAMS_NORESAMPLE
-#define SND_PCM_HW_PARAMS_NORESAMPLE (1<<0)
-#else
 #define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
-#endif
+#define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER
 
 typedef struct _snd_pcm_rbptr {
        snd_pcm_t *master;
@@ -114,7 +111,7 @@ typedef struct _snd_pcm_channel_info {
        void *addr;                     /* base address of channel samples */
        unsigned int first;             /* offset to first sample in bits */
        unsigned int step;              /* samples distance in bits */
-       enum { SND_PCM_AREA_SHM, SND_PCM_AREA_MMAP } type;
+       enum { SND_PCM_AREA_SHM, SND_PCM_AREA_MMAP, SND_PCM_AREA_LOCAL } type;
        union {
                struct {
                        struct snd_shm_area *area;
@@ -214,9 +211,9 @@ struct _snd_pcm {
        snd_pcm_rbptr_t appl;
        snd_pcm_rbptr_t hw;
        snd_pcm_uframes_t min_align;
-       int mmap_rw: 1,
-           mmap_shadow: 1,
-           donot_close: 1;
+       unsigned int mmap_rw: 1;
+       unsigned int mmap_shadow: 1;
+       unsigned int donot_close: 1;
        snd_pcm_channel_info_t *mmap_channels;
        snd_pcm_channel_area_t *running_areas;
        snd_pcm_channel_area_t *stopped_areas;
index e67ade738cad2c7378f48a84954e986f0e0c4257..adea7fb7adef40dd38c11d7917bafbebbedcd570 100644 (file)
@@ -285,9 +285,12 @@ int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int s
                return -EINVAL;
        }
        info->addr = 0;
-       info->type = SND_PCM_AREA_SHM;
-       info->u.shm.shmid = shmid;
-       info->u.shm.area = NULL;
+       if (pcm->hw_flags & SND_PCM_HW_PARAMS_EXPORT_BUFFER) {
+               info->type = SND_PCM_AREA_SHM;
+               info->u.shm.shmid = shmid;
+               info->u.shm.area = NULL;
+       } else
+               info->type = SND_PCM_AREA_LOCAL;
        return 0;
 }      
 
@@ -347,6 +350,8 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
                                        if (i1->u.shm.shmid != i->u.shm.shmid)
                                                continue;
                                        break;
+                               case SND_PCM_AREA_LOCAL:
+                                       break;
                                default:
                                        assert(0);
                                }
@@ -368,6 +373,7 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
                        case SND_PCM_AREA_SHM:
                                if (i->u.shm.shmid < 0) {
                                        int id;
+                                       /* FIXME: safer permission? */
                                        id = shmget(IPC_PRIVATE, size, 0666);
                                        if (id < 0) {
                                                SYSERR("shmget failed");
@@ -409,6 +415,14 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
                                }
                                i->addr = ptr;
                                break;
+                       case SND_PCM_AREA_LOCAL:
+                               ptr = malloc(size);
+                               if (ptr == NULL) {
+                                       SYSERR("malloc failed");
+                                       return -errno;
+                               }
+                               i->addr = ptr;
+                               break;
                        default:
                                assert(0);
                        }
@@ -427,6 +441,8 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
                                if (i1->u.shm.shmid != i->u.shm.shmid)
                                        continue;
                                break;
+                       case SND_PCM_AREA_LOCAL:
+                               break;
                        default:
                                assert(0);
                        }
@@ -494,6 +510,10 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
                                }
                        }
                        break;
+               case SND_PCM_AREA_LOCAL:
+                       free(i->addr);
+                       i->addr = NULL;
+                       break;
                default:
                        assert(0);
                }
index 1c963affa6f842602ac68ddbb46b310adb3110b3..f2968a5a3aed6167b8204ae64df5c8a6e5051883 100644 (file)
@@ -288,6 +288,7 @@ static int snd_pcm_shm_hw_params_slave(snd_pcm_t *pcm,
        snd_pcm_shm_t *shm = pcm->private_data;
        volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
        int err;
+       params->flags |= SND_PCM_HW_PARAMS_EXPORT_BUFFER;
        ctrl->cmd = SNDRV_PCM_IOCTL_HW_PARAMS;
        ctrl->u.hw_params = *params;
        err = snd_pcm_shm_action(pcm);