Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-30 Thread Alexander E. Patrakov
вт, 30 апр. 2019 г. в 23:46, Georg Chini :
>
> On 30.04.19 19:23, Alexander E. Patrakov wrote:
> >>   /* If set, this function is called in thread context when an update
> >> of the
> >>* filter parameters is requested, may be NULL. The function must
> >> replace
> >>* the currently used parameter structure by the new structure and
> >> return
> >>* a pointer to the old structure so that it can be freed in the
> >> main thread
> >>* using parameter_free(). If the old structure can be re-used, the
> >> function
> >>* may return NULL. */
> >>   void *(*update_filter_parameters)(void *parameters, void
> >> *filter_handle);
> > I don't think this is implementable. How are the parameters supposed
> > to be initially allocated?
> >
> Why should this not be possible to implement? Meanwhile I have
> it already implemented within the new virtual sink library and
> I am using it for the virtual-surround-sink and also for
> the ladspa-sink. Setting and querying parameters works
> perfectly. For the virtual-surround-sink I allocate new memory
> each time, while for the ladspa-sink I prepare a parameter set
> in the main thread and copy it to the "real" parameter set
> in the IO-thread.

Please don't treat the FIR for module-virtual-surround-sink as a set
of reconfigurable parameters. At least for now. Just hard-code the
contents of http://stuff.salscheider-online.de/hrir_kemar.tar.gz or
find a redistributable equivalent, preferably with more than 6
channels.

> The initial parameter set must be allocated when the
> filter is initialized. The parameter_set_all() function can be
> used to do that or the filter_init() function could create a
> default parameter set.

OK, I retract the "not implementable" objection.

-- 
Alexander E. Patrakov
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] configure a soundcard?

2019-04-30 Thread Georg Chini

On 27.04.19 12:26, Tanu Kaskinen wrote:

On Fri, 2019-04-26 at 07:37 -0500, Matt Zagrabelny wrote:

On Fri, Apr 26, 2019 at 4:28 AM Tanu Kaskinen  wrote:



In /usr/share/pulseaudio/alsa-mixer/paths/analog-output-
headphones.conf, change these lines:

[Jack Front Headphone]
required-any = any

to

[Jack Front Headphone]
required-any = any
state.plugged = unknown
state.unplugged = unknown

and similarly in /usr/share/pulseaudio/alsa-mixer/paths/analog-output-
lineout.conf change these lines:

[Jack Line Out Front]
required-any = any

to

[Jack Line Out Front]
required-any = any
state.plugged = unknown
state.unplugged = unknown

These changes will be overwritten whenever your distribution updates
pulseaudio (yes, this sucks, hopefully this will be improved some day;
I think George Chini already has something prepared related to
disabling jack detection).


Yes, once the messaging API patches are merged, I have at
least patches that provide the basic infrastructure to disable
jack detection on the fly.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-30 Thread Georg Chini

On 30.04.19 20:46, Georg Chini wrote:

On 30.04.19 19:23, Alexander E. Patrakov wrote:




  /* Callback to process a chunk of data by the filter. May be 
NULL */
  void (*process_chunk)(float *src, float *dst, unsigned count, 
void

*filter_handle);

  /* Callback to retrieve additional latency caused by the filter.
May be NULL */
  uint64_t (*get_extra_latency)(void *filter_handle);

  /* Initializes a new filter instance and returns a handle to 
it. */

  void *(*init_filter)(unsigned input_channels, unsigned
output_channels, unsigned sample_rate);

  /* Deletes filter instance. */
  void (*exit_filter)(void *filter_handle);

  /* If set, this function is called in thread context when an 
update

of the
   * filter parameters is requested, may be NULL. The function must
replace
   * the currently used parameter structure by the new structure 
and

return
   * a pointer to the old structure so that it can be freed in the
main thread
   * using parameter_free(). If the old structure can be 
re-used, the

function
   * may return NULL. */
  void *(*update_filter_parameters)(void *parameters, void
*filter_handle);

I don't think this is implementable. How are the parameters supposed
to be initially allocated?


Why should this not be possible to implement? Meanwhile I have
it already implemented within the new virtual sink library and
I am using it for the virtual-surround-sink and also for
the ladspa-sink. Setting and querying parameters works
perfectly. For the virtual-surround-sink I allocate new memory
each time, while for the ladspa-sink I prepare a parameter set
in the main thread and copy it to the "real" parameter set
in the IO-thread.
The initial parameter set must be allocated when the
filter is initialized. The parameter_set_all() function can be
used to do that or the filter_init() function could create a
default parameter set.


