Многоступенчатое преобразование скорости

Многоступенчатое преобразование скорости является подходом, который разделяет преобразование скорости на несколько этапов. Например, вместо десятикратного уменьшения в 18 раз, децимируйте в 3 раза, затем еще одно десятикратное уменьшение в 3, а затем в 2 раза. Использование нескольких каскадов уменьшает вычислительную сложность фильтрованного преобразования скорости. Кроме того, если один уже имеет модули преобразования для различных простых множителей, они могут использоваться как базовые блоки для более высоких скоростей. Этот пример продемонстрирует проекты многоступенчатого преобразования скорости.

Одноэтапное и многоступенчатое преобразование: анализ затрат

Рассмотрим систему десятикратного уменьшения скорости M = 8. Реализовать такую систему можно двумя способами:

  • Один дециматор скорости M = 8.

  • Каскад из трех дециматоров половинной скорости (M=2)

Хотя две альтернативы эффективно имеют одинаковый коэффициент десятикратного уменьшения, они различаются численными комплексами. Оцените стоимость реализации многоступенчатого дециматора с помощью cost function, и сравнить его со стоимостью реализации одностадийного дециматора.

bDecim2 = designMultirateFIR(1,2);
firDecim2_1 = dsp.FIRDecimator(2,bDecim2);
firDecim2_2 = dsp.FIRDecimator(2,bDecim2);
firDecim2_3 = dsp.FIRDecimator(2,bDecim2);
firDecim2cascade = dsp.FilterCascade(firDecim2_1,firDecim2_2,firDecim2_3);

cost2cascade = cost(firDecim2cascade)

bDecim8 = designMultirateFIR(1,8);
firDecim8 = dsp.FIRDecimator(8,bDecim8);
cost8 = cost(firDecim8)
cost2cascade = 

  struct with fields:

                  NumCoefficients: 75
                        NumStates: 138
    MultiplicationsPerInputSample: 21.8750
          AdditionsPerInputSample: 21


cost8 = 

  struct with fields:

                  NumCoefficients: 169
                        NumStates: 184
    MultiplicationsPerInputSample: 21.1250
          AdditionsPerInputSample: 21

Каскадирование трех дециматоров скорости M = 2 потребляет меньше памяти (состояний и коэффициентов) по сравнению с однокаскадным дециматором M = 8, что делает многоступенчатый преобразователь более эффективным. Арифметическая нагрузка (операции на выборку) одностадийной и многоступенчатой реализации эквивалентна. Обратите внимание, что количество выборок падает вдвое после каждого этапа десятикратного уменьшения. В заключение часто лучше разделить десятикратное уменьшение на несколько этапов (учитывая, что коэффициент изменения скорости не является простым числом, конечно).

Обычно существует более одного способа факторизации коэффициента (не простого) и даже больше степеней свободы многоступенчатого проекта. Для упрощения процесса проекта DSP System Toolbox(TM) предлагает несколько инструментов. Мы рассмотрим два из них в следующем.

Использование designMultistageDecimator и designMultistageInterpolator функции

The designMultistageInterpolator и designMultistageDecimator функции автоматически определяют оптимальное строение, которая включает в себя определение количества этапов вместе с их расположением, параметрами lowpass и т.д. Результатом является каскадный системный объект фильтра, которая инкапсуальтирует все стадии. Чтобы проиллюстрировать, давайте спроектируем дециматор скорости M = 12.

M = 12;
fcDecMulti = designMultistageDecimator(M);
info(fcDecMulti)
ans =

    'Discrete-Time Filter Cascade
     ----------------------------
     Number of stages: 3
     
     Stage1: dsp.FIRDecimator
     -------
     Discrete-Time FIR Multirate Filter (real)               
     -----------------------------------------               
     Filter Structure   : Direct-Form FIR Polyphase Decimator
     Decimation Factor  : 2                                  
     Polyphase Length   : 6                                  
     Filter Length      : 11                                 
     Stable             : Yes                                
     Linear Phase       : Yes (Type 1)                       
                                                             
     Arithmetic         : double                             
     
     
     Stage2: dsp.FIRDecimator
     -------
     Discrete-Time FIR Multirate Filter (real)               
     -----------------------------------------               
     Filter Structure   : Direct-Form FIR Polyphase Decimator
     Decimation Factor  : 2                                  
     Polyphase Length   : 8                                  
     Filter Length      : 15                                 
     Stable             : Yes                                
     Linear Phase       : Yes (Type 1)                       
                                                             
     Arithmetic         : double                             
     
     
     Stage3: dsp.FIRDecimator
     -------
     Discrete-Time FIR Multirate Filter (real)               
     -----------------------------------------               
     Filter Structure   : Direct-Form FIR Polyphase Decimator
     Decimation Factor  : 3                                  
     Polyphase Length   : 27                                 
     Filter Length      : 79                                 
     Stable             : Yes                                
     Linear Phase       : Yes (Type 1)                       
                                                             
     Arithmetic         : double                             
     
     '

Этот конкретный проект имеет 3 стадии $12=2\times 2\times 3$(), где lowpass последней стадии является самым длинным.

Повторите проект с одной ступенью.

fcDecSingle = designMultistageDecimator(M,'NumStages',1);
info(fcDecSingle)
ans =

    'Discrete-Time Filter Cascade
     ----------------------------
     Number of stages: 1
     
     Stage1: dsp.FIRDecimator
     -------
     Discrete-Time FIR Multirate Filter (real)               
     -----------------------------------------               
     Filter Structure   : Direct-Form FIR Polyphase Decimator
     Decimation Factor  : 12                                 
     Polyphase Length   : 26                                 
     Filter Length      : 307                                
     Stable             : Yes                                
     Linear Phase       : Yes (Type 1)                       
                                                             
     Arithmetic         : double                             
     
     '

