Avoiding latency noise in non-deterministic algorithms

Discussions about programming and implementing Coyote-1 effect modules

Avoiding latency noise in non-deterministic algorithms

Postby eric_admin » Sat Aug 16, 2008 10:24 pm

I came across an interesting source of noise when I was testing the Tube Distortion. The algorithm has some conditional clipping stages, which means it takes longer to complete when the stages are clipping than when they are not. If you pick apart the way the conduit engine works (COYOTE1_Conduit_Engine.spin) you'll find that it is syncs to the current microframe, processes all conduit transactions (i.e. copies data between sockets), and repeats. That means that the engine's read of any specific output socket is some consistent fixed delay after the start of each microframe. Because the Tube distortion's algorithm had a variable execution time, it would sometime write the output socket before it was read by the conduit engine and sometimes write the output socket after it was read. That caused a one sample jitter which was audible as a faint hissing distortion.

The solution? If your algorithm executes in variable time, save the final output to a temp variable and write it to the output just after the microframe synchronization. It's probably a good practice to adopt in general; it doesn't cost much (one instruction and one storage longword) , does no harm for deterministic effects, and avoids the potential for jitter noise in non-deterministic effects.

The implementation goes in 4 places, like this:

Code: Select all
_frame_sync             rdlong  current_microframe, p_frame_counter
                        cmp     previous_microframe, current_microframe  wz
              if_z      jmp     #_frame_sync                                    'If current_microframe = previoius_microframe

                        'Verify sync, and report an overrun condition if it has occurred.
                        '
                        'NOTE: An overrun condition is reported to the OS by writing a non-zero value to the "overrun detect" field in the
                        '      SYSTEM_STATE block.  The code below writes the value of current_microframe in order to conserve code space,
                        '      achieve portability, and limit execution time. That value will be non-zero 99.9999999767169% of the time,
                        '      which is sufficiently reliable for overrun reporting
                        '
                        add     previous_microframe, #1
                        cmp     previous_microframe, current_microframe  wz
              if_nz     wrlong  current_microframe, p_ss_overrun_detect
                       
                        mov     previous_microframe, current_microframe         'previous_microframe = current_microframe

                        '------------------------------------
                        'Get audio in sample and write audio out sample
                        '------------------------------------
                        wrlong  pending_audio_out, p_socket_audio_out           '<<<<<<<<<< MODIFICATION
                        rdlong  audio_in_sample, p_socket_audio_in   
                       
                        '------------------------------------
                        'Bypass
                        '------------------------------------
                        'Read bypass state
                        rdlong  r1, p_socket_bypass 
                        cmp     SIGNAL_TRUE, r1   wc, wz

                        'Update on/off indication
        if_c_or_z       mov     r2, 0
        if_nc_and_nz    mov     r2, SIGNAL_TRUE
                        wrlong  r2, p_socket_on
                       
                        'If bypassed, then just pass audio through
        if_c_or_z       mov    pending_audio_out, audio_in_sample              '<<<<<<<<<< MODIFICATION
        if_c_or_z       jmp     #_frame_sync

.
.  (rest of effect code)
.

                        '------------------------------------
                        'Store output
                        '------------------------------------
                        mov     pending_audio_out, x                            '<<<<<<<<<< MODIFICATION
                       

                        'Done Distortion
                        jmp     #_frame_sync

.
.  (more code and definitions)
.

pending_audio_out         res     1                                             '<<<<<<<<<< MODIFICATION   

User avatar
eric_admin
Site Admin
 
Posts: 121
Joined: Wed Aug 13, 2008 6:10 pm

Return to Effect Module Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron