aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:18:10 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:18:10 +0000
commit55ee3250937343f118e4f6b45aa7647e2cc3ce07 (patch)
tree879bb1b36ec8e65bef67135b6fdc634f58f77b7f
parent4d37e1a4e6c8aaadea3ac2e1d85156851e4e7a48 (diff)
parenta5afe506835ea6acd809320c55c578a6292f9d61 (diff)
downloadtinyalsa-android14-mainline-uwb-release.tar.gz
Change-Id: Icf59f81cbc3beab8517d515e3685b64b1d182f73
-rw-r--r--mixer.c2
-rw-r--r--pcm.c78
-rw-r--r--tinyplay.c15
3 files changed, 53 insertions, 42 deletions
diff --git a/mixer.c b/mixer.c
index fd0ad8d..506e0ef 100644
--- a/mixer.c
+++ b/mixer.c
@@ -388,7 +388,7 @@ struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name)
unsigned int n;
int hw_ctl_count;
- if (!mixer)
+ if (!mixer || !name)
return NULL;
hw_ctl_count = mixer_grp_get_count(mixer->hw_grp);
diff --git a/pcm.c b/pcm.c
index 1709be9..6d7dc29 100644
--- a/pcm.c
+++ b/pcm.c
@@ -26,6 +26,7 @@
** DAMAGE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
@@ -253,11 +254,11 @@ static void param_init(struct snd_pcm_hw_params *p)
struct pcm {
int fd;
unsigned int flags;
- int running:1;
- int prepared:1;
+ bool running:1;
+ bool prepared:1;
int underruns;
unsigned int buffer_size;
- unsigned int boundary;
+ unsigned long boundary;
char error[PCM_ERROR_MAX];
struct pcm_config config;
struct snd_pcm_mmap_status *mmap_status;
@@ -465,7 +466,7 @@ static int pcm_mmap_transfer_areas(struct pcm *pcm, char *buf,
int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
struct timespec *tstamp)
{
- int frames;
+ snd_pcm_sframes_t frames;
int rc;
snd_pcm_uframes_t hw_ptr;
@@ -488,11 +489,12 @@ int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
if (pcm->flags & PCM_IN)
frames = hw_ptr - pcm->mmap_control->appl_ptr;
else
- frames = hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
+ frames = hw_ptr + (snd_pcm_uframes_t) pcm->buffer_size -
+ pcm->mmap_control->appl_ptr;
if (frames < 0)
frames += pcm->boundary;
- else if (frames > (int)pcm->boundary)
+ else if (frames >= (snd_pcm_sframes_t) pcm->boundary)
frames -= pcm->boundary;
*avail = (unsigned int)frames;
@@ -549,12 +551,12 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
return prepare_error;
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
return oops(pcm, errno, "cannot write initial data");
- pcm->running = 1;
+ pcm->running = true;
return 0;
}
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
- pcm->prepared = 0;
- pcm->running = 0;
+ pcm->prepared = false;
+ pcm->running = false;
if (errno == EPIPE) {
/* we failed to make our window -- try to restart if we are
* allowed to do so. Otherwise, simply allow the EPIPE error to
@@ -589,8 +591,8 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
}
}
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
- pcm->prepared = 0;
- pcm->running = 0;
+ pcm->prepared = false;
+ pcm->running = false;
if (errno == EPIPE) {
/* we failed to make our window -- try to restart */
pcm->underruns++;
@@ -891,8 +893,8 @@ int pcm_close(struct pcm *pcm)
if (pcm->snd_node)
snd_utils_put_dev_node(pcm->snd_node);
- pcm->prepared = 0;
- pcm->running = 0;
+ pcm->prepared = false;
+ pcm->running = false;
pcm->buffer_size = 0;
pcm->fd = -1;
free(pcm);
@@ -1029,15 +1031,12 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
sparams.xfer_align = config->period_size / 2; /* needed for old kernels */
sparams.silence_threshold = config->silence_threshold;
sparams.silence_size = config->silence_size;
- pcm->boundary = sparams.boundary = pcm->buffer_size;
-
- while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
- pcm->boundary *= 2;
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
oops(&bad_pcm, errno, "cannot set sw params");
goto fail;
}
+ pcm->boundary = sparams.boundary;
rc = pcm_hw_mmap_status(pcm);
if (rc < 0) {
@@ -1084,7 +1083,7 @@ int pcm_prepare(struct pcm *pcm)
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_PREPARE) < 0)
return oops(pcm, errno, "cannot prepare channel");
- pcm->prepared = 1;
+ pcm->prepared = true;
return 0;
}
@@ -1100,7 +1099,7 @@ int pcm_start(struct pcm *pcm)
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_START) < 0)
return oops(pcm, errno, "cannot start channel");
- pcm->running = 1;
+ pcm->running = true;
return 0;
}
@@ -1109,50 +1108,53 @@ int pcm_stop(struct pcm *pcm)
if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_DROP) < 0)
return oops(pcm, errno, "cannot stop channel");
- pcm->prepared = 0;
- pcm->running = 0;
+ pcm->prepared = false;
+ pcm->running = false;
return 0;
}
-static inline int pcm_mmap_playback_avail(struct pcm *pcm)
+static inline long pcm_mmap_playback_avail(struct pcm *pcm)
{
- int avail;
-
- avail = pcm->mmap_status->hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
+ long avail = pcm->mmap_status->hw_ptr + (unsigned long) pcm->buffer_size -
+ pcm->mmap_control->appl_ptr;
- if (avail < 0)
+ if (avail < 0) {
avail += pcm->boundary;
- else if (avail > (int)pcm->boundary)
+ } else if ((unsigned long) avail >= pcm->boundary) {
avail -= pcm->boundary;
+ }
return avail;
}
-static inline int pcm_mmap_capture_avail(struct pcm *pcm)
+static inline long pcm_mmap_capture_avail(struct pcm *pcm)
{
- int avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr;
- if (avail < 0)
+ long avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr;
+ if (avail < 0) {
avail += pcm->boundary;
+ }
return avail;
}
int pcm_mmap_avail(struct pcm *pcm)
{
pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC);
- if (pcm->flags & PCM_IN)
- return pcm_mmap_capture_avail(pcm);
- else
- return pcm_mmap_playback_avail(pcm);
+ if (pcm->flags & PCM_IN) {
+ return (int) pcm_mmap_capture_avail(pcm);
+ } else {
+ return (int) pcm_mmap_playback_avail(pcm);
+ }
}
static void pcm_mmap_appl_forward(struct pcm *pcm, int frames)
{
- unsigned int appl_ptr = pcm->mmap_control->appl_ptr;
+ unsigned long appl_ptr = pcm->mmap_control->appl_ptr;
appl_ptr += frames;
/* check for boundary wrap */
- if (appl_ptr > pcm->boundary)
+ if (appl_ptr >= pcm->boundary) {
appl_ptr -= pcm->boundary;
+ }
pcm->mmap_control->appl_ptr = appl_ptr;
}
@@ -1313,8 +1315,8 @@ int pcm_mmap_transfer(struct pcm *pcm, const void *buffer, unsigned int bytes)
err = pcm_wait(pcm, time);
if (err < 0) {
- pcm->prepared = 0;
- pcm->running = 0;
+ pcm->prepared = false;
+ pcm->running = false;
oops(pcm, errno, "wait error: hw 0x%x app 0x%x avail 0x%x\n",
(unsigned int)pcm->mmap_status->hw_ptr,
(unsigned int)pcm->mmap_control->appl_ptr,
diff --git a/tinyplay.c b/tinyplay.c
index 8928d92..c5bb71f 100644
--- a/tinyplay.c
+++ b/tinyplay.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <signal.h>
#include <endian.h>
+#include <unistd.h>
#define ID_RIFF 0x46464952
#define ID_WAVE 0x45564157
@@ -59,7 +60,7 @@ struct chunk_fmt {
uint16_t bits_per_sample;
};
-static int close = 0;
+static int closing = 0;
void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
unsigned int rate, unsigned int bits, unsigned int period_size,
@@ -69,7 +70,7 @@ void stream_close(int sig)
{
/* allow the stream to be closed gracefully */
signal(sig, SIG_IGN);
- close = 1;
+ closing = 1;
}
int main(int argc, char **argv)
@@ -270,7 +271,15 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
}
data_sz -= num_read;
}
- } while (!close && num_read > 0 && data_sz > 0);
+ } while (!closing && num_read > 0 && data_sz > 0);
+
+ if (!closing) {
+ // drain the data in the ALSA ring buffer before closing the PCM device
+ unsigned long sleep_time_in_us =
+ (unsigned long) pcm_get_buffer_size(pcm) * 1000UL / ((unsigned long) rate / 1000UL);
+ printf("Draining... Wait %lu us\n", sleep_time_in_us);
+ usleep(sleep_time_in_us);
+ }
free(buffer);
pcm_close(pcm);