Previous: A Bestiary of Kiwi Objects Up: Implementation
Most software synthesizers include postprocessing, usually some kind of reverberation. Unfortunately, reverberation algorithms must act on the entire signal, not on the individual notes. Given this constraint, parallel reverberation seems impossible. An early version of Kiwi employed a Collector that performed the postprocessing on each grain as soon as all the samples were available. Unfortunately the Collector could not signal the Scheduler to continue until after postprocessing was complete, which resulted in a tenfold increase in running time.
Executing the reverberation algorithm in the Collector allowed no parallelism. To introduce parallelism, postprocessing was moved out of Kiwi entirely, and placed in a separate program. Only after the entire piece has been computed and written to the disk is the reverberator invoked. This simplifies the structure of both programs considerably.
The reverberator parallelizes reverberation calculations by exploiting the linearity of most audio signal processing algorithms. Reverberation and other common forms of postprocessing can be expressed entirely in terms of filters, and filters can be expressed linearly in the digital domain. Since a reverberator is linear, it is commutative with addition: the reverberation of a sum of notes is equal to the sum of the notes reverberated separately. This suggests a naive algorithm for parallelizing reverberation: give each note its own reverberator. Unfortunately, the net increase in work outweighs the increase in speed from parallelism.
A better way to parallelize reverberation is to divide the entire sound file into equal segments such that the size of a segment multiplied by the number of processors fits into memory. Each processor takes a segment from the file, reverberates it, and then writes onto the disk.
This scheme is complicated by the fact that some filters continue to produce non-zero output for some time after their inputs have dropped to zero. Filters that have this property are said to ``ring.'' This ringing simulates the sound in reverberant room gradually dying away. If a processor computes reverberation for a segment of the sound file, there will be a set of samples representing the ringing after the end of this segment which should be added to the beginning of the next segment. This set of samples is called the overlap. The overlap is added to the next segment after the next segment has been reverberated. In order to simplify the process, the segments should be at least as long as the overlap. The overlap size usually represent several seconds of sound. Thus, the segments are currently 200,000 samples.
Comments to walker@shout.net