]> Creatis software - CreaPhase.git/blob - octave_packages/communications-1.1.1/modmap.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / communications-1.1.1 / modmap.m
1 ## Copyright (C) 2003 David Bateman
2 ##
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
6 ## version.
7 ##
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
11 ## details.
12 ##
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/>.
15
16 ## -*- texinfo -*-
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})
26 ##
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})}.
34 ##
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}}
40 ## is an integer.
41 ##
42 ## The available mapping of the digital signal are
43 ##
44 ## @table @asis
45 ## @item 'ask'
46 ## Amplitude shift keying
47 ## @item 'fsk'
48 ## Frequency shift keying
49 ## @item 'msk'
50 ## Minimum shift keying
51 ## @item 'psk'
52 ## Phase shift keying
53 ## @item 'qask'
54 ## @itemx 'qsk'
55 ## @itemx 'qam' 
56 ## Quadraure amplitude shift keying
57 ## @end table
58 ##
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.
62 ##
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.
66 ##
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.
70 ##
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}.
76 ## @end deftypefn
77 ## @seealso{demodmap,dmodce,amodce,apkconst,qaskenco}
78
79 function y = modmap(varargin)
80
81   method = "sample";
82   if (nargout == 0)
83     if (nargin < 1)
84       error ("modmap: too few arguments");
85     endif
86     method = varargin{1};
87     optarg = 1;
88     M = 2;
89     fd = 1;
90     fs = 1;
91   elseif (nargout == 1)
92     if (nargin < 3)
93       error ("modmap: too few arguments");
94     endif
95     x = varargin{1};
96     fd = varargin{2};
97     fs = varargin{3};
98     if (nargin > 3)
99       method = varargin{4};
100     endif
101     M = max(2,2^ceil(log2(max(x(:)) + 1)));
102     optarg = 4;
103
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");
107     endif
108     if (abs(fs/fd - floor(fs/fd)) > eps)
109       error ("modmap: the sample rate Fs must be an integer multiple of Fd");
110     endif
111
112     nn = round(fs/fd);
113     if (min(size(x)) == 1)
114       n = length(x);
115       yy = zeros(n,1);
116       if (size(x,1) == 1)
117         yy = yy';
118       end
119       for i=1:nn
120         yy(i:nn:nn*n) = x;
121       end
122     else
123       n = size(x,1);
124       yy = zeros(n*nn,size(x,2));
125       for i=1:nn
126         yy(i:nn:nn*n,:) = x;
127       end
128     endif
129     x = yy;
130   else
131     error ("modmap: too many output arguments");
132   endif
133
134   if (!ischar(method))
135     error ("modmap: mapping method to use must be a string");
136   endif
137
138   if (isempty(findstr(method,"/arb")) && isempty(findstr(method,"/cir")))
139     if (nargin > optarg)
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");
143       endif
144     endif
145     if ((nargout != 0) && (M < max(x(:)) + 1))
146       error ("modmap: illegal symbol in data for modulation order");
147     endif
148   endif
149
150   if (strcmp(method,"ask"))
151     if (nargin > optarg + 1)
152       error ("modmap: too many arguments");
153     endif
154
155     if (nargout == 0)
156       if (floor(M/2) == M/2)
157         apkconst(2*ones(1,M/2),2*([1:M/2]-0.5)/(M-1));
158       else
159         apkconst([1,2*ones(1,floor(M/2))],2*([0:floor(M/2)])/(M-1));
160       endif
161     else
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)];
164       else
165         c = [ -2*([floor(M/2):-1:1])/(M-1),  0, 2*([1:floor(M/2)])/(M-1)];
166       endif
167       y = c(x+1);
168       if (size(x,2) == 1)
169         y = y';
170       endif
171     endif
172   elseif (strcmp(method,"psk"))
173     if (nargin > optarg + 1)
174       error ("modmap: too many arguments");
175     endif
176     if (nargout == 0)
177       apkconst(M,"n");
178     else
179       c = apkconst(M);
180       y = c(x+1);
181       if (size(x,2) == 1)
182         y = y';
183       endif
184     endif
185   elseif (strcmp(method,"msk"))
186
187     if (nargout == 0)
188       if (nargin > optarg)
189         fd = varargin{optarg+1};
190         if (!isscalar(fd))
191           error ("modmap: the sampling rate must be a scalar");
192         endif
193       endif
194       if (nargin > optarg + 1)
195         error ("modmap: too many arguments");
196       endif
197
198       ## This is an ugly plot, with little info. But hey!!!
199       try stem ([0, fd], [2, 1]);
200       catch
201         error ("modmap: can not find stem-plot function");
202       end
203       title("MSK constellation");
204       xlabel("Frequency (Hz)");
205       ylabel("");
206       axis([-fd, 2*fd, 0, 2]);
207     else
208       if (nargin > optarg)
209         error ("modmap: too many arguments");
210       endif
211       tone = fd/2;
212       y = tone * x;
213     endif
214   elseif (strcmp(method,"fsk"))
215     if (nargin > optarg + 1)
216       tone = varargin{optarg+2};
217       if (!isscalar(tone))
218         error ("modmap: the FSK tone must be a scalar");
219       endif
220     else
221       tone = fd;
222     endif
223     if (nargin > optarg + 2)
224       error ("modmap: too many arguments");
225     endif
226
227     if (nargout == 0)
228       ## This is an ugly plot, with little info. But hey!!!
229       try stem ([0:tone:(M-1)*tone], [2, ones(1,M-1)]);
230       catch
231         error ("modmap: can not find stem-plot function");
232       end
233       title("FSK constellation");
234       xlabel("Frequency (Hz)");
235       ylabel("");
236       axis([-tone, M*tone, 0, 2]);
237     else
238       y = tone * x;
239     endif
240   elseif ((strcmp(method,"qask")) || (strcmp(method,"qsk")) || ...
241           (strcmp(method,"qam")))
242     if (nargin > optarg + 1)
243       error ("modmap: too many arguments");
244     endif
245     if (nargout == 0)
246       qaskenco(M);
247     else
248       y = qaskenco(x, M);
249     endif
250   elseif ((strcmp(method,"qask/cir")) || (strcmp(method,"qsk/cir")) || ...
251           (strcmp(method,"qam/cir")))
252     nsig = M;
253     amp = [];
254     phs = [];
255     if (nargin > optarg)
256       nsig = varargin{optarg+1};
257       if (!isvector(nsig) || (sum(nsig) < M))
258         error ("modmap: insufficient number of constellation point in qask/cir");
259       endif
260     endif
261     if (nargin > optarg + 1)
262       amp = varargin{optarg+2};
263     endif
264     if (nargin > optarg + 2)
265       phs = varargin{optarg+3};
266     endif
267     if (nargout == 0)
268       apkconst(nsig,amp,phs,"n");
269     else
270       c = apkconst(nsig,amp,phs);
271       y = c(x+1);
272       if (size(x,2) == 1)
273         y = y';
274       endif
275     endif
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}; 
282       inphase = real(c);
283       quadr = imag(c);
284     elseif (nargin == optarg+2)
285       inphase = varargin{optarg+1}; 
286       quadr = varargin{optarg+2};
287     else
288       error ("modmap: incorrectly defined mapping in 'qask/arb'");
289     endif
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");
294     endif
295     
296     if (nargout == 0)
297       inphase = inphase(:);
298       quadr = quadr(:);
299       plot (inphase, quadr, "+r");
300       title("QASK Constellation");
301       xlabel("In-phase");
302       ylabel("Quadrature");
303       axis([min(inphase)-1, max(inphase)+1, min(quadr)-1, max(quadr)+1]);
304       xd = 0.02 * max(inphase);
305       if (nargin == 2)
306         msg = msg(:);
307         for i=1:length(inphase)
308           text(inphase(i)+xd,quadr(i),num2str(msg(i)));
309         end
310       else
311         for i=1:length(inphase)
312           text(inphase(i)+xd,quadr(i),num2str(i-1));
313         end
314       endif
315       refresh;
316     else
317       y = inphase(x+1) + 1i * quadr(x+1);
318       if (size(x,2) == 1)
319         y = y';
320       endif
321     endif
322   elseif (strcmp(method,"sample"))
323     if (nargout == 0)
324       error ("modmap: no constellation for resampling");
325     endif
326     ## Just for resampling !!! So don't need anything else here
327     y = x;
328   else
329     error ("modmap: unknown mapping method");
330   endif
331
332 endfunction