|
Line 0
Link Here
|
|
|
1 |
Bug 1153151 - make libcubeb sndio use non-blocking i/o |
| 2 |
Bug 1153179 - fix latency reporting in libcubeb sndio |
| 3 |
|
| 4 |
From cubeb: |
| 5 |
From 5ffce9e91b2fde70ba532ea215e3e9e7eed3d41a Mon Sep 17 00:00:00 2001 |
| 6 |
From: Alexandre Ratchov <alex@caoua.org> |
| 7 |
Date: Thu, 2 Apr 2015 13:09:22 +1300 |
| 8 |
Subject: [PATCH] sndio: improve and clamp float->s16 conversion. |
| 9 |
|
| 10 |
https://marc.info/?l=openbsd-ports&m=152641946326955&w=2 |
| 11 |
Apply volume in software as do other backends. This is necessary |
| 12 |
because sndio volume may be controlled externally and there's no |
| 13 |
volume getter in libcubeb to notify the caller about volume |
| 14 |
changes. |
| 15 |
|
| 16 |
--- media/libcubeb/src/cubeb_sndio.c.orig 2018-05-24 13:59:58 UTC |
| 17 |
+++ media/libcubeb/src/cubeb_sndio.c |
| 18 |
@@ -4,6 +4,7 @@ |
| 19 |
* This program is made available under an ISC-style license. See the |
| 20 |
* accompanying file LICENSE for details. |
| 21 |
*/ |
| 22 |
+#include <math.h> |
| 23 |
#include <poll.h> |
| 24 |
#include <pthread.h> |
| 25 |
#include <sndio.h> |
| 26 |
@@ -41,17 +42,39 @@ struct cubeb_stream { |
| 27 |
uint64_t wrpos; /* number of written frames */ |
| 28 |
cubeb_data_callback data_cb; /* cb to preapare data */ |
| 29 |
cubeb_state_callback state_cb; /* cb to notify about state changes */ |
| 30 |
+ float volume; /* current volume */ |
| 31 |
void *arg; /* user arg to {data,state}_cb */ |
| 32 |
}; |
| 33 |
|
| 34 |
static void |
| 35 |
-float_to_s16(void *ptr, long nsamp) |
| 36 |
+s16_setvol(void *ptr, long nsamp, float volume) |
| 37 |
{ |
| 38 |
int16_t *dst = ptr; |
| 39 |
+ int32_t mult = volume * 32768; |
| 40 |
+ int32_t s; |
| 41 |
+ while (nsamp-- > 0) { |
| 42 |
+ s = *dst; |
| 43 |
+ s = (s * mult) >> 15; |
| 44 |
+ *(dst++) = s; |
| 45 |
+ } |
| 46 |
+} |
| 47 |
+ |
| 48 |
+static void |
| 49 |
+float_to_s16(void *ptr, long nsamp, float volume) |
| 50 |
+{ |
| 51 |
+ int16_t *dst = ptr; |
| 52 |
float *src = ptr; |
| 53 |
+ float mult = volume * 32768; |
| 54 |
+ int s; |
| 55 |
|
| 56 |
- while (nsamp-- > 0) |
| 57 |
- *(dst++) = *(src++) * 32767; |
| 58 |
+ while (nsamp-- > 0) { |
| 59 |
+ s = lrintf(*(src++) * mult); |
| 60 |
+ if (s < -32768) |
| 61 |
+ s = -32768; |
| 62 |
+ else if (s > 32767) |
| 63 |
+ s = 32767; |
| 64 |
+ *(dst++) = s; |
| 65 |
+ } |
| 66 |
} |
| 67 |
|
| 68 |
static void |
| 69 |
@@ -59,7 +82,7 @@ sndio_onmove(void *arg, int delta) |
| 70 |
{ |
| 71 |
cubeb_stream *s = (cubeb_stream *)arg; |
| 72 |
|
| 73 |
- s->rdpos += delta; |
| 74 |
+ s->rdpos += delta * s->bpf; |
| 75 |
} |
| 76 |
|
| 77 |
static void * |
| 78 |
@@ -103,7 +126,9 @@ sndio_mainloop(void *arg) |
| 79 |
break; |
| 80 |
} |
| 81 |
if (s->conv) |
| 82 |
- float_to_s16(s->buf, nfr * s->pchan); |
| 83 |
+ float_to_s16(s->buf, nfr * s->pchan, s->volume); |
| 84 |
+ else |
| 85 |
+ s16_setvol(s->buf, nfr * s->pchan, s->volume); |
| 86 |
start = 0; |
| 87 |
end = nfr * s->bpf; |
| 88 |
} |
| 89 |
@@ -127,7 +152,7 @@ sndio_mainloop(void *arg) |
| 90 |
state = CUBEB_STATE_ERROR; |
| 91 |
break; |
| 92 |
} |
| 93 |
- s->wrpos = 0; |
| 94 |
+ s->wrpos += n; |
| 95 |
start += n; |
| 96 |
} |
| 97 |
} |
| 98 |
@@ -179,7 +204,7 @@ sndio_stream_init(cubeb *context, |
| 99 |
if (s == NULL) |
| 100 |
return CUBEB_ERROR; |
| 101 |
s->context = context; |
| 102 |
- s->hdl = sio_open(NULL, SIO_PLAY, 0); |
| 103 |
+ s->hdl = sio_open(NULL, SIO_PLAY, 1); |
| 104 |
if (s->hdl == NULL) { |
| 105 |
free(s); |
| 106 |
DPR("sndio_stream_init(), sio_open() failed\n"); |
| 107 |
@@ -242,6 +267,7 @@ sndio_stream_init(cubeb *context, |
| 108 |
free(s); |
| 109 |
return CUBEB_ERROR; |
| 110 |
} |
| 111 |
+ s->volume = 1.; |
| 112 |
*stream = s; |
| 113 |
DPR("sndio_stream_init() end, ok\n"); |
| 114 |
(void)context; |
| 115 |
@@ -318,7 +344,7 @@ sndio_stream_get_position(cubeb_stream *s, uint64_t *p |
| 116 |
{ |
| 117 |
pthread_mutex_lock(&s->mtx); |
| 118 |
DPR("sndio_stream_get_position() %lld\n", s->rdpos); |
| 119 |
- *p = s->rdpos; |
| 120 |
+ *p = s->rdpos / s->bpf; |
| 121 |
pthread_mutex_unlock(&s->mtx); |
| 122 |
return CUBEB_OK; |
| 123 |
} |
| 124 |
@@ -328,7 +354,11 @@ sndio_stream_set_volume(cubeb_stream *s, float volume) |
| 125 |
{ |
| 126 |
DPR("sndio_stream_set_volume(%f)\n", volume); |
| 127 |
pthread_mutex_lock(&s->mtx); |
| 128 |
- sio_setvol(s->hdl, SIO_MAXVOL * volume); |
| 129 |
+ if (volume < 0.) |
| 130 |
+ volume = 0.; |
| 131 |
+ else if (volume > 1.0) |
| 132 |
+ volume = 1.; |
| 133 |
+ s->volume = volume; |
| 134 |
pthread_mutex_unlock(&s->mtx); |
| 135 |
return CUBEB_OK; |
| 136 |
} |
| 137 |
@@ -338,7 +368,7 @@ sndio_stream_get_latency(cubeb_stream * stm, uint32_t |
| 138 |
{ |
| 139 |
// http://www.openbsd.org/cgi-bin/man.cgi?query=sio_open |
| 140 |
// in the "Measuring the latency and buffers usage" paragraph. |
| 141 |
- *latency = stm->wrpos - stm->rdpos; |
| 142 |
+ *latency = (stm->wrpos - stm->rdpos) / stm->bpf; |
| 143 |
return CUBEB_OK; |
| 144 |
} |
| 145 |
|