To make it clear: The proposal for an external interface comes
not out of the blue - I have all the bits already working for the
virtual sinks. That is module-virtual-sink, module-virtual-surround-sink,
module-remap-sink and module-ladspa-sink are fully converted to
the internal version of the interface. For module-equalizer-sink
I did not implement parameter changing because I could not
even figure out what the parameters are, but otherwise it also
uses the common infrastructure. Only module-echo-cancel
is a special case but still partly uses the virtual sink library.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-30 Thread Georg Chini

On 30.04.19 19:23, Alexander E. Patrakov wrote:

вт, 30 апр. 2019 г. в 16:31, Georg Chini :

  uint64_t min_latency; /* Minimum latency
allowed for the sink, 0 if unused */
  uint64_t max_latency; /* Maximum latency
allowed for the sink, 0 if unused */

Why would these fields be needed?


I simply followed what is currently used by the filters that are already
implemented in PA. The maximum latency field was intended to be
used if filters can't implement rewind and therefore have to limit
the maximum latency. If we always disable rewinding, it still may
be useful if you can specify an upper/lower limit, but in this case
the variables could be dropped.




  bool disable_rewind;  /* True when rewinding is
disabled */

I'd say get rid of it either. It's too hard to implement rewinds
correctly. Even in the simple cross-over filter that PulseAudio uses
for LFE remixing, it took four tries to reach at something that
doesn't produce clicks when the user e.g. changes the volume or
otherwise triggers a rewind.

Also, let's recollect the original purpose of the rewinds. They are,
in the end, a way to save power. That is, to use a very long interval
between wakeups if something non-interactive (like a music player) is
doing its job, without the side effect of slow reaction to events like
"new sink input wants to play something urgent". Please see my Linux
Audio Conference presentation and video for more details:

Paper: http://lac.linuxaudio.org/2015/papers/10.pdf
Slides: http://lac.linuxaudio.org/2015/download/rewind-slides.pdf
Video: http://lac.linuxaudio.org/2015/video.php?id=8

The main consideration here is that almost all filters are CPU-hungry
enough to mask (i.e. make irrelevant) the savings obtained by dynamic
latency and rewinds. So why give the filter implementer even an option
to shoot themselves in the foot?


I would not mind dropping this.





  /* Callback to reset the filter after rewind. May be NULL */
  void (*rewind_filter)(void *filter_handle, size_t amount);

Don't say "reset" here. Reset is not a proper way to handle a rewind,
users do notice the resulting clicks, see
https://bugs.freedesktop.org/show_bug.cgi?id=50113 (note: this is NOT
reported by me, there are real users who hear and care about this
imperfection!)

