Ticket #288 (new enhancement)

Opened 4 months ago

Last modified 2 months ago

Smooth rate variation in module-combine

Reported by: Chimrod Assigned to: lennart
Priority: normal Milestone:
Component: module-combine-* Severity: minor
Keywords: Cc:

Description

When we are using module-combine with a low adjust_time, we can get a good synchronization between the two sinks, but with brutal frequency variations, and make a strange effect on the sound. On the other side, with a great adjust_time, the sound seems clean, but it is hard to stay synchronized between the two sink ( as I use module-combine to combine sound with 2 computers, variations are frequents )

I send you a code for use low adjust_time values ( in my case I use a value of 1 ), and get a smooth variation in the frequencies. In the adjust_rates function :

    for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) {
        uint32_t r = base_rate;
//      We get the actual frequency rate
	uint32_t actual_rate = o->sink_input->sample_spec.rate;

        if (!o->sink_input || !PA_SINK_OPENED(pa_sink_get_state(o->sink)))
            continue;

        if (o->total_latency < target_latency)
            r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);
        else if (o->total_latency > target_latency)
            r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);

/*        if (r < (uint32_t) (base_rate*0.8) || r > (uint32_t) (base_rate*1.2)) {
            pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->name, base_rate, r);
            pa_sink_input_set_rate(o->sink_input, base_rate);
        } else {
*/

//	If the actual frequency differ too much from the future frequency, adjust r
        r = r > (uint32_t) (actual_rate*0.99) ? r : (uint32_t) (actual_rate*0.99) ;
        r = r < (uint32_t) (actual_rate*1.01) ? r : (uint32_t) (actual_rate*1.01) ;


        pa_log_info("[%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.", o->sink_input->name, r, (double) r / base_rate, (float) o->total_latency);
        pa_sink_input_set_rate(o->sink_input, r);
//        }
    }

The maximum correction is the same as in the default code with the default value for adjust_time ( 20 seconds ): 1.0120 = 1.22 against 1.2 for maximum frequency adpatation, but here we gett a better precision ( we can use an adjust_time of 1 second ), and the sound doesn't seem distorded when we are hearing it.

I didn't notice more cpu usage with changing the adjust_time to 1 ( I tried with a 533mHz computer :) ), the only one problem is when the rate diffrence is too high : it can take long time to get a good adjust, one time the frequency is too high, then too low, before becoming too high again... but globally the precision is better than with a great adjust_time value, and the sound stay clean when hearing

Chimrod

Change History

06/21/08 01:53:23 changed by lennart

  • milestone set to 0.9.11.

Hmm, so if I understand you correctly, then you changed the following:

  • Decrease the adjust_time to 1s
  • Suppress very small sampling rate changes.

Is that correct?

Sounds like a reasonable change.

07/24/08 15:15:57 changed by lennart

  • milestone deleted.