Hi Andrei, On Thu, May 8, 2014 at 3:25 PM, Andrei Emeltchenko <Andrei.Emeltchenko.news@xxxxxxxxx> wrote: > From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx> > > For synchronization interleave read() and write(). > --- > android/hal-sco.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 73 insertions(+) > > diff --git a/android/hal-sco.c b/android/hal-sco.c > index 7b6608b..5ec56ce 100644 > --- a/android/hal-sco.c > +++ b/android/hal-sco.c > @@ -41,6 +41,8 @@ > #define OUT_BUFFER_SIZE 2560 > #define OUT_STREAM_FRAMES 2560 > > +#define SOCKET_POLL_TIMEOUT_MS 500 > + > static int listen_sk = -1; > static int audio_sk = -1; > > @@ -275,6 +277,74 @@ static void downmix_to_mono(struct sco_stream_out *out, const uint8_t *buffer, > } > } > > +static bool write_data(struct sco_stream_out *out, const uint8_t *buffer, > + size_t bytes) > +{ > + struct pollfd pfd; > + size_t len, written = 0; > + int ret; > + uint16_t mtu = /* out->cfg.mtu */ 48; > + uint8_t read_buf[mtu]; > + bool do_write = false; > + > + pfd.fd = out->fd; > + pfd.events = POLLOUT | POLLIN | POLLHUP | POLLNVAL; > + > + while (bytes > written) { > + > + /* poll for sending */ > + if (poll(&pfd, 1, SOCKET_POLL_TIMEOUT_MS) == 0) { > + DBG("timeout fd %d", out->fd); > + return false; > + } > + > + if (pfd.revents & (POLLHUP | POLLNVAL)) { > + error("error fd %d, events 0x%x", out->fd, pfd.revents); > + return false; > + } > + > + if (pfd.revents & POLLIN) { > + ret = read(out->fd, read_buf, mtu); > + if (ret < 0) { > + error("Error reading fd %d (%s)", out->fd, > + strerror(errno)); > + return false; > + } > + > + do_write = true; You probably gonna have store the read data in a buffer to be read by upper layer after remixed to 44.1 KHz, to safe space you can probably leave the remixing to be done on the read callback. Im fine to do this in a separate patch but we should at least add a comment about it. > + } > + > + if (!do_write) > + continue; > + > + len = bytes - written > mtu ? mtu : bytes - written; > + > + ret = write(out->fd, buffer + written, len); > + if (ret > 0) { > + written += ret; > + do_write = false; > + continue; > + } > + > + if (errno == EAGAIN) { > + ret = errno; > + warn("write failed (%d)", ret); > + continue; > + } > + > + if (errno != EINTR) { > + ret = errno; > + error("write failed (%d) fd %d bytes %zd", ret, out->fd, > + bytes); > + return false; > + } > + } > + > + DBG("written %zd bytes", bytes); > + > + return true; > +} > + > static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, > size_t bytes) > { > @@ -320,6 +390,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, > > DBG("total %zd", total); > > + if (!write_data(out, send_buf, total)) > + return -1; > + > return bytes; > } > > -- > 1.8.3.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Luiz Augusto von Dentz -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html