xref: /aosp_15_r20/external/tinyalsa_new/include/tinyalsa/plugin.h (revision 02e95f1a335b55495d41ca67eaf42361f13704fa)
1 /* plugin.h
2 ** Copyright (c) 2019-2020, The Linux Foundation.
3 **
4 ** Redistribution and use in source and binary forms, with or without
5 ** modification, are permitted provided that the following conditions are
6 ** met:
7 **   * Redistributions of source code must retain the above copyright
8 **     notice, this list of conditions and the following disclaimer.
9 **   * Redistributions in binary form must reproduce the above
10 **     copyright notice, this list of conditions and the following
11 **     disclaimer in the documentation and/or other materials provided
12 **     with the distribution.
13 **   * Neither the name of The Linux Foundation nor the names of its
14 **     contributors may be used to endorse or promote products derived
15 **     from this software without specific prior written permission.
16 **
17 ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 ** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 ** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 ** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 ** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **/
29 
30 #ifndef TINYALSA_PLUGIN_H
31 #define TINYALSA_PLUGIN_H
32 
33 #include <poll.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37 #include <time.h>
38 
39 #include <sound/asound.h>
40 
41 /* static initializers */
42 
43 #define SND_VALUE_ENUM(etexts, eitems)    \
44     {.texts = etexts, .items = eitems}
45 
46 #define SND_VALUE_BYTES(csize)    \
47     {.size = csize }
48 
49 #define SND_VALUE_INTEGER(icount, imin, imax, istep) \
50     {.count = icount, .min = imin, .max = imax, .step = istep }
51 
52 #define SND_VALUE_TLV_BYTES(csize, cget, cput)       \
53     {.size = csize, .get = cget, .put = cput }
54 
55 /* pointer based initializers */
56 #define INIT_SND_CONTROL_INTEGER(c, cname, cget, cput, cint, pval, pdata)   \
57     {                                                                       \
58         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
59         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
60         c->type = SNDRV_CTL_ELEM_TYPE_INTEGER;                              \
61         c->name = cname; c->value = &cint; c->get = cget; c->put = cput;    \
62         c->private_value = pval; c->private_data = pdata;                   \
63     }
64 
65 #define INIT_SND_CONTROL_BYTES(c, cname, cget, cput, cint, pval, pdata)     \
66     {                                                                       \
67         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
68         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
69         c->type = SNDRV_CTL_ELEM_TYPE_BYTES;                                \
70         c->name = cname; c->value = &cint; c->get = cget; c->put = cput;    \
71         c->private_value = pval; c->private_data = pdata;                   \
72     }
73 
74 #define INIT_SND_CONTROL_ENUM(c, cname, cget, cput, cenum, pval, pdata)     \
75     {                                                                       \
76         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                              \
77         c->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;                        \
78         c->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;                           \
79         c->name = cname; c->value = cenum; c->get = cget; c->put = cput;    \
80         c->private_value = pval; c->private_data = pdata;                   \
81     }
82 
83 #define INIT_SND_CONTROL_TLV_BYTES(c, cname, cbytes, priv_val, priv_data)  \
84     {                                                                      \
85         c->iface = SNDRV_CTL_ELEM_IFACE_MIXER;                             \
86         c->access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE;                   \
87         c->type = SNDRV_CTL_ELEM_TYPE_BYTES;                               \
88         c->name = cname; c->value = &cbytes;                               \
89         c->private_value = priv_val; c->private_data = priv_data;          \
90     }
91 
92 struct mixer_plugin;
93 struct pcm_plugin;
94 struct snd_node;
95 
96 /** Operations that are required to be registered by the plugin.
97  * @ingroup libtinyalsa-pcm
98  */
99 struct pcm_plugin_ops {
100     /** open the pcm plugin */
101     int (*open) (struct pcm_plugin **plugin, unsigned int card,
102                  unsigned int device, unsigned int flags);
103     /** close the pcm plugin */
104     int (*close) (struct pcm_plugin *plugin);
105     /** Set the PCM hardware parameters to the plugin */
106     int (*hw_params) (struct pcm_plugin *plugin,
107                       struct snd_pcm_hw_params *params);
108     /** Set the PCM software parameters to the plugin */
109     int (*sw_params) (struct pcm_plugin *plugin,
110                       struct snd_pcm_sw_params *params);
111     /** Synchronize the pointer */
112     int (*sync_ptr) (struct pcm_plugin *plugin,
113                      struct snd_pcm_sync_ptr *sync_ptr);
114     /** Write frames to plugin to be rendered to output */
115     int (*writei_frames) (struct pcm_plugin *plugin,
116                           struct snd_xferi *x);
117     /** Read frames from plugin captured from input */
118     int (*readi_frames) (struct pcm_plugin *plugin,
119                          struct snd_xferi *x);
120     /** Obtain the timestamp for the PCM */
121     int (*ttstamp) (struct pcm_plugin *plugin,
122                     int *tstamp);
123     /** Prepare the plugin for data transfer */
124     int (*prepare) (struct pcm_plugin *plugin);
125     /** Start data transfer from/to the plugin */
126     int (*start) (struct pcm_plugin *plugin);
127     /** Signal the plugin to drain PCM */
128     int (*drain) (struct pcm_plugin *plugin);
129     /** Stop a PCM dropping pending frames if drain() is NOT called.
130      *  Stop a PCM preserving pending frames if drain() is called. */
131     int (*drop) (struct pcm_plugin *plugin);
132     /** Any custom or alsa specific ioctl implementation */
133     int (*ioctl) (struct pcm_plugin *plugin,
134                   int cmd, void *arg);
135     void *(*mmap) (struct pcm_plugin *plugin, void *addr, size_t length,
136                    int prot, int flags, off_t offset);
137     int (*munmap) (struct pcm_plugin *plugin, void *addr, size_t length);
138     int (*poll) (struct pcm_plugin *plugin, struct pollfd *pfd, nfds_t nfds,
139                  int timeout);
140 };
141 
142 /** Minimum and maximum values for hardware parameter constraints.
143  * @ingroup libtinyalsa-pcm
144  */
145 struct pcm_plugin_min_max {
146     /** Minimum value for the hardware parameter */
147     unsigned int min;
148     /** Maximum value for the hardware parameter */
149     unsigned int max;
150 };
151 
152 /** Encapsulate the hardware parameter constraints
153  * @ingroup libtinyalsa-pcm
154  */
155 struct pcm_plugin_hw_constraints {
156     /** Value for SNDRV_PCM_HW_PARAM_ACCESS param */
157     uint64_t access;
158     /** Value for SNDRV_PCM_HW_PARAM_FORMAT param.
159      * As of this implementation ALSA supports 52 formats */
160     uint64_t format;
161     /** Value for SNDRV_PCM_HW_PARAM_SAMPLE_BITS param */
162     struct pcm_plugin_min_max bit_width;
163     /** Value for SNDRV_PCM_HW_PARAM_CHANNELS param */
164     struct pcm_plugin_min_max channels;
165     /** Value for SNDRV_PCM_HW_PARAM_RATE param */
166     struct pcm_plugin_min_max rate;
167     /** Value for SNDRV_PCM_HW_PARAM_PERIODS param */
168     struct pcm_plugin_min_max periods;
169     /** Value for SNDRV_PCM_HW_PARAM_PERIOD_BYTES param */
170     struct pcm_plugin_min_max period_bytes;
171 };
172 
173 struct pcm_plugin {
174     /** Card number for the pcm device */
175     unsigned int card;
176     /** device number for the pcm device */
177     unsigned int device;
178     /** pointer to the contraints registered by the plugin */
179     struct pcm_plugin_hw_constraints *constraints;
180     /** Indicates read/write mode, etc.. */
181     int mode;
182     /* Pointer to hold the plugin's private data */
183     void *priv;
184     /* Tracks the plugin state */
185     unsigned int state;
186 };
187 
188 typedef void (*mixer_event_callback)(struct mixer_plugin *);
189 
190 struct mixer_plugin_ops {
191     int (*open) (struct mixer_plugin **plugin, unsigned int card);
192     void (*close) (struct mixer_plugin **plugin);
193     int (*subscribe_events) (struct mixer_plugin *plugin,
194                              mixer_event_callback event_cb);
195     ssize_t (*read_event) (struct mixer_plugin *plugin,
196                            struct snd_ctl_event *ev, size_t size);
197 };
198 
199 struct snd_control {
200     snd_ctl_elem_iface_t iface;
201     unsigned int access;
202     const char *name;
203     snd_ctl_elem_type_t type;
204     void *value;
205     int (*get) (struct mixer_plugin *plugin,
206                 struct snd_control *control,
207                 struct snd_ctl_elem_value *ev);
208     int (*put) (struct mixer_plugin *plugin,
209                 struct snd_control *control,
210                 struct snd_ctl_elem_value *ev);
211     uint32_t private_value;
212     void *private_data;
213 };
214 
215 struct mixer_plugin {
216     unsigned int card;
217     void *priv;
218 
219     int eventfd;
220     int subscribed;
221     int event_cnt;
222 
223     struct snd_control *controls;
224     unsigned int num_controls;
225 };
226 
227 struct snd_value_enum {
228     unsigned int items;
229     char **texts;
230 };
231 
232 struct snd_value_bytes {
233     unsigned int size;
234 };
235 
236 struct snd_value_tlv_bytes {
237     unsigned int size;
238     int (*get) (struct mixer_plugin *plugin,
239                 struct snd_control *control,
240                 struct snd_ctl_tlv *tlv);
241     int (*put) (struct mixer_plugin *plugin,
242                 struct snd_control *control,
243                 struct snd_ctl_tlv *tlv);
244 };
245 
246 struct snd_value_int {
247     unsigned int count;
248     int min;
249     int max;
250     int step;
251 };
252 
253 /** Operations defined by the plugin.
254  * */
255 struct snd_node_ops {
256     /** Function pointer to get card definition */
257     void* (*open_card)(unsigned int card);
258     /** Function pointer to release card definition */
259     void (*close_card)(void *card);
260     /** Get interger type properties from device definition */
261     int (*get_int)(void *node, const char *prop, int *val);
262     /** Get string type properties from device definition */
263     int (*get_str)(void *node, const char *prop, char **val);
264     /** Function pointer to get mixer definition */
265     void* (*get_mixer)(void *card);
266     /** Function pointer to get PCM definition */
267     void* (*get_pcm)(void *card, unsigned int id);
268     /** Reserved for other nodes such as compress */
269     void* reserved[4];
270 };
271 
272 #endif /* end of TINYALSA_PLUGIN_H */
273