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} {} modmap (@var{method},@var{...})
18 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'ask',@var{m})
19 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'fsk',@var{m},@var{tone})
20 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'msk')
21 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'psk',@var{m})
22 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask',@var{m})
23 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/cir',@var{nsig},@var{amp},@var{phs})
24 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/arb',@var{inphase},@var{quadr})
25 ## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/arb',@var{map})
27 ## Mapping of a digital signal to an analog signal. With no output arguments
28 ## @dfn{modmap} plots the constellation of the mapping. In this case the
29 ## first argument must be the string @var{method} defining one of 'ask',
30 ## 'fsk', 'msk', 'qask', 'qask/cir' or 'qask/arb'. The arguments following
31 ## the string @var{method} are generally the same as those after the
32 ## corresponding string in the fucntion call without output arguments.
33 ## The exception is @code{modmap('msk',@var{Fd})}.
35 ## With an output argument, @var{y} is the complex mapped analog signal. In
36 ## this case the arguments @var{x}, @var{fd} and @var{fs} are required. The
37 ## variable @var{x} is the digital signal to be mapped, @var{fd} is the
38 ## sampling rate of the of digital signal and the @var{fs} is the sampling
39 ## rate of the analog signal. It is required that @code{@var{fs}/@var{fd}}
42 ## The available mapping of the digital signal are
46 ## Amplitude shift keying
48 ## Frequency shift keying
50 ## Minimum shift keying
56 ## Quadraure amplitude shift keying
59 ## In addition the 'qask', 'qsk' and 'qam' method can be modified with the
60 ## flags '/cir' or '/arb'. That is 'qask/cir' and 'qask/arb', etc are valid
61 ## methods and give circular- and arbitrary-qask mappings respectively.
63 ## The additional argument @var{m} is the order of the modulation to use.
64 ## @var{m} must be larger than the largest element of @var{x}. The variable
65 ## @var{tone} is the FSK tone to use in the modulation.
67 ## For 'qask/cir', the additional arguments are the same as for
68 ## @dfn{apkconst}, and you are referred to @dfn{apkconst} for the definitions
69 ## of the additional variables.
71 ## For 'qask/arb', the additional arguments @var{inphase} and @var{quadr} give
72 ## the in-phase and quadrature components of the mapping, in a similar mapping
73 ## to the outputs of @dfn{qaskenco} with one argument. Similar @var{map}
74 ## represents the in-phase and quadrature components of the mapping as
75 ## the real and imaginary parts of the variable @var{map}.
77 ## @seealso{demodmap,dmodce,amodce,apkconst,qaskenco}
79 function y = modmap(varargin)
84 error ("modmap: too few arguments");
93 error ("modmap: too few arguments");
101 M = max(2,2^ceil(log2(max(x(:)) + 1)));
104 if (!isscalar(fs) || !isscalar(fd) || !isreal(fs) || !isreal(fd) || ...
105 (fs <= 0) || (fd <= 0))
106 error ("modmap: sampling rates must be positive real values");
108 if (abs(fs/fd - floor(fs/fd)) > eps)
109 error ("modmap: the sample rate Fs must be an integer multiple of Fd");
113 if (min(size(x)) == 1)
124 yy = zeros(n*nn,size(x,2));
131 error ("modmap: too many output arguments");
135 error ("modmap: mapping method to use must be a string");
138 if (isempty(findstr(method,"/arb")) && isempty(findstr(method,"/cir")))
140 M = varargin{optarg+1};
141 if (!isscalar(M) || !isreal(M) || (M < 0) || (M != floor(M)))
142 error ("modmap: modulation order must be a real positive integer");
145 if ((nargout != 0) && (M < max(x(:)) + 1))
146 error ("modmap: illegal symbol in data for modulation order");
150 if (strcmp(method,"ask"))
151 if (nargin > optarg + 1)
152 error ("modmap: too many arguments");
156 if (floor(M/2) == M/2)
157 apkconst(2*ones(1,M/2),2*([1:M/2]-0.5)/(M-1));
159 apkconst([1,2*ones(1,floor(M/2))],2*([0:floor(M/2)])/(M-1));
162 if (floor(M/2) == M/2)
163 c = [ -2*([M/2:-1:1]-0.5)/(M-1), 2*([1:M/2]-0.5)/(M-1)];
165 c = [ -2*([floor(M/2):-1:1])/(M-1), 0, 2*([1:floor(M/2)])/(M-1)];
172 elseif (strcmp(method,"psk"))
173 if (nargin > optarg + 1)
174 error ("modmap: too many arguments");
185 elseif (strcmp(method,"msk"))
189 fd = varargin{optarg+1};
191 error ("modmap: the sampling rate must be a scalar");
194 if (nargin > optarg + 1)
195 error ("modmap: too many arguments");
198 ## This is an ugly plot, with little info. But hey!!!
199 try stem ([0, fd], [2, 1]);
201 error ("modmap: can not find stem-plot function");
203 title("MSK constellation");
204 xlabel("Frequency (Hz)");
206 axis([-fd, 2*fd, 0, 2]);
209 error ("modmap: too many arguments");
214 elseif (strcmp(method,"fsk"))
215 if (nargin > optarg + 1)
216 tone = varargin{optarg+2};
218 error ("modmap: the FSK tone must be a scalar");
223 if (nargin > optarg + 2)
224 error ("modmap: too many arguments");
228 ## This is an ugly plot, with little info. But hey!!!
229 try stem ([0:tone:(M-1)*tone], [2, ones(1,M-1)]);
231 error ("modmap: can not find stem-plot function");
233 title("FSK constellation");
234 xlabel("Frequency (Hz)");
236 axis([-tone, M*tone, 0, 2]);
240 elseif ((strcmp(method,"qask")) || (strcmp(method,"qsk")) || ...
241 (strcmp(method,"qam")))
242 if (nargin > optarg + 1)
243 error ("modmap: too many arguments");
250 elseif ((strcmp(method,"qask/cir")) || (strcmp(method,"qsk/cir")) || ...
251 (strcmp(method,"qam/cir")))
256 nsig = varargin{optarg+1};
257 if (!isvector(nsig) || (sum(nsig) < M))
258 error ("modmap: insufficient number of constellation point in qask/cir");
261 if (nargin > optarg + 1)
262 amp = varargin{optarg+2};
264 if (nargin > optarg + 2)
265 phs = varargin{optarg+3};
268 apkconst(nsig,amp,phs,"n");
270 c = apkconst(nsig,amp,phs);
276 elseif ((strcmp(method,"qask/arb")) || (strcmp(method,"qsk/arb")) || ...
277 (strcmp(method,"qam/arb")))
278 if (nargin == optarg)
279 [inphase, quadr] = qaskenco(M);
280 elseif (nargin == optarg+1)
281 c = varargin{optarg+1};
284 elseif (nargin == optarg+2)
285 inphase = varargin{optarg+1};
286 quadr = varargin{optarg+2};
288 error ("modmap: incorrectly defined mapping in 'qask/arb'");
290 if (!isreal(inphase) || !isreal(quadr) || !isvector(inphase) || ...
291 !isvector(quadr) || !all(isfinite(inphase)) || ...
292 !all(isfinite(quadr)) ||(length(inphase) < M))
293 error ("modmap: invalid arbitrary qask mapping");
297 inphase = inphase(:);
299 plot (inphase, quadr, "+r");
300 title("QASK Constellation");
302 ylabel("Quadrature");
303 axis([min(inphase)-1, max(inphase)+1, min(quadr)-1, max(quadr)+1]);
304 xd = 0.02 * max(inphase);
307 for i=1:length(inphase)
308 text(inphase(i)+xd,quadr(i),num2str(msg(i)));
311 for i=1:length(inphase)
312 text(inphase(i)+xd,quadr(i),num2str(i-1));
317 y = inphase(x+1) + 1i * quadr(x+1);
322 elseif (strcmp(method,"sample"))
324 error ("modmap: no constellation for resampling");
326 ## Just for resampling !!! So don't need anything else here
329 error ("modmap: unknown mapping method");