Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-15 Thread Raman Shishniou
On 02/15/2018 12:43 PM, Georg Chini wrote:
> On 15.02.2018 10:31, Raman Shishniou wrote:
>> On 02/15/2018 10:20 AM, Georg Chini wrote:
>>> On 14.02.2018 22:51, Raman Shishniou wrote:
 On 02/14/2018 07:20 PM, Georg Chini wrote:
> On 14.02.2018 15:25, Raman Shyshniou wrote:
>> This patch adds a underrun_protection argument to
>> control underrun protection algorithm. Disabling
>> protection will keep loopback latency regardless
>> of underruns.
> Again I do not understand the motivation of the patch.
> In what situations are you seeing so many underruns and
> still want to keep the original configured latency value?
> Audio will be very bad in that case.
>
 All situations where where latency is more important than data integrity.
 Voice over IP (telephony) for example, receiving audio data using network
 by UDP/RTP. Any data loss leads to underruns in loopback module.
>>> This is not correct. It will only lead to underruns, if module-loopback runs
>>> out of data. So if you buffer enough data, missing packets in the voice
>>> stream would just appear to be small sample rate variations from the
>>> perspective of the loopback module. Because the loopback module
>>> does some adaptive re-sampling, these variations are no problem.
>>>
>>> Maybe this happens for you because module-pipe-source has no buffer
>>> at all and simply passes the values through whenever data arrives.
>>> With missing data packets, this can surely lead to underruns on the
>>> source side which are passed on to the loopback module.
>>> Perhaps you should implement some buffering in pipe-source?
>>>
>>> I don't see the point of your change. If you are seeing massive underruns,
>>> audio quality will be really bad and just sticking to the configured latency
>>> will not improve the situation. For me, the permanent occurrence of
>>> underruns shows that there is something wrong with your setup in the first
>>> place. The better idea is to correct the audio chain, so that no (or only 
>>> very
>>> few) underruns happen.
>> I Agree. For live streaming or internet radio I can buffer more data up to
>> several seconds (or just use tcp). But not for telephony, where 10-20
>> underruns per hour is acceptable, but latency more than 50-100ms is not.
>> Loopback module increases latency permanently. There is no way to decrease
>> it without unload and load again.
> 
> How about a max_latency_msec argument in the sense that the logic
> will not be completely disabled, but module-loopback will not try to
> increase the latency above max_latency_msec (if specified) even if
> underruns occur?
> 

I can see that, it makes sense to me. I'll make the patch.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-15 Thread Georg Chini

On 15.02.2018 10:31, Raman Shishniou wrote:

On 02/15/2018 10:20 AM, Georg Chini wrote:

On 14.02.2018 22:51, Raman Shishniou wrote:

On 02/14/2018 07:20 PM, Georg Chini wrote:

On 14.02.2018 15:25, Raman Shyshniou wrote:

This patch adds a underrun_protection argument to
control underrun protection algorithm. Disabling
protection will keep loopback latency regardless
of underruns.

Again I do not understand the motivation of the patch.
In what situations are you seeing so many underruns and
still want to keep the original configured latency value?
Audio will be very bad in that case.


All situations where where latency is more important than data integrity.
Voice over IP (telephony) for example, receiving audio data using network
by UDP/RTP. Any data loss leads to underruns in loopback module.

This is not correct. It will only lead to underruns, if module-loopback runs
out of data. So if you buffer enough data, missing packets in the voice
stream would just appear to be small sample rate variations from the
perspective of the loopback module. Because the loopback module
does some adaptive re-sampling, these variations are no problem.

Maybe this happens for you because module-pipe-source has no buffer
at all and simply passes the values through whenever data arrives.
With missing data packets, this can surely lead to underruns on the
source side which are passed on to the loopback module.
Perhaps you should implement some buffering in pipe-source?

I don't see the point of your change. If you are seeing massive underruns,
audio quality will be really bad and just sticking to the configured latency
will not improve the situation. For me, the permanent occurrence of
underruns shows that there is something wrong with your setup in the first
place. The better idea is to correct the audio chain, so that no (or only very
few) underruns happen.

I Agree. For live streaming or internet radio I can buffer more data up to
several seconds (or just use tcp). But not for telephony, where 10-20
underruns per hour is acceptable, but latency more than 50-100ms is not.
Loopback module increases latency permanently. There is no way to decrease
it without unload and load again.


