[pulseaudio-tickets] [PulseAudio] #288: Smooth rate variation in module-combine

PulseAudio trac-noreply at tango.0pointer.de
Sun May 4 05:51:03 PDT 2008


#288: Smooth rate variation in module-combine
------------------------------+---------------------------------------------
 Reporter:  Chimrod           |       Owner:  lennart
     Type:  enhancement       |      Status:  new    
 Priority:  normal            |   Milestone:         
Component:  module-combine-*  |    Severity:  minor  
 Keywords:                    |  
------------------------------+---------------------------------------------
 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.01^20^ = 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

-- 
Ticket URL: <http://pulseaudio.org/ticket/288>
PulseAudio <http://pulseaudio.org/>
The PulseAudio Sound Server


More information about the pulseaudio-bugs mailing list