Multirate
This section contains the following pages:
General Information
Audio Weaver is able to process signals at different samples rates all within the same layout. This was seen with control signals but the feature is much more powerful. Audio Weaver is able to handle multirate processing in two different ways:
Single block time processing
Multiple block time processing
In single block time processing all of the audio modules execute within a single thread at the same rate. In multiple block time processing there are multiple threads on the target processors and different block times execute within separate interrupt levels. Each approach is described in turn.
Single block time processing
A module has an associated block size and sampling rate. We’ve been treating these wire properties as separate information but when combined they yield the block time of a module. For example, consider the system shown below.
![](../../__attachments/2807661151/image-20221228-233858.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
The sampling rate is 48 kHz and the block size is 32 samples. Each block of audio thus represents 32 / 48000 = 2/3 msec of audio. 32 sample audio buffers arrive every 2/3 msec and each block executes in turn.
There are 4 modules which can be used to change the sampling rate and still maintain the same block time.
![]() | Upsampler | Inserts zeros between samples. No filtering |
![]() | Downsampler | Discards samples. No filtering. |
![]() | FIRInterpolator | Upsampler followed by an FIR interpolating filter |
![]() | FIRDecimator | FIR filter followed by a Downsampler |
The Upsampler and Downsampler modules insert zeros and discard samples, respectively. Specify the up and downsampling factors on the module properties. The downsampling factor must be chosen so that it divides the input block size and yields an integer number of output samples. Consider the system shown below:
![](../../__attachments/2807661151/image-20221228-233953.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
As before, the input block time is 2/3 of a millisecond. The Upsampler module is configured for an upsampling factor of L=2. The output sampling rate is 96 kHz and the block size is now 64 samples. Note that 64/96000 = 2/3 millisecond and the block time is preserved. As before, all modules execute every 2/3 millisecond.
The Upsampler and Downsampler modules correspond to standard up and downsamplers found in DSP text books. Since they lack any filtering, they are rarely used.
The FIRInterpolator and FIRDownsampler modules, on the other hand, contain FIR filters. The FIRInterpolator inserts zeros and then filters the resulting signal with a lowpass filter; the FIRDecimator first applies an FIR lowpass filter and then decimates. Both modules use an efficient polyphase implementation to reduce the processing load. These modules also preserve the underlying block time.
![](../../__attachments/2807661151/image-20221228-234006.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
On the module properties for the FIRInterpolator / FIRDecimator specify the up / downsampling factor as well as the length of the FIR filter. The length of the FIR filter must be an integer multiple of the up / downsampling factors. When the modules are instantiated the FIR filter coefficients are computed using a Hamming window. Advanced users can change the filter coefficients by using Matlab scripts.
The Rebuffer module stores and overlaps buffer data into larger block sizes, allowing for more data to be displayed. It does not change the fundamental block size for the system.
![]() | Rebuffer | Overlaps data into larger block sizes, allowing for longer time displays. Does not change fundamental block size |
The Rebuffer can accept data of any type. In its module properties is a variable called “outBlockSize,” which allows the user to set the output block size for the module. If a positive value is entered, that value is used as the output block size. If a negative value is entered, the value is used as a multiplier to the input block size. For example, an outBlockSize of 32 will yield an output of block size 32, and an outBlockSize of -8 yields an output with 8 times the block size of the input.
For example, the following block diagram shows a SinGen source wired directly to a Sink module to view in the scope display:
![](../../__attachments/2807661151/image-20221228-234024.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
However, the scope display shows only a small amount of data (in this case, 0.67 msec, based on the example above with a block size of 32 and sample rate of 48000 Hz):
![](../../__attachments/2807661151/image-20221228-234035.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
To extend the amount of displayed data, a Rebuffer module with outBlockSize -8 is added between the source and the sink:
![](../../__attachments/2807661151/image-20221228-234044.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
This allows the Sink module to display 8 times the amount of data, easily spanning the 4-msec window:
![](../../__attachments/2807661151/image-20221228-234055.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
The Rebuffer module is also useful for multirate processing. The Rebuffer module increases the output block size while keeping the sampling rate and block time constant. It achieves this by outputting blocks which overlap in time. Consider the system shown below. The input block size is 32 samples and the Rebuffer module is configured to output 128 sample blocks.
![](../../__attachments/2807661151/image-20221228-234104.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
Each block that is output overlaps the previous one by 96 samples as shown below.
![](../../__attachments/2807661151/image-20221228-234135.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
The Rebuffer module is useful for frequency domain processing when it is necessary to have a certain amount of overlap between blocks. The inverse of the Rebuffer module is the BlockExtract module. This module extracts a subset of samples and reduces the block size.
Multiple block time processing
In some applications processing needs to be performed at multiple block times. Consider a system that has low latency processing with a block size of 32 samples combined with frequency domain processing at a block size of 256 samples. At a 48 kHz sampling rate, the 32 sample processing would occur every 2/3 millisecond while the 256 sample processing would occur every 5 1/3 millisecond. This type of processing is achieved using the BufferUp and BufferDown modules.
![]() | BufferUp | Buffers up to larger blocks without overlapping. |
![]() | BufferDown | Buffers down to smaller blocks without dropping samples. |
The BufferUp module generates larger non-overlapping blocks. On the module properties dialog specify the output block size either as an integer number of samples or as a multiple of the input block size. In the example above, to go from 32 to 256 samples, specify a 256 sample block size (or a multiplier of 8). To return to a 32 sample block size, use the BufferDown module. Again, explicitly specify the output block size either as an integer number of samples or as a divider.
The system shown below combines 32 and 256 sample block sizes.
![](../../__attachments/2807661151/image-20221228-234204.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
In the figure, the name of the filter module is shown as “SOF1 [1/8]”. The annotation [1/8] indicates that this module executes in a separate thread at a rate of 1/8th compared to the others. The BufferUp module indicates [1/1 à 1/8] which means that the part of the module operates at the full rate (1/1) and part of the module executes at the 1/8 rate. The output of the BufferUp module contains 256 samples which equals 8 32-sample blocks. The output is non-overlapping as shown here.
![](../../__attachments/2807661151/image-20221228-234235.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
The BufferUp and BufferDown modules contain internal double buffering to connect the two processing rates. The double buffering introduces a latency equal to twice the larger block size. In the example above, the latency through the BufferUp, SOF, and BufferDown modules equals 512 samples.
On the target processor, the 32 and 256 sample processing occurs in different threads (or interrupt levels). The 32 sample processing occurs in a higher interrupt level and actually interrupts the 256 sample processing. The pattern of processing would be as shown below. The 32 sample block processing occurs at a uniform rate. When the 32 sample processing is not active then the 256 sample processing has a chance to execute. The 256 sample processing must complete before the next 8 blocks of 32 samples arrive.
![](../../__attachments/2807661151/image-20221228-234305.png?inst-v=afeb83b1-861e-46b8-b4de-1c642321bb7f)
Running at multiple block times can lead to erroneous module profiling results for the larger block time. The small block time is correct but the large block time incorrectly includes the time needed to execute the smaller blocks. Be aware of this when viewing profiling results.
Another limitation of Audio Weaver is that the smallest possible block time in the system corresponds to the fundamental block size of the target system. This means that the smallest block time occurs at the input pin of the system. Audio Weaver buffers can only BufferUp to larger block times. When using a platform with a fundamental block size of 32 samples, it is not possible to BufferDown to a 1 sample block size for stream processing.
One final note, not all targets support multiple block times. Refer to the user guide of the specific hardware target to see if this feature is supported.