1 ## Copyright (C) 2003 David Bateman
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'amdsb-tc',offset)
18 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'amdsb-tc/costas',offset)
19 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'amdsb-sc')
20 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'amdsb-sc/costas')
21 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'amssb')
22 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'qam')
23 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'qam/cmplx')
24 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'fm',@var{dev})
25 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},@var{Fs},'pm',@var{dev})
26 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{x},[@var{Fs},@var{iphs}],@var{...})
27 ## @deftypefnx {Function File} {@var{y} =} ademodce (@var{...},@var{num},@var{den})
29 ## Baseband demodulator for analog signals. The input signal is specified by
30 ## @var{x}, its sampling frequency by @var{Fs} and the type of modulation
31 ## by the third argument, @var{typ}. The default values of @var{Fs} is 1 and
32 ## @var{typ} is 'amdsb-tc'.
34 ## If the argument @var{Fs} is a two element vector, the the first element
35 ## represents the sampling rate and the second the initial phase.
37 ## The different types of demodulations that are available are
42 ## Double-sideband with carrier
43 ## @item 'amdsb-tc/costas'
44 ## Double-sideband with carrier and Costas phase locked loop
46 ## Double-sideband with suppressed carrier
48 ## Single-sideband with frequency domain Hilbert filtering
50 ## Quadrature amplitude demodulation. In-phase in odd-columns and quadrature
53 ## Quadrature amplitude demodulation with complex return value.
55 ## Frequency demodulation
60 ## Additional arguments are available for the demodulations 'amdsb-tc', 'fm',
61 ## 'pm'. These arguments are
65 ## The offset in the input signal for the transmitted carrier.
67 ## The deviation of the phase and frequency modulation
70 ## It is possible to specify a low-pass filter, by the numerator @var{num}
71 ## and denominator @var{den} that will be applied to the returned vector.
74 ## @seealso{ademodce,dmodce}
76 function y = ademodce (x, Fs, typ, varargin)
93 if ((max(size(Fs)) != 2) || (min(size(Fs)) != 1))
94 error ("ademodce: sampling frequency must be a scalar or 2-element vector");
100 ## Pass the optional arguments
106 error ("ademodce: modulation type must be a string");
107 elseif (strcmp(typ,"am") || strcmp(typ,"amdsb-tc"))
108 if (length(varargin) > 0)
109 offset = varargin{1};
112 elseif (strcmp(typ,"fm") || strcmp(typ,"pm"))
113 if (length(varargin) > 0)
118 if (length(varargin) == narg)
119 error ("ademodce: must specify must numerator and denominator of transfer function");
120 elseif (length(varargin) == narg+1)
121 num = varargin{narg};
122 den = varargin{narg+1};
123 elseif (length(varargin) != narg - 1)
124 error ("ademodce: too many arguments");
127 if (strcmp(typ,"am") || findstr(typ,"amdsb-tc"))
128 if (findstr(typ,"/costas"))
129 error ("ademodce: Costas phase locked loop not implemented");
131 y = real(x * exp(-1i * iphs));
132 if (exist("offset","var"))
135 if (min(size(y)) == 1)
139 y(:,i) = y(:,i) - mean(y(:,i));
143 elseif (strcmp(typ,"amdsb-sc"))
144 y = real(x * exp(-1i * iphs));
145 elseif (findstr(typ,"amssb"))
146 if (findstr(typ,"/costas"))
147 error ("ademodce: Costas phase locked loop not implemented");
149 y = real(x * exp(-1i * iphs));
150 elseif (strcmp(typ,"qam"))
151 y1 = x * exp(-1i * iphs);
152 y = zeros(size(y1,1),2*size(y1,2));
153 y(:,1:2:size(y,2)) = real(y1);
154 y(:,2:2:size(y,2)) = imag(y1);
155 elseif (strcmp(typ,"qam/cmplx"))
156 y = x * exp(-1i * iphs);
157 elseif (strcmp(typ,"pm"))
158 y = ( -1i * log(x) + iphs) / dev;
159 elseif (strcmp(typ,"fm"))
160 ## This can't work as it doesn't take into account the
161 ## phase wrapping in the modulation process. Therefore
162 ## we'll get some of the demodulated values in error, with
163 ## most of the values being correct..
165 ## Not sure the best approach to fixing this. Perhaps implement
166 ## a PLL with the ouput of the phase detector being the demodulated
168 warning("ademodce: FM demodulation broken!!")
169 pm = Fs / dev / pi * ( - 1i * log(x) + iphs)
170 y = [pm(:,1), (pm(:,2:size(pm,2)) - pm(:,1:size(pm,2)-1))];
172 error ("ademodce: unknown demodulation specified");
175 if (!isempty(num) && !isempty(dem))
176 ## Low-pass filter the output
177 if (min(size(y)) == 1)
178 y = filter(num,den, y);
181 y(:,i) = filter(num, den, y(:,i));