How about a max_latency_msec argument in the sense that the logic
will not be completely disabled, but module-loopback will not try to
increase the latency above max_latency_msec (if specified) even if
underruns occur?

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


Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-15 Thread Raman Shishniou
On 02/15/2018 10:20 AM, Georg Chini wrote:
> On 14.02.2018 22:51, Raman Shishniou wrote:
>> On 02/14/2018 07:20 PM, Georg Chini wrote:
>>> On 14.02.2018 15:25, Raman Shyshniou wrote:
 This patch adds a underrun_protection argument to
 control underrun protection algorithm. Disabling
 protection will keep loopback latency regardless
 of underruns.
>>> Again I do not understand the motivation of the patch.
>>> In what situations are you seeing so many underruns and
>>> still want to keep the original configured latency value?
>>> Audio will be very bad in that case.
>>>
>> All situations where where latency is more important than data integrity.
>> Voice over IP (telephony) for example, receiving audio data using network
>> by UDP/RTP. Any data loss leads to underruns in loopback module.
> 
> This is not correct. It will only lead to underruns, if module-loopback runs
> out of data. So if you buffer enough data, missing packets in the voice
> stream would just appear to be small sample rate variations from the
> perspective of the loopback module. Because the loopback module
> does some adaptive re-sampling, these variations are no problem.
> 
> Maybe this happens for you because module-pipe-source has no buffer
> at all and simply passes the values through whenever data arrives.
> With missing data packets, this can surely lead to underruns on the
> source side which are passed on to the loopback module.
> Perhaps you should implement some buffering in pipe-source?
> 
> I don't see the point of your change. If you are seeing massive underruns,
> audio quality will be really bad and just sticking to the configured latency
> will not improve the situation. For me, the permanent occurrence of
> underruns shows that there is something wrong with your setup in the first
> place. The better idea is to correct the audio chain, so that no (or only very
> few) underruns happen.

I Agree. For live streaming or internet radio I can buffer more data up to
several seconds (or just use tcp). But not for telephony, where 10-20
underruns per hour is acceptable, but latency more than 50-100ms is not.
Loopback module increases latency permanently. There is no way to decrease
it without unload and load again.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-14 Thread Georg Chini

On 14.02.2018 22:51, Raman Shishniou wrote:

On 02/14/2018 07:20 PM, Georg Chini wrote:

On 14.02.2018 15:25, Raman Shyshniou wrote:

This patch adds a underrun_protection argument to
control underrun protection algorithm. Disabling
protection will keep loopback latency regardless
of underruns.

Again I do not understand the motivation of the patch.
In what situations are you seeing so many underruns and
still want to keep the original configured latency value?
Audio will be very bad in that case.


All situations where where latency is more important than data integrity.
Voice over IP (telephony) for example, receiving audio data using network
by UDP/RTP. Any data loss leads to underruns in loopback module.


This is not correct. It will only lead to underruns, if module-loopback runs
out of data. So if you buffer enough data, missing packets in the voice
stream would just appear to be small sample rate variations from the
perspective of the loopback module. Because the loopback module
does some adaptive re-sampling, these variations are no problem.

Maybe this happens for you because module-pipe-source has no buffer
at all and simply passes the values through whenever data arrives.
With missing data packets, this can surely lead to underruns on the
source side which are passed on to the loopback module.
Perhaps you should implement some buffering in pipe-source?

