summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-11-01 14:33:09 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-11-01 14:33:09 +0200
commit3021e8663b01ab847f04ac96ea942b3ccc2acc34 (patch)
treedfe69a23341c38e8d0f2cba850825db08ee1d686
parent83d5731a087ec01ab3f9fc474c8052ecc902b0de (diff)
steam fixes
-rw-r--r--src/libasound.c24
-rw-r--r--src/pcm.c124
-rw-r--r--src/stubs.h10
3 files changed, 119 insertions, 39 deletions
diff --git a/src/libasound.c b/src/libasound.c
index d7027e9..d1add52 100644
--- a/src/libasound.c
+++ b/src/libasound.c
@@ -308,11 +308,35 @@ snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj)
}
const char*
+snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj)
+{
+ return snd_ctl_card_info_get_name(obj);
+}
+
+const char*
+snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj)
+{
+ return snd_ctl_card_info_get_name(obj);
+}
+
+const char*
+snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj)
+{
+ return snd_ctl_card_info_get_name(obj);
+}
+
+const char*
snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj)
{
return snd_ctl_card_info_get_name(obj);
}
+const char*
+snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj)
+{
+ return snd_ctl_card_info_get_name(obj);
+}
+
int
snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t *info)
{
diff --git a/src/pcm.c b/src/pcm.c
index 9c2f763..c078a92 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -95,13 +95,16 @@ struct _snd_pcm_hw_params {
snd_pcm_format_t supported[ARRAY_SIZE(SUPPORTED_FORMATS)];
unsigned int pchan[2], rchan[2], rate[2];
} limits;
+ int period_time;
snd_pcm_format_t format;
snd_pcm_access_t access;
snd_pcm_stream_t stream;
bool needs_conversion; // for unsupported formats
};
-struct _snd_pcm_sw_params { char noop; };
+struct _snd_pcm_sw_params {
+ snd_pcm_uframes_t avail_min;
+};
struct _snd_pcm {
struct _snd_pcm_hw_params hw;
@@ -239,6 +242,7 @@ snd_pcm_open(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mod
dump_cap(name, &(*pcm)->hw.cap, &(*pcm)->hw.limits);
(*pcm)->hw.format = SND_PCM_FORMAT_UNKNOWN;
+ (*pcm)->hw.period_time = -1;
return 0;
fail:
@@ -310,12 +314,6 @@ snd_pcm_state(snd_pcm_t *pcm)
return SND_PCM_STATE_OPEN;
}
-int
-snd_pcm_wait(snd_pcm_t *pcm, int timeout)
-{
- return 1; // we are always ready for io
-}
-
snd_pcm_sframes_t
snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
{
@@ -438,34 +436,61 @@ snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
return ret;
}
-snd_pcm_sframes_t
-snd_pcm_avail_update(snd_pcm_t *pcm)
+static uint64_t
+get_time_ns(void)
{
- struct pollfd pfd[16];
- int nfds = sio_nfds(pcm->hdl);
- assert((unsigned int)nfds < ARRAY_SIZE(pfd));
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (uint64_t)ts.tv_sec * (uint64_t)1e9 + (uint64_t)ts.tv_nsec;
+}
+
+int
+snd_pcm_wait(snd_pcm_t *pcm, int timeout)
+{
+ while (1) {
+ const uint64_t start = get_time_ns();
+
+ struct pollfd pfd[16];
+ int nfds = sio_nfds(pcm->hdl);
+ assert((unsigned int)nfds < ARRAY_SIZE(pfd));
+
+ const int want = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN);
+ nfds = sio_pollfd(pcm->hdl, pfd, want);
+
+ errno = 0;
+ while ((nfds = poll(pfd, nfds, timeout)) < 0) {
+ if (errno == EINVAL) {
+ WARNX1("poll EINVAL");
+ goto nodata;
+ } else if (errno == EINTR) {
+ WARNX1("poll EINTR");
+ goto nodata;
+ } else if (errno != EAGAIN)
+ goto nodata; // timeout
+ }
- nfds = sio_pollfd(pcm->hdl, pfd, (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN));
+ if (timeout > 0) {
+ const uint64_t delta = ((get_time_ns() - start) / 1e6);
+ if ((uint64_t)timeout <= delta)
+ goto nodata; // timeout;
- // XXX: timeout should be period time/buffer time(?)
- errno = 0;
- while ((nfds = poll(pfd, nfds, -1)) < 0) {
- if (errno == EINVAL) {
- WARNX1("poll EINVAL");
- goto nodata;
+ timeout -= delta;
}
+
+ if (sio_revents(pcm->hdl, pfd) & want)
+ break;
}
+ return 1;
- const int revents = sio_revents(pcm->hdl, pfd);
- if (!(revents & POLLOUT) && !(revents & POLLIN))
- goto nodata;
+nodata:
+ return 0;
+}
+snd_pcm_sframes_t
+snd_pcm_avail_update(snd_pcm_t *pcm)
+{
+ while (snd_pcm_wait(pcm, pcm->hw.period_time) && pcm->avail < pcm->sw.avail_min);
return (pcm->avail > pcm->hw.par.appbufsz ? pcm->hw.par.appbufsz : pcm->avail);
-
-nodata:
- // NOTE: returning 1, as some programs don't check the return value :/ (namely qwebengine)
- // thus they SIGFPE by dividing by 0 or -1
- return 1;
}
snd_pcm_sframes_t
@@ -477,7 +502,7 @@ snd_pcm_avail(snd_pcm_t *pcm)
int
snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{
- if (delayp) *delayp = pcm->written - pcm->position;
+ if (delayp) *delayp = (pcm->hw.stream == SND_PCM_STREAM_PLAYBACK ? pcm->written - pcm->position : pcm->position - pcm->written);
return 0;
}
@@ -845,6 +870,18 @@ snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *para
}
int
+snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
+{
+ return snd_pcm_hw_params_set_buffer_size_near(pcm, params, val);
+}
+
+int
+snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)
+{
+ return snd_pcm_hw_params_set_buffer_size_near(pcm, params, &val);
+}
+
+int
snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)
{
if (val) *val = params->par.appbufsz;
@@ -928,7 +965,22 @@ int
snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
{
if (dir) *dir = 0;
- if (val) *val = 32;
+ if (val) *val = params->par.appbufsz / params->par.round;
+ return 0;
+}
+
+int
+snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir)
+{
+ params->period_time = val / (uint64_t)1e3;
+ return 0;
+}
+
+int
+snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
+{
+ if (dir) *dir = 0;
+ if (val) snd_pcm_hw_params_set_period_time(pcm, params, *val, 0);
return 0;
}
@@ -951,6 +1003,13 @@ snd_pcm_sw_params_free(snd_pcm_sw_params_t *ptr)
}
int
+snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
+{
+ pcm->sw = *params;
+ return 0;
+}
+
+int
snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
{
*params = pcm->sw;
@@ -958,6 +1017,13 @@ snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
}
int
+snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)
+{
+ params->avail_min = val;
+ return 0;
+}
+
+int
snd_pcm_set_params(snd_pcm_t *pcm, snd_pcm_format_t format, snd_pcm_access_t access, unsigned int channels, unsigned int rate, int soft_resample, unsigned int latency)
{
snd_pcm_hw_params_t params;
diff --git a/src/stubs.h b/src/stubs.h
index 4b49cbd..0b66678 100644
--- a/src/stubs.h
+++ b/src/stubs.h
@@ -118,10 +118,6 @@ void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val) { WARNX
void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj) { WARNX1("stub"); }
void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src) { WARNX1("stub"); }
int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj) { WARNX1("stub"); return 0; }
-const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj) { WARNX1("stub"); return NULL; }
-const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj) { WARNX1("stub"); return NULL; }
-const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj) { WARNX1("stub"); return NULL; }
-const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj) { WARNX1("stub"); return NULL; }
size_t snd_ctl_event_sizeof(void) { WARNX1("stub"); return 0; }
int snd_ctl_event_malloc(snd_ctl_event_t **ptr) { WARNX1("stub"); return -1; }
void snd_ctl_event_free(snd_ctl_event_t *obj) { WARNX1("stub"); }
@@ -457,7 +453,6 @@ int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, snd
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler) { WARNX1("stub"); return NULL; }
int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info) { WARNX1("stub"); return 0; }
int snd_pcm_hw_free(snd_pcm_t *pcm) { WARNX1("stub"); return 0; }
-int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { WARNX1("stub"); return 0; }
int snd_pcm_hwsync(snd_pcm_t *pcm) { WARNX1("stub"); return 0; }
int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp) { WARNX1("stub"); return 0; }
int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp) { WARNX1("stub"); return 0; }
@@ -542,11 +537,9 @@ int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigne
int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) { WARNX1("stub"); return 0; }
-int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir) { WARNX1("stub"); return 0; }
-int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir) { WARNX1("stub"); return 0; }
@@ -577,8 +570,6 @@ int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *
int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val) { WARNX1("stub"); return 0; }
-int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val) { WARNX1("stub"); return 0; }
-int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max) { WARNX1("stub"); return 0; }
int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { WARNX1("stub"); return 0; }
@@ -590,7 +581,6 @@ int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *param
int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val) { WARNX1("stub"); return 0; }
int snd_pcm_sw_params_set_tstamp_type(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t val) { WARNX1("stub"); return 0; }
int snd_pcm_sw_params_get_tstamp_type(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_type_t *val) { WARNX1("stub"); return 0; }
-int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val) { WARNX1("stub"); return 0; }
int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val) { WARNX1("stub"); return 0; }
int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val) { WARNX1("stub"); return 0; }
int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val) { WARNX1("stub"); return 0; }