Сравните стоимость двух реализаций. Послушно, многоступенчатый подход является более эффективным.

costMulti = cost(fcDecMulti)
costSingle = cost(fcDecSingle)
costMulti = 

  struct with fields:

                  NumCoefficients: 69
                        NumStates: 102
    MultiplicationsPerInputSample: 10.1667
          AdditionsPerInputSample: 9.3333


costSingle = 

  struct with fields:

                  NumCoefficients: 283
                        NumStates: 300
    MultiplicationsPerInputSample: 23.5833
          AdditionsPerInputSample: 23.5000

Теперь давайте сравним комбинированную частотную характеристику децимирующих фильтров. Несмотря на то, что фильтры двух реализаций различаются в стоповом диапазоне, ширина полосы пропускания и ширина перехода почти идентичны.

hfv = fvtool(fcDecMulti, fcDecSingle);
legend(hfv,'Multistage Combined Response', 'Single-Stage Response');

Та же методология применяется и для designMultistageInterpolator. Создайте две интерполяторы (одноступенчатую и многоступенчатую) и сравните их выходы. Обратите внимание, что выходы почти идентичны, за исключением немного большей задержки многоступенчатого интерполятора.

n = (1:20)';
x = (abs(n-5)<=5).*(5-abs(n-5));

L = 12;
fcIntrMulti = designMultistageInterpolator(L);
fcIntrSingle = designMultistageInterpolator(L,'NumStages',1);

xInterpSingle = fcIntrSingle(x);
xInterpMulti = fcIntrMulti(x);

release(fcIntrMulti);
release(fcIntrSingle);

subplot(3,1,1); stem(x); xlim([1,20]); title('Input Sequence');
subplot(3,1,2); stem(xInterpSingle); title('Single-Stage Interpolated')
subplot(3,1,3); stem(xInterpMulti); title('Multistage Interpolated')

The dsp.SampleRateConverter Системный объект

The dsp.SampleRateConverter системный объект обеспечивает удобный интерфейс для произвольного преобразования скорости, комбинируя интерполяцию и десятикратное уменьшение по мере необходимости.

src = dsp.SampleRateConverter('InputSampleRate',18,'OutputSampleRate',16,'Bandwidth',13);
info(src)
ans =

    'Overall Interpolation Factor    : 8
     Overall Decimation Factor       : 9
     Number of Filters               : 1
     Multiplications per Input Sample: 24.333333
     Number of Coefficients          : 219
     Filters:                         
        Filter 1:
        dsp.FIRRateConverter - Interpolation Factor: 8
                             - Decimation Factor   : 9 
     '

Различные стадии могут быть извлечены с помощью getFilters функция:

firs = getFilters(src)
firs = 

  dsp.FilterCascade with properties:

    Stage1: [1x1 dsp.FIRRateConverter]

Мы также можем задать абсолютные частоты (а не коэффициенты). Для примера, dsp.SampleRateConverter объект может преобразовать частоту выборки аудио данных с 48 кГц в 44,1 кГц.

src = dsp.SampleRateConverter('InputSampleRate',48000,'OutputSampleRate',44100);
[L,M] = getRateChangeFactors(src);

firs = getFilters(src);

reader = dsp.AudioFileReader('audio48kHz.wav','SamplesPerFrame',4*M);

x = reader();
xr = src(x);

% Obtain the rate conversion FIR
b = firs.Stage1.Numerator;

% Calculate the resampling delay
i0 = floor(length(b)/2)/L;

figure;
hold on;
stem((1:length(x))+i0,x);
stem(linspace(1,length(x),length(xr)),xr,'r');
hold off;
legend('Input Audio','Resampled Audio');
xlim([150,200])

release(reader);

Упрощение по SLACK преобразования скорости

Коэффициенты преобразования, подобные ($48k/44.1k$используемые в предыдущем разделе), требуют больших коэффициентов повышающей дискретизации и понижающей дискретизации, так как даже их уменьшенная форма. $L/M=160/147$Фильтры, необходимые для такого преобразования, довольно длинные, что вводит значительную задержку в дополнение к памяти и вычислительной нагрузке.

cost(src)
ans = 

  struct with fields:

                  NumCoefficients: 8587
                        NumStates: 58
    MultiplicationsPerInputSample: 53.6688
          AdditionsPerInputSample: 52.7500

Мы можем уменьшить дорогостоящее преобразование путем аппроксимации коэффициента преобразования ставок. Для примера,

$$48kHz/44.1kHz \approx 48kHz/44kHz = 12/11.$$

Отклонение 100Hz невелико, всего 0,23% от абсолютных частот. The dsp.SampleRateConverter может автоматически аппроксимировать коэффициент преобразования скорости, позволяя возмущать частоту выхода. Допуск возмущения задаётся через 'OutputRateTolerance' свойство. Допуск по умолчанию 0, то есть, без ослабления. Другими словами, ослабление означает отклонение от заданного значения выходной скорости. Очевидно, что аппроксимированное преобразование скорости имеет гораздо меньшие вычислительные затраты и достаточно для многих приложений, таких как обработка аудио стандартного определения.

src_approx = dsp.SampleRateConverter('InputSampleRate',48000,...
            'OutputSampleRate',44100,'Bandwidth',13,...
            'OutputRateTolerance',0.01);
[L_approx,M_approx] = getRateChangeFactors(src_approx)

cost(src_approx)
L_approx =

    11


M_approx =

    12


ans = 

  struct with fields:

                  NumCoefficients: 61
                        NumStates: 5
    MultiplicationsPerInputSample: 5.0833
          AdditionsPerInputSample: 4.1667

Похожие темы