diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | gen-stubs.bash | 2 | ||||
-rw-r--r-- | src/libasound.c | 173 | ||||
-rw-r--r-- | src/mixer.c | 264 | ||||
-rw-r--r-- | src/pcm.c (renamed from libasound.c) | 460 | ||||
-rw-r--r-- | src/stubs.h (renamed from stubs.h) | 0 | ||||
-rw-r--r-- | src/symversioning-hell.h (renamed from symversioning-hell.h) | 0 | ||||
-rw-r--r-- | src/util/defs.h (renamed from dsp/defs.h) | 0 | ||||
-rw-r--r-- | src/util/dsp.c (renamed from dsp/dsp.c) | 0 | ||||
-rw-r--r-- | src/util/dsp.h (renamed from dsp/dsp.h) | 0 | ||||
-rw-r--r-- | src/util/sysex.h (renamed from sysex.h) | 0 | ||||
-rw-r--r-- | src/util/util.h | 29 |
12 files changed, 471 insertions, 459 deletions
@@ -26,7 +26,7 @@ libasound.so.2.0.0: private override CPPFLAGS += -DBYTE_ORDER=__BYTE_ORDER -DLIT libasound.so.2.0.0: private override CFLAGS += -Wno-unused-parameter -Wno-deprecated-declarations libasound.so.2.0.0: private override LDFLAGS += -Wl,--version-script=libasound.map -Wl,-soname,libasound.so.2 libasound.so.2.0.0: private override LDLIBS += -lsndio -libasound.so.2.0.0: libasound.c dsp/dsp.c libasound.map stubs.h symversioning-hell.h +libasound.so.2.0.0: src/libasound.c src/pcm.c src/mixer.c src/util/dsp.c src/util/dsp.h src/util/sysex.h src/util/defs.h src/util/util.h src/stubs.h src/symversioning-hell.h libasound.map $(LINK.c) -shared $(filter %.c,$^) $(LDLIBS) -o $@ libasound.so.2: libasound.so.2.0.0 diff --git a/gen-stubs.bash b/gen-stubs.bash index cd5a6cb..0b9886b 100644 --- a/gen-stubs.bash +++ b/gen-stubs.bash @@ -76,5 +76,5 @@ preprocess() cat include/alsa/*.h | preprocess | match | tr -d ';' | while read -r fun; do name="$(fun_name_for "$fun")" - grep -Fqs "$name(" libasound.c || printf '%s { WARNX1("stub"); %s }\n' "$fun" "$(return_for "$fun" "$name")" + grep -Fqs "$name(" src/{libasound,pcm,mixer}.c || printf '%s { WARNX1("stub"); %s }\n' "$fun" "$(return_for "$fun" "$name")" done diff --git a/src/libasound.c b/src/libasound.c new file mode 100644 index 0000000..b43ae95 --- /dev/null +++ b/src/libasound.c @@ -0,0 +1,173 @@ +#include <alsa/asoundlib.h> +#include <alsa/pcm.h> +#include <alsa/pcm_plugin.h> +#include <alsa/pcm_extplug.h> +#include <alsa/pcm_ioplug.h> +#include <alsa/control_external.h> +#include <alsa/mixer_abst.h> +#include <alsa/use-case.h> +#include <alsa/topology.h> + +#include "util/util.h" +#include "stubs.h" +#include "symversioning-hell.h" + +struct _snd_config { char noop; } s_snd_config; +struct _snd_config *snd_config = &s_snd_config; + +const char* +snd_asoundlib_version(void) +{ + return "1.1.7"; +} + +const char* +snd_strerror(int errnum) +{ + // Do not bother implementing this, just WARN/ERR directly in this lib + // Letting applications show useful error messages never works out + return "^"; +} + +snd_lib_error_handler_t snd_lib_error; + +int snd_lib_error_set_handler(snd_lib_error_handler_t handler) +{ + snd_lib_error = handler; + return 0; +} + +int +snd_card_load(int card) +{ + return 0; +} + +int +snd_card_next(int *card) +{ + if (card) { + *card = (*card == -1 ? 0 : -1); + return 0; + } + + return -1; +} + +int +snd_card_get_index(const char *name) +{ + if (!strcmp(name, "default")) + return 0; + + return -1; +} + +int +snd_card_get_name(int card, char **name) +{ + if (name) *name = "default"; + return 0; +} + +int snd_card_get_longname(int card, char **name) +{ + if (name) *name = "default"; + return 0; +} + +struct device_name_hint { char *name, *ioid; }; + +int +snd_device_name_hint(int card, const char *iface, void ***hints) +{ + static struct device_name_hint defaults[] = { { .name = "default", .ioid = "Output" }, { .name = "capture", .ioid = "Input" } }; + static struct device_name_hint *array[] = { &defaults[0], &defaults[1], NULL }; + *hints = (void**)array; + return 0; +} + +char* +snd_device_name_get_hint(const void *hint, const char *id) +{ + const struct device_name_hint *shint = hint; + + if (!strcmp(id, "NAME")) + return c_strdup(shint->name); + else if (!strcmp(id, "IOID")) + return c_strdup(shint->ioid); + + return NULL; +} + +int +snd_device_name_free_hint(void **hints) +{ + return 0; +} + +struct _snd_ctl { + char noop; +}; + +int +snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode) +{ + if (!(*ctl = calloc(1, sizeof(**ctl)))) { + WARNX1("calloc"); + return -1; + } + + return 0; +} + +int +snd_ctl_close(snd_ctl_t *ctl) +{ + free(ctl); + return 0; +} + +struct _snd_ctl_card_info { + const char *name; +}; + +size_t +snd_ctl_card_info_sizeof(void) +{ + return sizeof(snd_ctl_card_info_t); +} + +int +snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr) +{ + if (!(*ptr = calloc(1, sizeof(**ptr)))) + return -1; + + return 0; +} + +void +snd_ctl_card_info_free(snd_ctl_card_info_t *obj) +{ + free(obj); +} + +int +snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info) +{ + info->name = "sndio"; + return 0; +} + +const char* +snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj) +{ + return obj->name; +} + +const char* +snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj) +{ + return obj->name; +} diff --git a/src/mixer.c b/src/mixer.c new file mode 100644 index 0000000..317f12c --- /dev/null +++ b/src/mixer.c @@ -0,0 +1,264 @@ +#include <alsa/asoundlib.h> +#include <sndio.h> +#include <stdbool.h> +#include <stdio.h> +#include "util/sysex.h" +#include "util/util.h" + +struct _snd_mixer_elem { + snd_mixer_elem_t *next; + char name[SYSEX_NAMELEN]; + unsigned int index, vol; +}; + +struct _snd_mixer { + struct mio_hdl *hdl; + snd_mixer_elem_t *controls; +}; + +#define MIXER_MAX_CHANNELS 16 + +static bool +onsysex(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]) +{ + if (len < SYSEX_SIZE(empty)) + return false; + + union { + struct sysex x; + unsigned char buf[sizeof(struct sysex)]; + } u; + + memcpy(u.buf, buf, len); + + if (u.x.type == SYSEX_TYPE_RT && u.x.id0 == SYSEX_CONTROL && u.x.id1 == SYSEX_MASTER) { + if (len == SYSEX_SIZE(master)) { + controls[0].vol = u.x.u.master.coarse; + snprintf(controls[0].name, sizeof(controls[0].name), "master"); + } + return false; + } + + if (u.x.type != SYSEX_TYPE_EDU || u.x.id0 != SYSEX_AUCAT) + return false; + + switch (u.x.id1) { + case SYSEX_AUCAT_MIXINFO: { + unsigned cn = u.x.u.mixinfo.chan; + if (cn >= MIXER_MAX_CHANNELS || !memchr(u.x.u.mixinfo.name, '\0', SYSEX_NAMELEN)) + return false; + + snprintf(controls[cn + 1].name, sizeof(controls[cn + 1].name), "%s", u.x.u.mixinfo.name); + break; + } + + case SYSEX_AUCAT_DUMPEND: + return true; + } + + return false; +} + +static void +oncommon(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]) +{ +#define MIDI_CMDMASK 0xf0 +#define MIDI_CTL 0xb0 +#define MIDI_CTLVOL 7 + if ((buf[0] & MIDI_CMDMASK) != MIDI_CTL || buf[1] != MIDI_CTLVOL) + return; + +#define MIDI_CHANMASK 0x0f + unsigned cn = (buf[0] & MIDI_CHANMASK); + if (cn >= MIXER_MAX_CHANNELS) + return; + + controls[cn + 1].vol = buf[2]; +} + +static void +get_controls(snd_mixer_t *mixer) +{ + const unsigned char dumpreq[] = { + SYSEX_START, + SYSEX_TYPE_EDU, + 0, + SYSEX_AUCAT, + SYSEX_AUCAT_DUMPREQ, + SYSEX_END, + }; + + static snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]; + memset(controls, 0, sizeof(controls)); + + unsigned char buf[0x100]; + mio_write(mixer->hdl, dumpreq, sizeof(dumpreq)); + for (int ready = 0; !ready;) { + size_t size; + if (!(size = mio_read(mixer->hdl, buf, sizeof(buf)))) { + WARNX1("mio_read failed"); + return; + } + + static unsigned voice_len[] = { 3, 3, 3, 3, 2, 2, 3 }; + static unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 }; + + unsigned char mmsg[0x100]; + unsigned int mst = 0, midx = 0, mlen = 0; + for (unsigned char *p = buf; size > 0; --size, ++p) { + if (*p >= 0xf8) { + /* clock events */ + } else if (*p >= 0xf0) { + if (mst == SYSEX_START && *p == SYSEX_END && midx < sizeof(mmsg)) { + mmsg[midx++] = *p; + ready = onsysex(mmsg, midx, controls); + continue; + } + + mmsg[0] = *p; + mlen = common_len[*p & 7]; + mst = *p; + midx = 1; + } else if (*p >= 0x80) { + mmsg[0] = *p; + mlen = voice_len[(*p >> 4) & 7]; + mst = *p; + midx = 1; + } else if (mst) { + if (midx == sizeof(mmsg)) + continue; + + if (midx == 0) + mmsg[midx++] = mst; + + mmsg[midx++] = *p; + + if (midx == mlen) { + oncommon(mmsg, midx, controls); + midx = 0; + } + } + } + } + + snd_mixer_elem_t **tail = &mixer->controls; + for (size_t i = 0; i < ARRAY_SIZE(controls); ++i) { + if (!controls[i].name[0]) + continue; + + *tail = &controls[i]; + tail = &(*tail)->next; + } +} + +int +snd_mixer_open(snd_mixer_t **mixer, int mode) +{ + if (!(*mixer = calloc(1, sizeof(**mixer)))) { + WARNX1("calloc"); + return -1; + } + + if (!((*mixer)->hdl = mio_open("snd/0", MIO_OUT | MIO_IN, 0))) { + WARNX1("mio_open failed"); + goto fail; + } + + get_controls(*mixer); + return 0; + +fail: + free(*mixer); + return -1; +} + +int +snd_mixer_close(snd_mixer_t *mixer) +{ + mio_close(mixer->hdl); + free(mixer); + return 0; +} + +struct _snd_mixer_selem_id { + char noop; +}; + +int +snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr) +{ + if (!(*ptr = calloc(1, sizeof(**ptr)))) + return -1; + + return 0; +} + +void +snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj) +{ + free(obj); +} + +snd_mixer_elem_t* +snd_mixer_first_elem(snd_mixer_t *mixer) +{ + return mixer->controls; +} + +snd_mixer_elem_t* +snd_mixer_elem_next(snd_mixer_elem_t *elem) +{ + return elem->next; +} + +const char* +snd_mixer_selem_get_name(snd_mixer_elem_t *elem) +{ + return elem->name; +} + +int +snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) +{ + if (value) *value = ((float)elem->vol / (float)0x7f) * 100; + return 0; +} + +int +snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) +{ + if (value) *value = (long)elem->vol - 0x7f; + return 0; +} + +int +snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, long *min, long *max) +{ + if (max) *max = 0; + if (min) *min = -127; + return 0; +} + +int +snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem) +{ + return true; +} + +int +snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem) +{ + return true; +} + +int +snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem) +{ + return true; +} + +int +snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem) +{ + return true; +} @@ -1,138 +1,10 @@ #include <alsa/asoundlib.h> -#include <alsa/pcm.h> -#include <alsa/pcm_plugin.h> -#include <alsa/pcm_extplug.h> -#include <alsa/pcm_ioplug.h> -#include <alsa/control_external.h> -#include <alsa/mixer_abst.h> -#include <alsa/use-case.h> -#include <alsa/topology.h> - #include <sndio.h> +#include <poll.h> #include <stdbool.h> #include <assert.h> -#include <err.h> -#include <poll.h> - -#include "dsp/dsp.h" -#include "sysex.h" - -#define WARN1(x) do { warn("asound: %s %s", __func__, x); } while (0) -#define WARN(x, ...) do { warn("asound: %s " x, __func__, ##__VA_ARGS__); } while (0) -#define WARNX1(x) do { warnx("asound: %s %s", __func__, x); } while (0) -#define WARNX(x, ...) do { warnx("asound: %s " x, __func__, ##__VA_ARGS__); } while (0) -#define ERRX1(x, y) do { errx(x, "asound: %s %s", __func__, y); } while (0) -#define ERRX(x, y, ...) do { errx(x, "asound: %s " y, __func__, ##__VA_ARGS__); } while (0) -#define ERR(x, y, ...) do { err(x, "asound: %s " y, __func__, ##__VA_ARGS__); } while (0) - -#include "stubs.h" - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -const char* -snd_asoundlib_version(void) -{ - return "1.1.7"; -} - -const char* -snd_strerror(int errnum) -{ - // Do not bother implementing this, just WARN/ERR directly in this lib - // Letting applications show useful error messages never works out - return "^"; -} - -snd_lib_error_handler_t snd_lib_error; - -int snd_lib_error_set_handler(snd_lib_error_handler_t handler) -{ - snd_lib_error = handler; - return 0; -} - -struct _snd_config { char noop; } s_snd_config; -struct _snd_config *snd_config = &s_snd_config; - -int -snd_card_load(int card) -{ - return 0; -} - -int -snd_card_next(int *card) -{ - if (card) { - *card = (*card == -1 ? 0 : -1); - return 0; - } - return -1; -} - -int -snd_card_get_index(const char *name) -{ - if (!strcmp(name, "default")) - return 0; - return -1; -} - -int -snd_card_get_name(int card, char **name) -{ - if (name) *name = "default"; - return 0; -} - -int snd_card_get_longname(int card, char **name) -{ - if (name) *name = "default"; - return 0; -} - -struct _snd_pcm_hint { char *name, *ioid; }; - -int -snd_device_name_hint(int card, const char *iface, void ***hints) -{ - static struct _snd_pcm_hint defaults[] = { { .name = "default", .ioid = "Output" }, { .name = "capture", .ioid = "Input" } }; - static struct _snd_pcm_hint *array[] = { &defaults[0], &defaults[1], NULL }; - *hints = (void**)array; - return 0; -} - -static char* -c_strdup(const char *str) -{ - size_t len = strlen(str); - - char *copy; - if (!(copy = calloc(1, len + 1))) - return NULL; - - memcpy(copy, str, len); - return copy; -} - -char* -snd_device_name_get_hint(const void *hint, const char *id) -{ - const struct _snd_pcm_hint *shint = hint; - - if (!strcmp(id, "NAME")) - return c_strdup(shint->name); - else if (!strcmp(id, "IOID")) - return c_strdup(shint->ioid); - - return NULL; -} - -int -snd_device_name_free_hint(void **hints) -{ - return 0; -} +#include "util/dsp.h" +#include "util/util.h" struct _snd_pcm_hw_params { struct sio_cap cap; @@ -1036,329 +908,3 @@ snd_pcm_get_chmap(snd_pcm_t *pcm) return map; } - -struct _snd_ctl { - char noop; -}; - -int -snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode) -{ - if (!(*ctl = calloc(1, sizeof(**ctl)))) { - WARNX1("calloc"); - return -1; - } - - return 0; -} - -int -snd_ctl_close(snd_ctl_t *ctl) -{ - free(ctl); - return 0; -} - -struct _snd_ctl_card_info { - const char *name; -}; - -size_t -snd_ctl_card_info_sizeof(void) -{ - return sizeof(snd_ctl_card_info_t); -} - -int -snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr) -{ - if (!(*ptr = calloc(1, sizeof(**ptr)))) - return -1; - - return 0; -} - -void -snd_ctl_card_info_free(snd_ctl_card_info_t *obj) -{ - free(obj); -} - -int -snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info) -{ - info->name = "sndio"; - return 0; -} - -const char* -snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj) -{ - return obj->name; -} - -const char* -snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj) -{ - return obj->name; -} - -struct _snd_mixer_elem { - snd_mixer_elem_t *next; - char name[SYSEX_NAMELEN]; - unsigned int index, vol; -}; - -struct _snd_mixer { - struct mio_hdl *hdl; - snd_mixer_elem_t *controls; -}; - -#define MIXER_MAX_CHANNELS 16 - -static bool -onsysex(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]) -{ - if (len < SYSEX_SIZE(empty)) - return false; - - union { - struct sysex x; - unsigned char buf[sizeof(struct sysex)]; - } u; - - memcpy(u.buf, buf, len); - - if (u.x.type == SYSEX_TYPE_RT && u.x.id0 == SYSEX_CONTROL && u.x.id1 == SYSEX_MASTER) { - if (len == SYSEX_SIZE(master)) { - controls[0].vol = u.x.u.master.coarse; - snprintf(controls[0].name, sizeof(controls[0].name), "master"); - } - return false; - } - - if (u.x.type != SYSEX_TYPE_EDU || u.x.id0 != SYSEX_AUCAT) - return false; - - switch (u.x.id1) { - case SYSEX_AUCAT_MIXINFO: { - unsigned cn = u.x.u.mixinfo.chan; - if (cn >= MIXER_MAX_CHANNELS || !memchr(u.x.u.mixinfo.name, '\0', SYSEX_NAMELEN)) - return false; - - snprintf(controls[cn + 1].name, sizeof(controls[cn + 1].name), "%s", u.x.u.mixinfo.name); - break; - } - - case SYSEX_AUCAT_DUMPEND: - return true; - } - - return false; -} - -static void -oncommon(unsigned char *buf, unsigned len, snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]) -{ -#define MIDI_CMDMASK 0xf0 -#define MIDI_CTL 0xb0 -#define MIDI_CTLVOL 7 - if ((buf[0] & MIDI_CMDMASK) != MIDI_CTL || buf[1] != MIDI_CTLVOL) - return; - -#define MIDI_CHANMASK 0x0f - unsigned cn = (buf[0] & MIDI_CHANMASK); - if (cn >= MIXER_MAX_CHANNELS) - return; - - controls[cn + 1].vol = buf[2]; -} - -static void -get_controls(snd_mixer_t *mixer) -{ - const unsigned char dumpreq[] = { - SYSEX_START, - SYSEX_TYPE_EDU, - 0, - SYSEX_AUCAT, - SYSEX_AUCAT_DUMPREQ, - SYSEX_END, - }; - - static snd_mixer_elem_t controls[MIXER_MAX_CHANNELS + 1]; - memset(controls, 0, sizeof(controls)); - - unsigned char buf[0x100]; - mio_write(mixer->hdl, dumpreq, sizeof(dumpreq)); - for (int ready = 0; !ready;) { - size_t size; - if (!(size = mio_read(mixer->hdl, buf, sizeof(buf)))) { - WARNX1("mio_read failed"); - return; - } - - static unsigned voice_len[] = { 3, 3, 3, 3, 2, 2, 3 }; - static unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 }; - - unsigned char mmsg[0x100]; - unsigned int mst = 0, midx = 0, mlen = 0; - for (unsigned char *p = buf; size > 0; --size, ++p) { - if (*p >= 0xf8) { - /* clock events */ - } else if (*p >= 0xf0) { - if (mst == SYSEX_START && *p == SYSEX_END && midx < sizeof(mmsg)) { - mmsg[midx++] = *p; - ready = onsysex(mmsg, midx, controls); - continue; - } - - mmsg[0] = *p; - mlen = common_len[*p & 7]; - mst = *p; - midx = 1; - } else if (*p >= 0x80) { - mmsg[0] = *p; - mlen = voice_len[(*p >> 4) & 7]; - mst = *p; - midx = 1; - } else if (mst) { - if (midx == sizeof(mmsg)) - continue; - - if (midx == 0) - mmsg[midx++] = mst; - - mmsg[midx++] = *p; - - if (midx == mlen) { - oncommon(mmsg, midx, controls); - midx = 0; - } - } - } - } - - snd_mixer_elem_t **tail = &mixer->controls; - for (size_t i = 0; i < ARRAY_SIZE(controls); ++i) { - if (!controls[i].name[0]) - continue; - - *tail = &controls[i]; - tail = &(*tail)->next; - } -} - -int -snd_mixer_open(snd_mixer_t **mixer, int mode) -{ - if (!(*mixer = calloc(1, sizeof(**mixer)))) { - WARNX1("calloc"); - return -1; - } - - if (!((*mixer)->hdl = mio_open("snd/0", MIO_OUT | MIO_IN, 0))) { - WARNX1("mio_open failed"); - goto fail; - } - - get_controls(*mixer); - return 0; - -fail: - free(*mixer); - return -1; -} - -int -snd_mixer_close(snd_mixer_t *mixer) -{ - mio_close(mixer->hdl); - free(mixer); - return 0; -} - -struct _snd_mixer_selem_id { - char noop; -}; - -int -snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr) -{ - if (!(*ptr = calloc(1, sizeof(**ptr)))) - return -1; - - return 0; -} - -void -snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj) -{ - free(obj); -} - -snd_mixer_elem_t* -snd_mixer_first_elem(snd_mixer_t *mixer) -{ - return mixer->controls; -} - -snd_mixer_elem_t* -snd_mixer_elem_next(snd_mixer_elem_t *elem) -{ - return elem->next; -} - -const char* -snd_mixer_selem_get_name(snd_mixer_elem_t *elem) -{ - return elem->name; -} - -int -snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) -{ - if (value) *value = ((float)elem->vol / (float)0x7f) * 100; - return 0; -} - -int -snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) -{ - if (value) *value = (long)elem->vol - 0x7f; - return 0; -} - -int -snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, long *min, long *max) -{ - if (max) *max = 0; - if (min) *min = -127; - return 0; -} - -int -snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem) -{ - return true; -} - -int -snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem) -{ - return true; -} - -int -snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem) -{ - return true; -} - -int -snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem) -{ - return true; -} - -#include "symversioning-hell.h" diff --git a/symversioning-hell.h b/src/symversioning-hell.h index f3e9b35..f3e9b35 100644 --- a/symversioning-hell.h +++ b/src/symversioning-hell.h diff --git a/dsp/defs.h b/src/util/defs.h index 6cfc877..6cfc877 100644 --- a/dsp/defs.h +++ b/src/util/defs.h diff --git a/dsp/dsp.c b/src/util/dsp.c index 62510b9..62510b9 100644 --- a/dsp/dsp.c +++ b/src/util/dsp.c diff --git a/dsp/dsp.h b/src/util/dsp.h index d057d37..d057d37 100644 --- a/dsp/dsp.h +++ b/src/util/dsp.h diff --git a/sysex.h b/src/util/sysex.h index 245cd2a..245cd2a 100644 --- a/sysex.h +++ b/src/util/sysex.h diff --git a/src/util/util.h b/src/util/util.h new file mode 100644 index 0000000..9e118c2 --- /dev/null +++ b/src/util/util.h @@ -0,0 +1,29 @@ +#pragma once + +#include <stdlib.h> +#include <string.h> +#include <stddef.h> +#include <err.h> + +#define WARN1(x) do { warn("asound: %s %s", __func__, x); } while (0) +#define WARN(x, ...) do { warn("asound: %s " x, __func__, ##__VA_ARGS__); } while (0) +#define WARNX1(x) do { warnx("asound: %s %s", __func__, x); } while (0) +#define WARNX(x, ...) do { warnx("asound: %s " x, __func__, ##__VA_ARGS__); } while (0) +#define ERRX1(x, y) do { errx(x, "asound: %s %s", __func__, y); } while (0) +#define ERRX(x, y, ...) do { errx(x, "asound: %s " y, __func__, ##__VA_ARGS__); } while (0) +#define ERR(x, y, ...) do { err(x, "asound: %s " y, __func__, ##__VA_ARGS__); } while (0) + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static inline char* +c_strdup(const char *str) +{ + size_t len = strlen(str); + + char *copy; + if (!(copy = calloc(1, len + 1))) + return NULL; + + memcpy(copy, str, len); + return copy; +} |