Please make it absolutely clear that the filter state must not be
reset, but seamlessly restored to the specified point in the past
(which is the filter's responsibility to keep). If one can't do that,
they shouldn't say that they support rewinds.

And yes, I understand that we have no filters (other than the trivial
one) which handle this correctly. That's actually one of the reasons
why I am so opposed to supporting rewindable filters.

One more comment - the "void" return type means that the filter must
be able to rewind itself no matter what, i.e. that failure is not
possible and not allowed. Assuming that my hint to stop pretending to
support rewinds gets ignored, I'd say that's a good thing.


If we drop disable_rewinding, this one can be dropped as well.
Otherwise you are right, and I should not say reset.




  /* Callback to process a chunk of data by the filter. May be NULL */
  void (*process_chunk)(float *src, float *dst, unsigned count, void
*filter_handle);

  /* Callback to retrieve additional latency caused by the filter.
May be NULL */
  uint64_t (*get_extra_latency)(void *filter_handle);

  /* Initializes a new filter instance and returns a handle to it. */
  void *(*init_filter)(unsigned input_channels, unsigned
output_channels, unsigned sample_rate);

  /* Deletes filter instance. */
  void (*exit_filter)(void *filter_handle);

  /* If set, this function is called in thread context when an update
of the
   * filter parameters is requested, may be NULL. The function must
replace
   * the currently used parameter structure by the new structure and
return
   * a pointer to the old structure so that it can be freed in the
main thread
   * using parameter_free(). If the old structure can be re-used, the
function
   * may return NULL. */
  void *(*update_filter_parameters)(void *parameters, void
*filter_handle);

I don't think this is implementable. How are the parameters supposed
to be initially allocated?


Why should this not be possible to implement? Meanwhile I have
it already implemented within the new virtual sink library and
I am using it for the virtual-surround-sink and also for
the ladspa-sink. Setting and querying parameters works
perfectly. For the virtual-surround-sink I allocate new memory
each time, while for the ladspa-sink I prepare a parameter set
in the main thread and copy it to the "real" parameter set
in the IO-thread.
The initial parameter set must be allocated when the
filter is initialized. The parameter_set_all() function can be
used to do that or the filter_init() function could create a
default 

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-30 Thread Alexander E. Patrakov
вт, 30 апр. 2019 г. в 16:31, Georg Chini :
>  uint64_t min_latency; /* Minimum latency
> allowed for the sink, 0 if unused */
>  uint64_t max_latency; /* Maximum latency
> allowed for the sink, 0 if unused */

Why would these fields be needed?

>  bool disable_rewind;  /* True when rewinding is
> disabled */

I'd say get rid of it either. It's too hard to implement rewinds
correctly. Even in the simple cross-over filter that PulseAudio uses
for LFE remixing, it took four tries to reach at something that
doesn't produce clicks when the user e.g. changes the volume or
otherwise triggers a rewind.

Also, let's recollect the original purpose of the rewinds. They are,
in the end, a way to save power. That is, to use a very long interval
between wakeups if something non-interactive (like a music player) is
doing its job, without the side effect of slow reaction to events like
"new sink input wants to play something urgent". Please see my Linux
Audio Conference presentation and video for more details:

Paper: http://lac.linuxaudio.org/2015/papers/10.pdf
Slides: http://lac.linuxaudio.org/2015/download/rewind-slides.pdf
Video: http://lac.linuxaudio.org/2015/video.php?id=8

The main consideration here is that almost all filters are CPU-hungry
enough to mask (i.e. make irrelevant) the savings obtained by dynamic
latency and rewinds. So why give the filter implementer even an option
to shoot themselves in the foot?

>
>  /* Callback to reset the filter after rewind. May be NULL */
>  void (*rewind_filter)(void *filter_handle, size_t amount);

Don't say "reset" here. Reset is not a proper way to handle a rewind,
users do notice the resulting clicks, see
https://bugs.freedesktop.org/show_bug.cgi?id=50113 (note: this is NOT
reported by me, there are real users who hear and care about this
imperfection!)

Please make it absolutely clear that the filter state must not be
reset, but seamlessly restored to the specified point in the past
(which is the filter's responsibility to keep). If one can't do that,
they shouldn't say that they support rewinds.

And yes, I understand that we have no filters (other than the trivial
one) which handle this correctly. That's actually one of the reasons
why I am so opposed to supporting rewindable filters.

One more comment - the "void" return type means that the filter must
be able to rewind itself no matter what, i.e. that failure is not
possible and not allowed. Assuming that my hint to stop pretending to
support rewinds gets ignored, I'd say that's a good thing.

>
>  /* Callback to process a chunk of data by the filter. May be NULL */
>  void (*process_chunk)(float *src, float *dst, unsigned count, void
> *filter_handle);
>
>  /* Callback to retrieve additional latency caused by the filter.
> May be NULL */
>  uint64_t (*get_extra_latency)(void *filter_handle);
>
>  /* Initializes a new filter instance and returns a handle to it. */
>  void *(*init_filter)(unsigned input_channels, unsigned
> output_channels, unsigned sample_rate);
>
>  /* Deletes filter instance. */
>  void (*exit_filter)(void *filter_handle);
>
>  /* If set, this function is called in thread context when an update
> of the
>   * filter parameters is requested, may be NULL. The function must
> replace
>   * the currently used parameter structure by the new structure and
> return
>   * a pointer to the old structure so that it can be freed in the
> main thread
>   * using parameter_free(). If the old structure can be re-used, the
> function
>   * may return NULL. */
>  void *(*update_filter_parameters)(void *parameters, void
> *filter_handle);

I don't think this is implementable. How are the parameters supposed
to be initially allocated?

-- 
Alexander E. Patrakov
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v9 0/8] Bluetooth A2DP codecs