I don't see the point of your change. If you are seeing massive underruns,
audio quality will be really bad and just sticking to the configured latency
will not improve the situation. For me, the permanent occurrence of
underruns shows that there is something wrong with your setup in the first
place. The better idea is to correct the audio chain, so that no (or 
only very

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


Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-14 Thread Raman Shishniou
On 02/14/2018 07:20 PM, Georg Chini wrote:
> On 14.02.2018 15:25, Raman Shyshniou wrote:
>> This patch adds a underrun_protection argument to
>> control underrun protection algorithm. Disabling
>> protection will keep loopback latency regardless
>> of underruns.
> 
> Again I do not understand the motivation of the patch.
> In what situations are you seeing so many underruns and
> still want to keep the original configured latency value?
> Audio will be very bad in that case.
> 

All situations where where latency is more important than data integrity.
Voice over IP (telephony) for example, receiving audio data using network
by UDP/RTP. Any data loss leads to underruns in loopback module. Current
implementation will increase overall latency by 5 msec every 3 underruns. 

>> ---
>>   src/modules/module-loopback.c | 31 +--
>>   1 file changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
>> index aecac0a..c452e1a 100644
>> --- a/src/modules/module-loopback.c
>> +++ b/src/modules/module-loopback.c
>> @@ -45,6 +45,7 @@ PA_MODULE_USAGE(
>>   "sink= "
>>   "adjust_time= "
>>   "latency_msec= "
>> +"underrun_protection= "
>>   "format= "
>>   "rate= "
>>   "channels= "
>> @@ -90,6 +91,7 @@ struct userdata {
>>   /* Values from command line configuration */
>>   pa_usec_t latency;
>>   pa_usec_t adjust_time;
>> +bool underrun_protection;
>> /* Latency boundaries and current values */
>>   pa_usec_t min_source_latency;
>> @@ -158,6 +160,7 @@ static const char* const valid_modargs[] = {
>>   "sink",
>>   "adjust_time",
>>   "latency_msec",
>> +"underrun_protection",
>>   "format",
>>   "rate",
>>   "channels",
>> @@ -325,11 +328,20 @@ static void adjust_rates(struct userdata *u) {
>> /* If we are seeing underruns then the latency is too small */
>>   if (u->underrun_counter > 2) {
>> -u->underrun_latency_limit = PA_MAX(u->latency, u->minimum_latency) 
>> + 5 * PA_USEC_PER_MSEC;
>> -u->underrun_latency_limit = 
>> PA_CLIP_SUB((int64_t)u->underrun_latency_limit, u->sink_latency_offset + 
>> u->source_latency_offset);
>> -update_minimum_latency(u, u->sink_input->sink, false);
>> -pa_log_warn("Too many underruns, increasing latency to %0.2f ms", 
>> (double)u->minimum_latency / PA_USEC_PER_MSEC);
>> -u->underrun_counter = 0;
>> +int64_t target_latency;
>> +
>> +target_latency = PA_MAX(u->latency, u->minimum_latency);
>> +
>> +if (u->underrun_protection)
>> +target_latency += 5 * PA_USEC_PER_MSEC;
>> +
>> +u->underrun_latency_limit = PA_CLIP_SUB(target_latency, 
>> u->sink_latency_offset + u->source_latency_offset);
>> +
>> +if (u->minimum_latency < u->underrun_latency_limit) {
> 
> The above comparison does not make sense to me. The minimum latency
> should always be smaller than (or equal to) the underrun_latency_limit.
> Otherwise we would not be seeing underruns. There are two ways, the
> minimum latency is calculated:
> 1) Theoretically. Anything below that value will definitely cause underruns.
> The value is directly derived from the minimum sink/source latency.
> 2) Practically: If we are seeing underruns at some latency, we know the
> theoretical value is too small and update it to the empirically found value.
> 
>> +update_minimum_latency(u, u->sink_input->sink, false);
>> +pa_log_warn("Too many underruns, increasing latency to %0.2f 
>> ms", (double)u->minimum_latency / PA_USEC_PER_MSEC);
>> +u->underrun_counter = 0;
>> +}
>>   }
>> /* Allow one underrun per hour */
>> @@ -347,7 +359,7 @@ static void adjust_rates(struct userdata *u) {
>>   }
>>   u->adjust_time_stamp = now;
>>   -/* Rates and latencies*/
>> +/* Rates and latencies */
>>   old_rate = u->sink_input->sample_spec.rate;
>>   base_rate = u->source_output->sample_spec.rate;
>>   @@ -1251,6 +1263,7 @@ int pa__init(pa_module *m) {
>>   pa_source *source = NULL;
>>   pa_source_output_new_data source_output_data;
>>   bool source_dont_move;
>> +bool underrun_protection = true;
>>   uint32_t latency_msec;
>>   pa_sample_spec ss;
>>   pa_channel_map map;
>> @@ -1336,10 +1349,16 @@ int pa__init(pa_module *m) {
>>   goto fail;
>>   }
>>   +if (pa_modargs_get_value_boolean(ma, "underrun_protection", 
>> _protection) < 0) {
>> +pa_log("Failed to parse underrun_protection value.");
>> +goto fail;
>> +}
>> +
>>   m->userdata = u = pa_xnew0(struct userdata, 1);
>>   u->core = m->core;
>>   u->module = m;
>>   u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
>> +u->underrun_protection = underrun_protection;
>>   u->output_thread_info.pop_called = false;
>>   

Re: [pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-14 Thread Georg Chini

On 14.02.2018 15:25, Raman Shyshniou wrote:

This patch adds a underrun_protection argument to
control underrun protection algorithm. Disabling
protection will keep loopback latency regardless
of underruns.


Again I do not understand the motivation of the patch.
In what situations are you seeing so many underruns and
still want to keep the original configured latency value?
Audio will be very bad in that case.


---
  src/modules/module-loopback.c | 31 +--
  1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index aecac0a..c452e1a 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -45,6 +45,7 @@ PA_MODULE_USAGE(
  "sink= "
  "adjust_time= "
  "latency_msec= "
+"underrun_protection= "
  "format= "
  "rate= "
  "channels= "
@@ -90,6 +91,7 @@ struct userdata {
  /* Values from command line configuration */
  pa_usec_t latency;
  pa_usec_t adjust_time;
+bool underrun_protection;
  
  /* Latency boundaries and current values */

  pa_usec_t min_source_latency;
@@ -158,6 +160,7 @@ static const char* const valid_modargs[] = {
  "sink",
  "adjust_time",
  "latency_msec",
+"underrun_protection",
  "format",
  "rate",
  "channels",
@@ -325,11 +328,20 @@ static void adjust_rates(struct userdata *u) {
  
  /* If we are seeing underruns then the latency is too small */

  if (u->underrun_counter > 2) {
-u->underrun_latency_limit = PA_MAX(u->latency, u->minimum_latency) + 5 
* PA_USEC_PER_MSEC;
-u->underrun_latency_limit = PA_CLIP_SUB((int64_t)u->underrun_latency_limit, 
u->sink_latency_offset + u->source_latency_offset);
-update_minimum_latency(u, u->sink_input->sink, false);
-pa_log_warn("Too many underruns, increasing latency to %0.2f ms", 
(double)u->minimum_latency / PA_USEC_PER_MSEC);
-u->underrun_counter = 0;
+int64_t target_latency;
+
+target_latency = PA_MAX(u->latency, u->minimum_latency);
+
+if (u->underrun_protection)
+target_latency += 5 * PA_USEC_PER_MSEC;
+
+u->underrun_latency_limit = PA_CLIP_SUB(target_latency, 
u->sink_latency_offset + u->source_latency_offset);
+
+if (u->minimum_latency < u->underrun_latency_limit) {


The above comparison does not make sense to me. The minimum latency
should always be smaller than (or equal to) the underrun_latency_limit.
Otherwise we would not be seeing underruns. There are two ways, the
minimum latency is calculated:
1) Theoretically. Anything below that value will definitely cause underruns.
The value is directly derived from the minimum sink/source latency.
2) Practically: If we are seeing underruns at some latency, we know the
theoretical value is too small and update it to the empirically found value.


+update_minimum_latency(u, u->sink_input->sink, false);
+pa_log_warn("Too many underruns, increasing latency to %0.2f ms", 
(double)u->minimum_latency / PA_USEC_PER_MSEC);
+u->underrun_counter = 0;
+}
  }
  
  /* Allow one underrun per hour */

@@ -347,7 +359,7 @@ static void adjust_rates(struct userdata *u) {
  }
  u->adjust_time_stamp = now;
  
-/* Rates and latencies*/

+/* Rates and latencies */
  old_rate = u->sink_input->sample_spec.rate;
  base_rate = u->source_output->sample_spec.rate;
  
@@ -1251,6 +1263,7 @@ int pa__init(pa_module *m) {

  pa_source *source = NULL;
  pa_source_output_new_data source_output_data;
  bool source_dont_move;
+bool underrun_protection = true;
  uint32_t latency_msec;
  pa_sample_spec ss;
  pa_channel_map map;
@@ -1336,10 +1349,16 @@ int pa__init(pa_module *m) {
  goto fail;
  }
  
+if (pa_modargs_get_value_boolean(ma, "underrun_protection", _protection) < 0) {

+pa_log("Failed to parse underrun_protection value.");
+goto fail;
+}
+
  m->userdata = u = pa_xnew0(struct userdata, 1);
  u->core = m->core;
  u->module = m;
  u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
+u->underrun_protection = underrun_protection;
  u->output_thread_info.pop_called = false;
  u->output_thread_info.pop_adjust = false;
  u->output_thread_info.push_called = false;



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


[pulseaudio-discuss] [PATCH] loopback: underrun_protection argument

2018-02-14 Thread Raman Shyshniou
This patch adds a underrun_protection argument to
control underrun protection algorithm. Disabling
protection will keep loopback latency regardless
of underruns.
---
 src/modules/module-loopback.c | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index aecac0a..c452e1a 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -45,6 +45,7 @@ PA_MODULE_USAGE(
 "sink= "
 "adjust_time= "
 "latency_msec= "
+"underrun_protection= "
 "format= "
 "rate= "
 "channels= "
@@ -90,6 +91,7 @@ struct userdata {
 /* Values from command line configuration */
 pa_usec_t latency;
 pa_usec_t adjust_time;
+bool underrun_protection;
 
 /* Latency boundaries and current values */
 pa_usec_t min_source_latency;
@@ -158,6 +160,7 @@ static const char* const valid_modargs[] = {
 "sink",
 "adjust_time",
 "latency_msec",
+"underrun_protection",
 "format",
 "rate",
 "channels",
@@ -325,11 +328,20 @@ static void adjust_rates(struct userdata *u) {
 
 /* If we are seeing underruns then the latency is too small */
 if (u->underrun_counter > 2) {
-u->underrun_latency_limit = PA_MAX(u->latency, u->minimum_latency) + 5 
* PA_USEC_PER_MSEC;
-u->underrun_latency_limit = 
PA_CLIP_SUB((int64_t)u->underrun_latency_limit, u->sink_latency_offset + 
u->source_latency_offset);
-update_minimum_latency(u, u->sink_input->sink, false);
-pa_log_warn("Too many underruns, increasing latency to %0.2f ms", 
(double)u->minimum_latency / PA_USEC_PER_MSEC);
-u->underrun_counter = 0;
+int64_t target_latency;
+
+target_latency = PA_MAX(u->latency, u->minimum_latency);
+
+if (u->underrun_protection)
+target_latency += 5 * PA_USEC_PER_MSEC;
+
+u->underrun_latency_limit = PA_CLIP_SUB(target_latency, 
u->sink_latency_offset + u->source_latency_offset);
+
+if (u->minimum_latency < u->underrun_latency_limit) {
+update_minimum_latency(u, u->sink_input->sink, false);
+pa_log_warn("Too many underruns, increasing latency to %0.2f ms", 
(double)u->minimum_latency / PA_USEC_PER_MSEC);
+u->underrun_counter = 0;
+}
 }
 
 /* Allow one underrun per hour */
@@ -347,7 +359,7 @@ static void adjust_rates(struct userdata *u) {
 }
 u->adjust_time_stamp = now;
 
-/* Rates and latencies*/
+/* Rates and latencies */
 old_rate = u->sink_input->sample_spec.rate;
 base_rate = u->source_output->sample_spec.rate;
 
@@ -1251,6 +1263,7 @@ int pa__init(pa_module *m) {
 pa_source *source = NULL;
 pa_source_output_new_data source_output_data;
 bool source_dont_move;
+bool underrun_protection = true;
 uint32_t latency_msec;
 pa_sample_spec ss;
 pa_channel_map map;
@@ -1336,10 +1349,16 @@ int pa__init(pa_module *m) {
 goto fail;
 }
 
+if (pa_modargs_get_value_boolean(ma, "underrun_protection", 
_protection) < 0) {
+pa_log("Failed to parse underrun_protection value.");
+goto fail;
+}
+
 m->userdata = u = pa_xnew0(struct userdata, 1);
 u->core = m->core;
 u->module = m;
 u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
+u->underrun_protection = underrun_protection;
 u->output_thread_info.pop_called = false;
 u->output_thread_info.pop_adjust = false;
 u->output_thread_info.push_called = false;
-- 
1.8.3.1

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