diff options
-rw-r--r-- | include/tinyalsa/attributes.h | 11 | ||||
-rw-r--r-- | include/tinyalsa/mixer.h | 25 | ||||
-rw-r--r-- | include/tinyalsa/pcm.h | 4 | ||||
-rw-r--r-- | src/mixer.c | 52 | ||||
-rw-r--r-- | src/pcm.c | 18 |
5 files changed, 87 insertions, 23 deletions
diff --git a/include/tinyalsa/attributes.h b/include/tinyalsa/attributes.h index e33f46a..f465ba1 100644 --- a/include/tinyalsa/attributes.h +++ b/include/tinyalsa/attributes.h @@ -6,7 +6,12 @@ * when the library is being used incorrectly. * */ -#ifdef __GNUC__ +// FIXME: Disable the deprecated attribute in Android temporarily. pcm_read/write are marked as +// deprecated functions in the latest tinyalsa in GitHub. However, there are lots of libraries in +// Android using these functions and building with -Werror flags. Besides build breakage, the +// behavior and interface of the successors, pcm_readi/writei, are also changed. Once all have +// been cleaned up, we will enable this again. +#if defined(__GNUC__) && !defined(ANDROID) /** Issues a warning when a function is being * used that is now deprecated. @@ -20,7 +25,7 @@ * */ #define TINYALSA_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else /* __GNUC__ */ +#else /* __GNUC__ && !ANDROID */ /** This is just a placeholder for compilers * that aren't GCC or Clang. @@ -34,6 +39,6 @@ * */ #define TINYALSA_WARN_UNUSED_RESULT -#endif /* __GNUC__ */ +#endif /* __GNUC__ && !ANDROID */ #endif /* TINYALSA_ATTRIBUTES_H */ diff --git a/include/tinyalsa/mixer.h b/include/tinyalsa/mixer.h index 77d5d01..7d0580f 100644 --- a/include/tinyalsa/mixer.h +++ b/include/tinyalsa/mixer.h @@ -37,19 +37,34 @@ #include <sys/time.h> #include <stddef.h> -#include <sound/asound.h> #if defined(__cplusplus) extern "C" { #endif -/* TLV header size*/ -#define TLV_HEADER_SIZE sizeof(struct snd_ctl_tlv) - struct mixer; struct mixer_ctl; +// mixer_ctl_event is a mirroring structure of snd_ctl_event +struct mixer_ctl_event { + int type; + union { + struct { + unsigned int mask; + struct { + unsigned int numid; + int iface; + unsigned int device; + unsigned int subdevice; + unsigned char name[44]; + unsigned int index; + } id; + } element; + unsigned char data[60]; + } data; +}; + /** Mixer control type. * @ingroup libtinyalsa-mixer */ @@ -138,7 +153,7 @@ int mixer_ctl_get_range_min(const struct mixer_ctl *ctl); int mixer_ctl_get_range_max(const struct mixer_ctl *ctl); -int mixer_read_event(struct mixer *mixer, struct snd_ctl_event *ev); +int mixer_read_event(struct mixer *mixer, struct mixer_ctl_event *event); int mixer_consume_event(struct mixer *mixer); #if defined(__cplusplus) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index cdc31a5..6569146 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -221,6 +221,8 @@ struct pcm_config { /** The number of frames to overwrite the playback buffer when the playback underrun is greater * than the silence threshold */ unsigned int silence_size; + + unsigned int avail_min; }; /** Enumeration of a PCM's hardware parameters. @@ -361,6 +363,8 @@ int pcm_wait(struct pcm *pcm, int timeout); long pcm_get_delay(struct pcm *pcm); +int pcm_ioctl(struct pcm *pcm, int code, ...) TINYALSA_DEPRECATED; + #if defined(__cplusplus) } /* extern "C" */ #endif diff --git a/src/mixer.c b/src/mixer.c index fe590e8..a45502e 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -553,39 +553,61 @@ exit: * further events can be alerted. * * @param mixer A mixer handle. - * @returns 0 on success. -errno on failure. + * @returns 1 on success. 0, if no pending event. -errno on failure. * @ingroup libtinyalsa-mixer */ int mixer_consume_event(struct mixer *mixer) { - struct snd_ctl_event ev; + struct mixer_ctl_event ev; return mixer_read_event(mixer, &ev); } -int mixer_read_event(struct mixer *mixer, struct snd_ctl_event *ev) +/** Read a mixer control event. + * Try to read an control event from mixer. + * + * @param mixer A mixer handle. + * @param event Output parameter. If there is an event read form the mixer, this function will fill + * the event data into it. + * @returns 1 on success. 0, if no pending event. -errno on failure. + * @ingroup libtinyalsa-mixer + */ +int mixer_read_event(struct mixer *mixer, struct mixer_ctl_event *event) { - struct mixer_ctl_group *grp; - ssize_t count = 0; + struct mixer_ctl_group *grp = NULL; + struct snd_ctl_event ev; + ssize_t bytes = 0; + + if (!mixer || !event) { + return -EINVAL; + } if (mixer->h_grp) { - grp = mixer->h_grp; - if (grp->event_cnt) { - grp->event_cnt--; - count = grp->ops->read_event(grp->data, ev, sizeof(*ev)); - return (count >= 0) ? 0 : -errno; + if (mixer->h_grp->event_cnt > 0) { + grp = mixer->h_grp; } } #ifdef TINYALSA_USES_PLUGINS if (mixer->v_grp) { - grp = mixer->v_grp; - if (grp->event_cnt) { - grp->event_cnt--; - count = grp->ops->read_event(grp->data, ev, sizeof(*ev)); - return (count >= 0) ? 0 : -errno; + if (mixer->v_grp->event_cnt > 0) { + grp = mixer->v_grp; } } #endif + if (grp) { + grp->event_cnt--; + bytes = grp->ops->read_event(grp->data, &ev, sizeof(ev)); + + if (bytes < 0) { + return -errno; + } + + if (bytes == sizeof(*event)) { + memcpy(event, &ev, sizeof(*event)); + return 1; + } + } + return 0; } @@ -1750,3 +1750,21 @@ long pcm_get_delay(struct pcm *pcm) return pcm->pcm_delay; } + +// TODO: Currently in Android, there are some libraries using this function to control the driver. +// We should remove this function as soon as possible. +int pcm_ioctl(struct pcm *pcm, int request, ...) +{ + va_list ap; + void * arg; + + if (!pcm_is_ready(pcm)) + return -1; + + va_start(ap, request); + arg = va_arg(ap, void *); + va_end(ap); + + // FIXME Does not handle plugins + return ioctl(pcm->fd, request, arg); +} |