DSPRelated.com
Forums

M-to-2 Polyphase Decimation Channelizer

Started by mrberman87 7 years ago3 replieslatest reply 7 years ago346 views
I am trying to make a M to 2 Polyphase Channelizer.  I have a design in Octave running fine, but when I try to double the output sample rate, I am getting a lot of signal bleed through to other channels.  I am pretty sure that I am handling the comutator input and the phase shift between the filter and IFFT.  What am I doing wrong to have such little channel isolation?  Please see my code and output images below.


clear all;close all; clc;

chans = 16;
chan_inject = 0.1;
Fs = 100e6;
NSamp = 10e3;
NFFT = 2.^floor(log2(NSamp));
data_in = single_tone_data(Fs/chans*chan_inject, Fs, NSamp);

%% M-to-1 Decimation Channelizer
%{
f1 = Fs / chans * 0.6;
f2 = Fs / chans * 0.8;
f3 = Fs / chans * 1.0;
delta_f = f3 - f1;
dB  = 100;
N = dB * Fs / (22 * delta_f);
hc = fir2((round(N / chans) * chans) - 1, [0 f1/Fs f2/Fs f3/Fs 1], [1 1 1/2 0 0]);

dataBank = flipud(reshape(data_in, chans, floor(size(data_in, 2) / chans)));
coeffBank = reshape(hc, chans, size(hc, 2)/chans);
data_out = zeros(size(dataBank));

for rowIdx = 1:chans
  data_out(rowIdx,:) = filter(coeffBank(rowIdx,:), 1, dataBank(rowIdx,:));
endfor

for colIdx = 1:size(data_out, 2)
    data_out(:,colIdx) = fftshift(ifft(data_out(:,colIdx)));
endfor

figure
fDisp = (-NFFT/chans/2:NFFT/chans/2 - 1) * Fs / (NFFT/chans);
for rowIdx = 1:chans
  subplot(ceil(sqrt(chans)),ceil(sqrt(chans)),rowIdx)
  dis = 20*log10(abs(fftshift(fft(data_out(rowIdx,:), NFFT/chans))));
  plot(fDisp,dis);
endfor
%}

%% M-to-2 Decimation Channelizer
%%{
f1 = Fs / chans * 0.6;
f2 = Fs / chans * 0.8;
f3 = Fs / chans * 1.0;
delta_f = f3 - f1;
dB  = 100;
N = dB * Fs / (22 * delta_f);
hc = fir2((round(N / chans) * chans) - 1, [0 f1/Fs f2/Fs f3/Fs 1], [1 1 1/2 0 0]);

dataBank = flipud(reshape(data_in, chans/2, size(data_in, 2)/chans*2));
dataBank = [dataBank;[zeros(chans/2, 1) dataBank(:,1:end-1)]];
coeffBank = reshape(hc, chans, size(hc, 2)/chans);
data_out = zeros(size(dataBank));

for rowIdx = 1:chans
  data_out(rowIdx,:) = filter(coeffBank(rowIdx,:), 1, dataBank(rowIdx,:));
endfor

for colIdx = 1:size(data_out, 2)
  if mod(colIdx, 2) == 1
    data_out(:,colIdx) = fftshift(ifft(data_out(:,colIdx)));
  else
    data_out(:,colIdx) = fftshift(ifft([data_out(end/2+1:end,colIdx);data_out(1:end/2,colIdx)]));
  endif
endfor

figure
fDisp = (-NFFT/chans/2:NFFT/chans/2 - 1) * Fs * 2 / (NFFT/chans);
for rowIdx = 1:chans
  subplot(ceil(sqrt(chans)),ceil(sqrt(chans)),rowIdx)
  dis = 20*log10(abs(fftshift(fft(data_out(rowIdx,:), NFFT/chans))));
  plot(fDisp,dis);
endfor
%}

M-to-1 Output:

m_to_1_32011.png

M-to-2 Output:

m_to_2_86864.png



[ - ]
Reply by spetcavichMarch 8, 2017

here is an example of a 6-to-1 i implemented a while back where h1a is my FIR filter, and x is my input sequence. You're code was a little convoluted so i didnt sift through it but maybe this will shed some light on stuff.  


h1apoly=6∗reshape(h1a ,6 ,length( h1a ) / 6 ) ;

regsa=zeros ( 6 , length(h1a) / 6 ) ;

v1= 0 ;

vv = 0 ;

n2=1;

for n = 1:6:length(x)−5

v1 = fliplr ( x(n:n + 5) ) ’;

regsa = [ v1 regsa(: , 1:size(h1apoly ,2) −1)] ;

for k=1:6

vv (k)= regsa(k ,:) ∗ h1apoly (k , :) ’ ;

end

yy(:, n2)= ifft(vv) ’ ;

n2=n2+1;

end

[ - ]
Reply by mrberman87March 8, 2017

Spetcavich,


Thanks for the info.  Looking at what you have, you are breaking your FDM signal into 6 channels, each at a sample rate of Fs/6.  I have this, where the output sample rate of each channel is the sample rate divided by the number of channels.  Where I am having issues is where the output sample rate of each channel is 2 * Fs / N, where N is the number of channels.  From what I have read around, the structure and data packing is a little different.  This, or the values of my prototype filter, are where I believe I am having issues.


Michael

[ - ]
Reply by spetcavichMarch 8, 2017
I think you're filtering wrong initially ...see page 19 of this thesis paper advised by fred harris who has written a lot of papers on channelizers and see how i apply the filters to the data below

http://sdsu-dspace.calstate.edu/bitstream/handle/1...

also not sure you should have zeros packed into your data vector like this, not sure what is going on here:

dataBank = [dataBank;[zeros(chans/2, 1) dataBank(:,1:end-1)]];

Example:

h1bpoly=6∗reshape( h1b , 6 , length ( h1b ) / 6 ) ;
regb=zeros(6 , 2∗length(h1b)/6 ) ;
n2=1;
flg =0;


%process
for n = 1:3:length(x)−2
    v1b (1:3) = fliplr( x(n:n+2) ) ';
    v1b (4:6) = v1b ( 1 : 3 ) ;
    regb = [v1b regb( : , 1:size(regb , 2) −1) ] ;

    for k=1:3
        vvb (k)= regb( k , 1:2:end )∗h1bpoly ( k , : ) ' ;
        vvb (k+3)=regb( k+3 , 2:2:end )∗ h1bpoly ( k + 3 , :) ' ;
    end

    ifflg == 0
        flg = 1 ;
    elseif flg == 1
        flg = 0 ;
        vvb = [ vvb (4:6) ; vvb(1:3) ] ;
    end

    yyb ( :,n2)=3∗ ifft (vvb) ' ;
    n2=n2+1;
end