From 9c9a44299900695a91aa50a2751f903144bd3a0f Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 16:05:19 +0800 Subject: AOSP CL "Add pcm_params string conversion and format checking" https://android.googlesource.com/platform/external/tinyalsa/+/70530a69767a9a383c5bf546e6e803aac08a5a1e%5E!/ title: Add pcm_params string conversion and format checking commit 70530a69767a9a383c5bf546e6e803aac08a5a1e author Andy Hung --- include/tinyalsa/pcm.h | 15 +++++ src/pcm.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index 1184d81..5191882 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -264,6 +264,21 @@ unsigned int pcm_params_get_min(const struct pcm_params *pcm_params, enum pcm_pa unsigned int pcm_params_get_max(const struct pcm_params *pcm_params, enum pcm_param param); +/* Converts the pcm parameters to a human readable string. + * The string parameter is a caller allocated buffer of size bytes, + * which is then filled up to size - 1 and null terminated, + * if size is greater than zero. + * The return value is the number of bytes copied to string + * (not including null termination) if less than size; otherwise, + * the number of bytes required for the buffer. + */ +int pcm_params_to_string(struct pcm_params *params, char *string, unsigned int size); + +/* Returns 1 if the pcm_format is present (format bit set) in + * the pcm_params structure; 0 otherwise, or upon unrecognized format. + */ +int pcm_params_format_test(struct pcm_params *params, enum pcm_format format); + struct pcm; struct pcm *pcm_open(unsigned int card, diff --git a/src/pcm.c b/src/pcm.c index 3f5ae0a..406ac8d 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -70,6 +70,83 @@ #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) #endif /* SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP */ +/* Logs information into a string; follows snprintf() in that + * offset may be greater than size, and though no characters are copied + * into string, characters are still counted into offset. */ +#define STRLOG(string, offset, size, ...) \ + do { int temp, clipoffset = offset > size ? size : offset; \ + temp = snprintf(string + clipoffset, size - clipoffset, __VA_ARGS__); \ + if (temp > 0) offset += temp; } while (0) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +/* refer to SNDRV_PCM_ACCESS_##index in sound/asound.h. */ +static const char * const access_lookup[] = { + "MMAP_INTERLEAVED", + "MMAP_NONINTERLEAVED", + "MMAP_COMPLEX", + "RW_INTERLEAVED", + "RW_NONINTERLEAVED", +}; + +/* refer to SNDRV_PCM_FORMAT_##index in sound/asound.h. */ +static const char * const format_lookup[] = { + /*[0] =*/ "S8", + "U8", + "S16_LE", + "S16_BE", + "U16_LE", + "U16_BE", + "S24_LE", + "S24_BE", + "U24_LE", + "U24_BE", + "S32_LE", + "S32_BE", + "U32_LE", + "U32_BE", + "FLOAT_LE", + "FLOAT_BE", + "FLOAT64_LE", + "FLOAT64_BE", + "IEC958_SUBFRAME_LE", + "IEC958_SUBFRAME_BE", + "MU_LAW", + "A_LAW", + "IMA_ADPCM", + "MPEG", + /*[24] =*/ "GSM", + /* gap */ + [31] = "SPECIAL", + "S24_3LE", + "S24_3BE", + "U24_3LE", + "U24_3BE", + "S20_3LE", + "S20_3BE", + "U20_3LE", + "U20_3BE", + "S18_3LE", + "S18_3BE", + "U18_3LE", + /*[43] =*/ "U18_3BE", +#if 0 + /* recent additions, may not be present on local asound.h */ + "G723_24", + "G723_24_1B", + "G723_40", + "G723_40_1B", + "DSD_U8", + "DSD_U16_LE", +#endif +}; + +/* refer to SNDRV_PCM_SUBFORMAT_##index in sound/asound.h. */ +static const char * const subformat_lookup[] = { + "STD", +}; static inline int param_is_mask(int p) { @@ -798,6 +875,87 @@ unsigned int pcm_params_get_max(const struct pcm_params *pcm_params, return param_get_max(params, p); } +static int pcm_mask_test(const struct pcm_mask *m, unsigned int index) +{ + const unsigned int bitshift = 5; /* for 32 bit integer */ + const unsigned int bitmask = (1 << bitshift) - 1; + unsigned int element; + + element = index >> bitshift; + if (element >= ARRAY_SIZE(m->bits)) + return 0; /* for safety, but should never occur */ + return (m->bits[element] >> (index & bitmask)) & 1; +} + +static int pcm_mask_to_string(const struct pcm_mask *m, char *string, unsigned int size, + char *mask_name, + const char * const *bit_array_name, size_t bit_array_size) +{ + unsigned int i; + unsigned int offset = 0; + + if (m == NULL) + return 0; + if (bit_array_size < 32) { + STRLOG(string, offset, size, "%12s:\t%#08x\n", mask_name, m->bits[0]); + } else { /* spans two or more bitfields, print with an array index */ + for (i = 0; i < (bit_array_size + 31) >> 5; ++i) { + STRLOG(string, offset, size, "%9s[%d]:\t%#08x\n", + mask_name, i, m->bits[i]); + } + } + for (i = 0; i < bit_array_size; ++i) { + if (pcm_mask_test(m, i)) { + STRLOG(string, offset, size, "%12s \t%s\n", "", bit_array_name[i]); + } + } + return offset; +} + +int pcm_params_to_string(struct pcm_params *params, char *string, unsigned int size) +{ + const struct pcm_mask *m; + unsigned int min, max; + unsigned int clipoffset, offset; + + m = pcm_params_get_mask(params, PCM_PARAM_ACCESS); + offset = pcm_mask_to_string(m, string, size, + "Access", access_lookup, ARRAY_SIZE(access_lookup)); + m = pcm_params_get_mask(params, PCM_PARAM_FORMAT); + clipoffset = offset > size ? size : offset; + offset += pcm_mask_to_string(m, string + clipoffset, size - clipoffset, + "Format", format_lookup, ARRAY_SIZE(format_lookup)); + m = pcm_params_get_mask(params, PCM_PARAM_SUBFORMAT); + clipoffset = offset > size ? size : offset; + offset += pcm_mask_to_string(m, string + clipoffset, size - clipoffset, + "Subformat", subformat_lookup, ARRAY_SIZE(subformat_lookup)); + min = pcm_params_get_min(params, PCM_PARAM_RATE); + max = pcm_params_get_max(params, PCM_PARAM_RATE); + STRLOG(string, offset, size, " Rate:\tmin=%uHz\tmax=%uHz\n", min, max); + min = pcm_params_get_min(params, PCM_PARAM_CHANNELS); + max = pcm_params_get_max(params, PCM_PARAM_CHANNELS); + STRLOG(string, offset, size, " Channels:\tmin=%u\t\tmax=%u\n", min, max); + min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS); + max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS); + STRLOG(string, offset, size, " Sample bits:\tmin=%u\t\tmax=%u\n", min, max); + min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE); + max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE); + STRLOG(string, offset, size, " Period size:\tmin=%u\t\tmax=%u\n", min, max); + min = pcm_params_get_min(params, PCM_PARAM_PERIODS); + max = pcm_params_get_max(params, PCM_PARAM_PERIODS); + STRLOG(string, offset, size, "Period count:\tmin=%u\t\tmax=%u\n", min, max); + return offset; +} + +int pcm_params_format_test(struct pcm_params *params, enum pcm_format format) +{ + unsigned int alsa_format = pcm_format_to_alsa(format); + + if (alsa_format == SNDRV_PCM_FORMAT_S16_LE && format != PCM_FORMAT_S16_LE) + return 0; /* caution: format not recognized is equivalent to S16_LE */ + return pcm_mask_test(pcm_params_get_mask(params, PCM_PARAM_FORMAT), alsa_format); +} + /** Closes a PCM returned by @ref pcm_open. * @param pcm A PCM returned by @ref pcm_open. * May not be NULL. -- cgit v1.2.3 From 1e75a165df625396afd68bbc68a59c517727c3e6 Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 17:37:19 +0800 Subject: AOSP CL "pcm: add support to set silence_size" https://android.googlesource.com/platform/external/tinyalsa/+/e25fe0b50ea717a9f347dcb927d396e8772e6362 commit e25fe0b50ea717a9f347dcb927d396e8772e6362 author Maneet Singh pcm: add support to set silence_size Tinyalsa always set silence_size to zero. Add support to set this pcm software parameter as required. Bug: 20226809 Bug: 20300203 Change-Id: I25de43623dc04bf5a3ad4c6573bc2b8dad1eec5e --- include/tinyalsa/pcm.h | 11 ++++++++--- src/pcm.c | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index 5191882..f32e11d 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -202,13 +202,15 @@ struct pcm_config { unsigned int period_count; /** The sample format of a PCM */ enum pcm_format format; - /* Values to use for the ALSA start, stop and silence thresholds. Setting - * any one of these values to 0 will cause the default tinyalsa values to be - * used instead. Tinyalsa defaults are as follows. + /* Values to use for the ALSA start, stop and silence thresholds, and + * silence size. Setting any one of these values to 0 will cause the + * default tinyalsa values to be used instead. + * Tinyalsa defaults are as follows. * * start_threshold : period_count * period_size * stop_threshold : period_count * period_size * silence_threshold : 0 + * silence_size : 0 */ /** The minimum number of frames required to start the PCM */ unsigned int start_threshold; @@ -216,6 +218,9 @@ struct pcm_config { unsigned int stop_threshold; /** The minimum number of frames to silence the PCM */ unsigned int silence_threshold; + /** The number of frames to overwrite the playback buffer when the playback underrun is greater + * than the silence threshold */ + unsigned int silence_size; }; /** Enumeration of a PCM's hardware parameters. diff --git a/src/pcm.c b/src/pcm.c index 406ac8d..8da3241 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -438,6 +438,7 @@ int pcm_set_config(struct pcm *pcm, const struct pcm_config *config) pcm->config.start_threshold = config->period_count * config->period_size; pcm->config.stop_threshold = config->period_count * config->period_size; pcm->config.silence_threshold = 0; + pcm->config.silence_size = 0; } else pcm->config = *config; @@ -519,7 +520,7 @@ int pcm_set_config(struct pcm *pcm, const struct pcm_config *config) sparams.stop_threshold = config->stop_threshold; sparams.xfer_align = config->period_size / 2; /* needed for old kernels */ - sparams.silence_size = 0; + sparams.silence_size = config->silence_size; sparams.silence_threshold = config->silence_threshold; pcm->boundary = sparams.boundary = pcm->buffer_size; -- cgit v1.2.3 From ed51bc4ba921806690dd0dffe7927031db5739d1 Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 22:09:09 +0800 Subject: AOSP CL "tinyalsa: channel status set as per IEC958" https://android.googlesource.com/platform/external/tinyalsa/+/49a61374fc18a0f39da0d9c11cc9ccc3e9c1ec3f commit 49a61374fc18a0f39da0d9c11cc9ccc3e9c1ec3f author Yogesh Agrawal tinyalsa: channel status set as per IEC958 Add support for modifying the IEC958 structure in a mixer_ctl. Bug: 9428304 Bug: 22576112 Change-Id: I8982340da9403a8a9e36b389fc97e9c635a9f681 --- src/mixer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mixer.c b/src/mixer.c index 6a104fe..fe590e8 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -990,6 +990,11 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count) break; } + case SNDRV_CTL_ELEM_TYPE_IEC958: + size = sizeof(ev.value.iec958); + source = &ev.value.iec958; + break; + default: return -EINVAL; } @@ -1116,6 +1121,11 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) } break; + case SNDRV_CTL_ELEM_TYPE_IEC958: + size = sizeof(ev.value.iec958); + dest = &ev.value.iec958; + break; + default: return -EINVAL; } -- cgit v1.2.3 From 07c8dc2123270f88622ec2d543b844367d500362 Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 22:15:21 +0800 Subject: initialize silence_size to zero --- utils/tinyplay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/tinyplay.c b/utils/tinyplay.c index 20dd7e8..8b01a1d 100644 --- a/utils/tinyplay.c +++ b/utils/tinyplay.c @@ -59,6 +59,7 @@ void cmd_init(struct cmd *cmd) cmd->config.rate = 48000; cmd->config.format = PCM_FORMAT_S16_LE; cmd->config.silence_threshold = 1024 * 2; + cmd->config.silence_size = 0; cmd->config.stop_threshold = 1024 * 2; cmd->config.start_threshold = 1024; cmd->bits = 16; -- cgit v1.2.3 From faaa6972a2846b43366887bc0779c6c1be20a16f Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 22:18:40 +0800 Subject: AOSP CL "Export pcm_mmap_avail" https://android.googlesource.com/platform/external/tinyalsa/+/9074cfc4127cb841f0633b35895141f90da3f0d6 commit 9074cfc4127cb841f0633b35895141f90da3f0d6 author Dylan Reid Export pcm_mmap_avail This is useful for timer based wakeups and for checking how much data has been captured by a hotwording device. Change-Id: I409201a5c9ce73abc807a9dd767beb3a32810f06 Signed-off-by: Dylan Reid --- include/tinyalsa/pcm.h | 2 ++ src/pcm.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index f32e11d..a49746c 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -341,6 +341,8 @@ int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, unsigned int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); +int pcm_mmap_avail(struct pcm *pcm); + int pcm_link(struct pcm *pcm1, struct pcm *pcm2); int pcm_unlink(struct pcm *pcm); diff --git a/src/pcm.c b/src/pcm.c index 8da3241..e88c18c 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -1236,7 +1236,7 @@ static inline int pcm_mmap_capture_avail(struct pcm *pcm) return avail; } -static inline int pcm_mmap_avail(struct pcm *pcm) +int pcm_mmap_avail(struct pcm *pcm) { if (pcm->flags & PCM_IN) return pcm_mmap_capture_avail(pcm); -- cgit v1.2.3 From 72216211c7a5f29510a2f50dbdc70b35af44fb3a Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 22:22:27 +0800 Subject: AOSP CL "Add pcm_get_poll_fd" https://android.googlesource.com/platform/external/tinyalsa/+/b42510d55bafc96805a44bd6ac40faac28ebd219 commit b42510d55bafc96805a44bd6ac40faac28ebd219 author Dylan Reid Add pcm_get_poll_fd Similar to ALSA snd_pcm_get_poll_fd, this will allow a user to wait for a sound device to have data in a poll(2) call. The hotword thread will use this to wait for a message on its socket or for audio data to become ready. Change-Id: I61375a73d7a842b00362fc707c12f99aa18e0bdf Signed-off-by: Dylan Reid --- include/tinyalsa/pcm.h | 2 ++ src/pcm.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index a49746c..99ca786 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -343,6 +343,8 @@ int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); int pcm_mmap_avail(struct pcm *pcm); +int pcm_get_poll_fd(struct pcm *pcm); + int pcm_link(struct pcm *pcm1, struct pcm *pcm2); int pcm_unlink(struct pcm *pcm); diff --git a/src/pcm.c b/src/pcm.c index e88c18c..eb16ed3 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -1344,6 +1344,11 @@ static int pcm_mmap_transfer_areas(struct pcm *pcm, char *buf, return count; } +int pcm_get_poll_fd(struct pcm *pcm) +{ + return pcm->fd; +} + int pcm_avail_update(struct pcm *pcm) { pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_APPL|SNDRV_PCM_SYNC_PTR_AVAIL_MIN); -- cgit v1.2.3 From e43e85c1885d935e36c53fc04c4f1660c2b3fd3a Mon Sep 17 00:00:00 2001 From: dvdli Date: Wed, 28 Oct 2020 22:56:53 +0800 Subject: AOSP CL "pcm: add API for MMAP NO IRQ mode" https://android.googlesource.com/platform/external/tinyalsa/+/5b15b4cbd9e779a4ecd87e0f757fb0f8f6b9bcb8 commit 5b15b4cbd9e779a4ecd87e0f757fb0f8f6b9bcb8 author Eric Laurent pcm: add API for MMAP NO IRQ mode Bug: 33398120 Test: build Change-Id: Iecb47f76337d98ceb01044ca488a04e1f350c6bc --- include/tinyalsa/pcm.h | 2 ++ src/pcm.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h index 99ca786..cdc31a5 100644 --- a/include/tinyalsa/pcm.h +++ b/include/tinyalsa/pcm.h @@ -343,6 +343,8 @@ int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); int pcm_mmap_avail(struct pcm *pcm); +int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr, struct timespec *tstamp); + int pcm_get_poll_fd(struct pcm *pcm); int pcm_link(struct pcm *pcm1, struct pcm *pcm2); diff --git a/src/pcm.c b/src/pcm.c index eb16ed3..3b54ec7 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -1560,6 +1560,34 @@ int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count) return pcm_mmap_transfer(pcm, data, pcm_bytes_to_frames(pcm, count)); } +/* Returns current read/write position in the mmap buffer with associated time stamp. */ +int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr, struct timespec *tstamp) +{ + int rc; + + if (pcm == NULL || hw_ptr == NULL || tstamp == NULL) + return oops(pcm, EINVAL, "pcm %p, hw_ptr %p, tstamp %p", pcm, hw_ptr, tstamp); + + if (!pcm_is_ready(pcm)) + return oops(pcm, errno, "pcm_is_ready failed"); + + rc = pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC); + if (rc < 0) + return oops(pcm, errno, "pcm_sync_ptr failed"); + + if ((pcm->mmap_status->state != PCM_STATE_RUNNING) && + (pcm->mmap_status->state != PCM_STATE_DRAINING)) + return oops(pcm, ENOSYS, "invalid stream state %d", pcm->mmap_status->state); + + *tstamp = pcm->mmap_status->tstamp; + if (tstamp->tv_sec == 0 && tstamp->tv_nsec == 0) + return oops(pcm, errno, "invalid time stamp"); + + *hw_ptr = pcm->mmap_status->hw_ptr; + + return 0; +} + static int pcm_rw_transfer(struct pcm *pcm, void *data, unsigned int frames) { int is_playback; -- cgit v1.2.3 From c0c5e7534011a9a3d64b74e0f20a3417fbbbc290 Mon Sep 17 00:00:00 2001 From: dvdli Date: Thu, 29 Oct 2020 15:32:35 +0800 Subject: AOSP CL "tinyalsa: fix typos in tinyplay and asoundlib.h" commit f451f433520fc154de6e371747f21d2f746da83b author Glenn Kasten tinyalsa: fix typos in tinyplay and asoundlib.h Test: run tinyplay and look for typos in the output Change-Id: Ieedcc1b7610700aa3d5ff913d5c01105db2c1601 --- include/tinyalsa/mixer.h | 2 +- utils/tinyplay.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/tinyalsa/mixer.h b/include/tinyalsa/mixer.h index 2acdd54..77d5d01 100644 --- a/include/tinyalsa/mixer.h +++ b/include/tinyalsa/mixer.h @@ -133,7 +133,7 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count); int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string); -/* Determe range of integer mixer controls */ +/* Determine range of integer mixer controls */ int mixer_ctl_get_range_min(const struct mixer_ctl *ctl); int mixer_ctl_get_range_max(const struct mixer_ctl *ctl); diff --git a/utils/tinyplay.c b/utils/tinyplay.c index 8b01a1d..c006acc 100644 --- a/utils/tinyplay.c +++ b/utils/tinyplay.c @@ -376,8 +376,10 @@ int sample_is_playable(const struct cmd *cmd) can_play = check_param(params, PCM_PARAM_RATE, cmd->config.rate, "sample rate", "hz"); can_play &= check_param(params, PCM_PARAM_CHANNELS, cmd->config.channels, "sample", " channels"); can_play &= check_param(params, PCM_PARAM_SAMPLE_BITS, cmd->bits, "bits", " bits"); - can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, cmd->config.period_size, "period size", ""); - can_play &= check_param(params, PCM_PARAM_PERIODS, cmd->config.period_count, "period count", ""); + can_play &= check_param(params, PCM_PARAM_PERIOD_SIZE, cmd->config.period_size, "period size", + " frames"); + can_play &= check_param(params, PCM_PARAM_PERIODS, cmd->config.period_count, "period count", + " frames"); pcm_params_free(params); -- cgit v1.2.3 From b39234c6a35378abb18e81ea0967331f68fd9029 Mon Sep 17 00:00:00 2001 From: dvdli Date: Thu, 29 Oct 2020 16:24:43 +0800 Subject: AOSP CL "pcm: Fix usage of oops() function for use of strerror." https://android.googlesource.com/platform/external/tinyalsa/+/50028cd233f8cf8a084e950c951eefc01e1cd15c commit 50028cd233f8cf8a084e950c951eefc01e1cd15c author John Muir pcm: Fix usage of oops() function for use of strerror. The oops() function expected errno to be passed in, but at some point it was broken to look at errno itself, and ignore the passed-in value. Fix the oops() function to check the passed-in value, and modify uses of oops() to actually pass in errno and not -errno or the return value from the errored function call. Bug: None Test: pcm error code printed correctly. Change-Id: I555e1eda0cdd0cc9b94e05423d341f1c08f8e485 (cherry picked from commit 2c1d902ace5f78dcff0c39740642d269b2e17dff) Note: the oops in pcm_mmap_transfer was removed. --- src/pcm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pcm.c b/src/pcm.c index 3b54ec7..a175668 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -332,7 +332,7 @@ static int oops(struct pcm *pcm, int e, const char *fmt, ...) va_end(ap); sz = strlen(pcm->error); - if (errno) + if (e) snprintf(pcm->error + sz, PCM_ERROR_MAX - sz, ": %s", strerror(e)); return -1; @@ -455,7 +455,7 @@ int pcm_set_config(struct pcm *pcm, const struct pcm_config *config) if (pcm->flags & PCM_NOIRQ) { if (!(pcm->flags & PCM_MMAP)) { - oops(pcm, -EINVAL, "noirq only currently supported with mmap()."); + oops(pcm, EINVAL, "noirq only currently supported with mmap()."); return -EINVAL; } @@ -1082,7 +1082,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, rc = pcm_hw_mmap_status(pcm); if (rc < 0) { - oops(pcm, rc, "mmap status failed"); + oops(pcm, errno, "mmap status failed"); goto fail; } @@ -1091,7 +1091,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, int arg = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC; rc = pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_TTSTAMP, &arg); if (rc < 0) { - oops(pcm, rc, "cannot set timestamp type"); + oops(pcm, errno, "cannot set timestamp type"); goto fail; } } -- cgit v1.2.3 From dbb6ba612745097ffc317fff327a5408ea17bbc5 Mon Sep 17 00:00:00 2001 From: dvdli Date: Thu, 29 Oct 2020 16:32:44 +0800 Subject: AOSP CL "tinyalsa: check for NULL mmap_status" https://android.googlesource.com/platform/external/tinyalsa/+/62644f7a3c4cfa18d7935f731cf59b675669d17a commit 62644f7a3c4cfa18d7935f731cf59b675669d17a author Phil Burk tinyalsa: check for NULL mmap_status pcm_mmap_get_hw_ptr() was not checking pcm->mmap_status and crashed when it was NULL. Bug: 64346189 Test: input_monitor.cpp, see bug report for repro steps Change-Id: I8436686a231eb01a82dd28ca2cce561d5460bcd6 --- src/pcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pcm.c b/src/pcm.c index a175668..b592780 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -1575,6 +1575,9 @@ int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr, struct timespec * if (rc < 0) return oops(pcm, errno, "pcm_sync_ptr failed"); + if (pcm->mmap_status == NULL) + return oops(pcm, EINVAL, "pcm %p, mmap_status is NULL", pcm); + if ((pcm->mmap_status->state != PCM_STATE_RUNNING) && (pcm->mmap_status->state != PCM_STATE_DRAINING)) return oops(pcm, ENOSYS, "invalid stream state %d", pcm->mmap_status->state); -- cgit v1.2.3 From ee63fc9a456215d88de45881565b7dae71eafb48 Mon Sep 17 00:00:00 2001 From: dvdli Date: Thu, 29 Oct 2020 18:31:55 +0800 Subject: check whether the audio data are still enough to play reference: https://android.googlesource.com/platform/external/tinyalsa/+/8b7274b2ec686c87673bf39328381acbdea1a333 commit 8b7274b2ec686c87673bf39328381acbdea1a333 author Haynes Mathew George tinyplay: play PCM up to size specified in the header tinyplay plays to the end of file without checking whether playback goes beyond end of data section which its size is specified in the RIFF wave header. This could lead to playing out unwanted data which is placed at the end of file. authored-by: Patrick Lai Change-Id: I17bd3f6ebca4813f8987585472208c1f52696cae --- utils/tinyplay.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/utils/tinyplay.c b/utils/tinyplay.c index c006acc..f6762a0 100644 --- a/utils/tinyplay.c +++ b/utils/tinyplay.c @@ -389,13 +389,14 @@ int sample_is_playable(const struct cmd *cmd) int play_sample(struct ctx *ctx) { char *buffer; - int size; - int num_read; + size_t buffer_size = pcm_frames_to_bytes(ctx->pcm, pcm_get_buffer_size(ctx->pcm)); + size_t num_read = 0; + size_t remaining_data_size = ctx->chunk_header.sz; + size_t read_size = 0; - size = pcm_frames_to_bytes(ctx->pcm, pcm_get_buffer_size(ctx->pcm)); - buffer = malloc(size); + buffer = malloc(buffer_size); if (!buffer) { - fprintf(stderr, "unable to allocate %d bytes\n", size); + fprintf(stderr, "unable to allocate %zu bytes\n", buffer_size); return -1; } @@ -403,15 +404,17 @@ int play_sample(struct ctx *ctx) signal(SIGINT, stream_close); do { - num_read = fread(buffer, 1, size, ctx->file); + read_size = remaining_data_size > buffer_size ? buffer_size : remaining_data_size; + num_read = fread(buffer, 1, read_size, ctx->file); if (num_read > 0) { if (pcm_writei(ctx->pcm, buffer, pcm_bytes_to_frames(ctx->pcm, num_read)) < 0) { fprintf(stderr, "error playing sample\n"); break; } + remaining_data_size -= num_read; } - } while (!close && num_read > 0); + } while (!close && num_read > 0 && remaining_data_size > 0); pcm_wait(ctx->pcm, -1); -- cgit v1.2.3 From 877ccaf02b773ad7b995bacbfba8e1bdfe11b00d Mon Sep 17 00:00:00 2001 From: dvdli Date: Thu, 29 Oct 2020 18:38:53 +0800 Subject: AOSP CL "tinymix: fix setting enum str started with digits" https://android.googlesource.com/platform/external/tinyalsa/+/f2d93a540297e75815eeb6644bf675cdae3be909 commit f2d93a540297e75815eeb6644bf675cdae3be909 author HW Lee tinymix: fix setting enum str started with digits For those value strings which are started with digits, they must be set as enum instead of index value. Test: with mixer control values started with digits like '48KHz' Change-Id: I1c70f5613a48d020d3248b71c1e4384f83e33d25 Signed-off-by: HW Lee --- utils/tinymix.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/utils/tinymix.c b/utils/tinymix.c index fdb774c..41ca269 100644 --- a/utils/tinymix.c +++ b/utils/tinymix.c @@ -146,6 +146,16 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } +static int isnumber(const char *str) { + char *end; + + if (str == NULL || strlen(str) == 0) + return 0; + + strtol(str, &end, 0); + return strlen(end) == 0; +} + static void tinymix_list_controls(struct mixer *mixer, int print_all) { struct mixer_ctl *ctl; @@ -201,7 +211,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control) int ret; char *buf = NULL; - if (isdigit(control[0])) + if (isnumber(control)) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); @@ -469,7 +479,7 @@ static int tinymix_set_value(struct mixer *mixer, const char *control, struct mixer_ctl *ctl; enum mixer_ctl_type type; - if (isdigit(control[0])) + if (isnumber(control)) ctl = mixer_get_ctl(mixer, atoi(control)); else ctl = mixer_get_ctl_by_name(mixer, control); -- cgit v1.2.3