2019-04-30 Thread Luiz Augusto von Dentz
Hi Pali,

On Tue, Apr 30, 2019 at 12:42 PM Luiz Augusto von Dentz
 wrote:
>
> Hi Pali,
>
> On Fri, Apr 26, 2019 at 6:47 PM Pali Rohár  wrote:
> >
> > On Friday 26 April 2019 16:44:03 Luiz Augusto von Dentz wrote:
> > > Hi Pali,
> > >
> > > On Fri, Apr 26, 2019 at 1:55 PM Pali Rohár  wrote:
> > > >
> > > > On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> > > > > Hi Pali,
> > > > >
> > > > > On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár  
> > > > > wrote:
> > > > > >
> > > > > > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > > > > > I have an assert when I use a different headset which does 
> > > > > > > support apt-X HD:
> > > > > > >
> > > > > > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> > > > > >
> > > > > > I have not tested aptX HD, nor aptX Low Latency. I tested only 
> > > > > > (classic)
> > > > > > aptX. I looked at code and there is incorrect calculation of buffer
> > > > > > block size for aptX HD. Try following:
> > > > > >
> > > > > > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, 
> > > > > > size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> > > > > > /* aptX HD compression ratio is 4:1 and we need to process one 
> > > > > > aptX HD sample (6 bytes) at once */
> > > > > > *encoded_buffer_size = (link_mtu/6) * 6;
> > > > > > *decoded_buffer_size = *encoded_buffer_size * 4;
> > > > > > }
> > > > >
> > > > > Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> > > > > asserts as well:
> > > > >
> > > > > https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> > > > >
> > > > > It seems that fill_preferred_configuration and can_accept_capabilities
> > > > > are not agreeing with one another
> > > >
> > > > When fill_preferred_configuration or can_accept_capabilities fails it
> > > > prints debug message about it. But I do not see any of them in your
> > > > output. So I think problem can be somewhere else.
> > > >
> > > > I have not got this assert for uhq2, so this looks like some race
> > > > condition.
> > > >
> > > > > so we got a transport but no profile.
> > > >
> > > > In your log is:
> > > > bluez activated sbc_uhq2, then module-bluez5-device started to be
> > > > loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
> > > > in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
> > > > sbc_uhq2 was released and prepared for switching to initial profile
> > > > aptx. And then assertion failed.
> > > >
> > > > My guess is: because card.c was not fully initialized yet (it called
> > > > hook for choosing initial profile), which called code for switching
> > > > profile, then u->card->profiles was not fully initialized and crashed.
> > > > Profile switching should be probably allowed only after full card
> > > > initialization to prevent such race conditions...
> > >
> > > Managed to find the problem, it was in choose_remote_endpoint_table:
> > >
> > >
> > >  for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
> > >  if (freq_table[i].rate == default_sample_spec->rate) {
> > > -frequency = freq_table[i].rate;
> > > +frequency = freq_table[i].cap;
> > >  break;
> > >  }
> >
> > Nice catch, thank you!
> >
> > > I have not idea how this worked with the bose, maybe that has more
> > > frequencies enabled since I end up with 0x44 which did not match any
> > > frequencies supported in case of sony.
> >
> > It worked also for me, so seems that more enabled frequencies was the
> > reason.
>
> Btw, if you are to send a v10 also include the following:
>
> @@ -1838,6 +1847,9 @@ static DBusMessage
> *endpoint_set_configuration(DBusConnection *conn, DBusMessage
>  t->release = bluez5_transport_release_cb;
>  pa_bluetooth_transport_put(t);
>
> +if (!d->change_a2dp_profile_in_progress)
> +pa_bluetooth_transport_set_state(t,
> PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
> +
>  pa_log_debug("Transport %s available for profile %s", t->path,
> pa_bluetooth_profile_to_string(t->profile));
>
>  return NULL;
>
> Otherwise last used logic don't work as intended.
>
> Btw, have you tried these patches with a phone? It seems to work but
> we got some problems:
>
> 1. At least Android seems to prefer aptX-HD but that doesn't seems to
> produce any audio, in fact it crashed a few times so either have to
> find out why aptX-HD is not working or don't include it.
> 2. Codec switching with Android always seems to timeout.
> 3. There seem to be some regression with loopback module, there seems
> it always produces some glitch when resuming (during the playback it
> seems alright):
>
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
> audio from queue
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
> audio from queue
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
> silence to queue
> I: [alsa-sink-ALC293 Analog] 

Re: [pulseaudio-discuss] R: New equalizer module (module-eqpro-sink), some questions

2019-04-30 Thread Georg Chini

On 27.04.19 17:14, Georg Chini wrote:

On 27.04.19 12:55, Georg Chini wrote:

On 27.04.19 12:04, Tanu Kaskinen wrote:

On Fri, 2019-04-26 at 11:40 +0200, Georg Chini wrote:

On 26.04.19 10:56, Tanu Kaskinen wrote:

On Tue, 2019-04-23 at 21:20 +0200, Georg Chini wrote:

The current scheme for
updating
parameters I have in mind should work for any of the existing 
filters

and relies on
passing around parameter structures:


Based on my implementation, the interface to a PA external plugin could 
look like this:



    unsigned input_channels; /* Number of audio input 
channels, 0 if variable */
    unsigned output_channels;    /* Number of audio output 
channels, 0 if variable */


    const char *desc_head;    /* Leading part of 
description string */
    const char *filter_type;  /* Name for the type of 
filter */


    size_t max_chunk_size;    /* Maximum chunk size in 
bytes that the filter will

   * accept, 0 for default */
    size_t fixed_block_size;  /* Block size in frames 
for fixed block size filters,
   * 0 if block size is 
variable */
    uint64_t min_latency; /* Minimum latency 
allowed for the sink, 0 if unused */
    uint64_t max_latency; /* Maximum latency 
allowed for the sink, 0 if unused */
    bool disable_rewind;  /* True when rewinding is 
disabled */


    /* Callback to reset the filter after rewind. May be NULL */
    void (*rewind_filter)(void *filter_handle, size_t amount);

    /* Callback to process a chunk of data by the filter. May be NULL */
    void (*process_chunk)(float *src, float *dst, unsigned count, void 
*filter_handle);


    /* Callback to retrieve additional latency caused by the filter. 
May be NULL */

    uint64_t (*get_extra_latency)(void *filter_handle);

    /* Initializes a new filter instance and returns a handle to it. */
    void *(*init_filter)(unsigned input_channels, unsigned 
output_channels, unsigned sample_rate);


    /* Deletes filter instance. */
    void (*exit_filter)(void *filter_handle);

    /* If set, this function is called in thread context when an update 
of the
 * filter parameters is requested, may be NULL. The function must 
replace
 * the currently used parameter structure by the new structure and 
return
 * a pointer to the old structure so that it can be freed in the 
main thread
 * using parameter_free(). If the old structure can be re-used, the 
function

 * may return NULL. */
    void *(*update_filter_parameters)(void *parameters, void 
*filter_handle);


    /* Frees a parameter structure. May only be NULL, if 
update_filter_parameters()
 * is also NULL or if update_filter_parameters() always returns 
NULL. */

    void (*parameter_free)(void *parameters);

    /* The following functions can be provided to set and get 
parameters. The parameter
 * structure is defined by the filter and should contain all 
parameters that are
 * configurable by the user. The library code makes no assumption 
on the contents
 * of the structure but only passes references. The library 
implements a message
 * handler which supports the following messages that use the 
functions below:

 * parameter-get - Retrieve a single parameter.
 * parameter-set - Set a single parameter.
 * parameter-get-all - Retrieve all parameters as a list in message 
format.

 * parameter-set-all - Set all parameters simultaneously.
 * parameter-get-description - Returns a filter description and a 
list that describes
 * all parameters. Example of the list 
element format:

 * {{Identifier}{Type}{default}{min}{max}}
 * The last message can be used to get information about the filter 
or to implement

 * a filter control GUI that is independent of the filter type.
 * If filter_message_handler() is defined, all other messages are 
passed on to the
 * filter. The get functions are expected to return a string in the 
message handler
 * format while the set functions receive plain strings. On 
failure, all get/set

 * functions will return NULL. */

    /* Get the value of the parameter described by identifier. The 
value shall be returned
 * as a string enclosed in double curly braces. The identifier may 
be any string that
 * the filter recognizes like a name or index, depending of the 
implementation of this

 * function. */
    char *(*parameter_get)(const char *identifier, void *filter_handle);

    /* Sets the value of the parameter described by identifier. The 
value is expected as
 * a string. The identifier may be any string that the filter 
recognizes like a name
 * or index. Returns a parameter structure filled with all current 
parameter values,
 * reflecting the updated parameter, 

Re: [pulseaudio-discuss] [PATCH v9 0/8] Bluetooth A2DP codecs

2019-04-30 Thread Luiz Augusto von Dentz
Hi Pali,

On Fri, Apr 26, 2019 at 6:47 PM Pali Rohár  wrote:
>
> On Friday 26 April 2019 16:44:03 Luiz Augusto von Dentz wrote:
> > Hi Pali,
> >
> > On Fri, Apr 26, 2019 at 1:55 PM Pali Rohár  wrote:
> > >
> > > On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> > > > Hi Pali,
> > > >
> > > > On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár  
> > > > wrote:
> > > > >
> > > > > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > > > > I have an assert when I use a different headset which does support 
> > > > > > apt-X HD:
> > > > > >
> > > > > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> > > > >
> > > > > I have not tested aptX HD, nor aptX Low Latency. I tested only 
> > > > > (classic)
> > > > > aptX. I looked at code and there is incorrect calculation of buffer
> > > > > block size for aptX HD. Try following:
> > > > >
> > > > > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, 
> > > > > size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> > > > > /* aptX HD compression ratio is 4:1 and we need to process one 
> > > > > aptX HD sample (6 bytes) at once */
> > > > > *encoded_buffer_size = (link_mtu/6) * 6;
> > > > > *decoded_buffer_size = *encoded_buffer_size * 4;
> > > > > }
> > > >
> > > > Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> > > > asserts as well:
> > > >
> > > > https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> > > >
> > > > It seems that fill_preferred_configuration and can_accept_capabilities
> > > > are not agreeing with one another
> > >
> > > When fill_preferred_configuration or can_accept_capabilities fails it
> > > prints debug message about it. But I do not see any of them in your
> > > output. So I think problem can be somewhere else.
> > >
> > > I have not got this assert for uhq2, so this looks like some race
> > > condition.
> > >
> > > > so we got a transport but no profile.
> > >
> > > In your log is:
> > > bluez activated sbc_uhq2, then module-bluez5-device started to be
> > > loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
> > > in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
> > > sbc_uhq2 was released and prepared for switching to initial profile
> > > aptx. And then assertion failed.
> > >
> > > My guess is: because card.c was not fully initialized yet (it called
> > > hook for choosing initial profile), which called code for switching
> > > profile, then u->card->profiles was not fully initialized and crashed.
> > > Profile switching should be probably allowed only after full card
> > > initialization to prevent such race conditions...
> >
> > Managed to find the problem, it was in choose_remote_endpoint_table:
> >
> >
> >  for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
> >  if (freq_table[i].rate == default_sample_spec->rate) {
> > -frequency = freq_table[i].rate;
> > +frequency = freq_table[i].cap;
> >  break;
> >  }
>
> Nice catch, thank you!
>
> > I have not idea how this worked with the bose, maybe that has more
> > frequencies enabled since I end up with 0x44 which did not match any
> > frequencies supported in case of sony.
>
> It worked also for me, so seems that more enabled frequencies was the
> reason.

Btw, if you are to send a v10 also include the following:

@@ -1838,6 +1847,9 @@ static DBusMessage
*endpoint_set_configuration(DBusConnection *conn, DBusMessage
 t->release = bluez5_transport_release_cb;
 pa_bluetooth_transport_put(t);

+if (!d->change_a2dp_profile_in_progress)
+pa_bluetooth_transport_set_state(t,
PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
+
 pa_log_debug("Transport %s available for profile %s", t->path,
pa_bluetooth_profile_to_string(t->profile));

 return NULL;

Otherwise last used logic don't work as intended.

Btw, have you tried these patches with a phone? It seems to work but
we got some problems:

1. At least Android seems to prefer aptX-HD but that doesn't seems to
produce any audio, in fact it crashed a few times so either have to
find out why aptX-HD is not working or don't include it.
2. Codec switching with Android always seems to timeout.
3. There seem to be some regression with loopback module, there seems
it always produces some glitch when resuming (during the playback it
seems alright):

I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
audio from queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
audio from queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
silence to queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 105170 usec
of audio from queue


>
> --
> Pali Rohár
> pali.ro...@gmail.com



-- 
Luiz Augusto von Dentz
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org