Re: [RFCv0 01/14] android/hal-sco: Use nanosleep for SCO synchronization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andrei,

On Thu, May 22, 2014 at 3:05 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@xxxxxxxxx> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx>
>
> ---
>  android/hal-sco.c | 56 +++++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 42 insertions(+), 14 deletions(-)
>
> diff --git a/android/hal-sco.c b/android/hal-sco.c
> index ea9857e..fb7b4d4 100644
> --- a/android/hal-sco.c
> +++ b/android/hal-sco.c
> @@ -64,6 +64,8 @@ struct sco_stream_out {
>         int fd;
>
>         uint8_t *downmix_buf;
> +       size_t samples;
> +       struct timespec start;
>
>         struct resampler_itfe *resampler;
>         int16_t *resample_buf;
> @@ -277,6 +279,21 @@ static void downmix_to_mono(struct sco_stream_out *out, const uint8_t *buffer,
>         }
>  }
>
> +static uint64_t timespec_diff_us(struct timespec *a, struct timespec *b)
> +{
> +       struct timespec res;
> +
> +       res.tv_sec = a->tv_sec - b->tv_sec;
> +       res.tv_nsec = a->tv_nsec - b->tv_nsec;
> +
> +       if (res.tv_nsec < 0) {
> +               res.tv_sec--;
> +               res.tv_nsec += 1000000000ll; /* 1sec */
> +       }
> +
> +       return res.tv_sec * 1000000ll + res.tv_nsec / 1000ll;
> +}
> +
>  static bool write_data(struct sco_stream_out *out, const uint8_t *buffer,
>                                                                 size_t bytes)
>  {
> @@ -284,13 +301,13 @@ static bool write_data(struct sco_stream_out *out, const uint8_t *buffer,
>         size_t len, written = 0;
>         int ret;
>         uint16_t mtu = /* out->cfg.mtu */ 48;
> -       uint8_t read_buf[mtu];
> -       bool do_write = false;
> +       uint64_t audio_sent_us, audio_passed_us;
>
>         pfd.fd = out->fd;
>         pfd.events = POLLOUT | POLLIN | POLLHUP | POLLNVAL;
>
>         while (bytes > written) {
> +               struct timespec now;
>
>                 /* poll for sending */
>                 if (poll(&pfd, 1, SOCKET_POLL_TIMEOUT_MS) == 0) {
> @@ -303,27 +320,38 @@ static bool write_data(struct sco_stream_out *out, const uint8_t *buffer,
>                         return false;
>                 }
>
> -               /* FIXME synchronize by time instead of read() */
> -               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;
> +               clock_gettime(CLOCK_REALTIME, &now);

Im not sure why did you choose to got with CLOCK_REALTIME, we used
CLOCK_MONOTONIC on hal-audio.c for a very important reason because it
is nonsettable.

> +               /* Mark start of the stream */
> +               if (!out->samples)
> +                       memcpy(&out->start, &now, sizeof(out->start));
> +
> +               audio_sent_us = out->samples * 1000000ll / AUDIO_STREAM_SCO_RATE;
> +               audio_passed_us = timespec_diff_us(&now, &out->start);
> +               if ((int) (audio_sent_us - audio_passed_us) > 1500) {

What is 1500 for?

> +                       struct timespec timeout = {0,
> +                                               (audio_sent_us -
> +                                                audio_passed_us) * 1000};
> +                       DBG("Sleeping for %d ms",
> +                                       (int) (audio_sent_us - audio_passed_us));
> +                       nanosleep(&timeout, NULL);

Also we should use clock_nanosleep just as hal-audio.c.

> +               } else if ((int)(audio_passed_us - audio_sent_us) > 50000) {
> +                       DBG("\n\nResync\n\n");
> +                       out->samples = 0;
> +                       memcpy(&out->start, &now, sizeof(out->start));
>                 }
>
> -               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;
> +
> +                       out->samples += ret / 2;
> +
> +                       DBG("written %d samples %zd total %zd bytes",
> +                                       ret, out->samples, written);
>                         continue;
>                 }
>
> --
> 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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux