]> Creatis software - CreaPhase.git/blob - octave_packages/communications-1.1.1/demodmap.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / communications-1.1.1 / demodmap.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}  {z = } demodmap (@var{y},@var{fd},@var{fs},'ask',@var{m})
18 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'fsk',@var{m},@var{tone})
19 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'msk')
20 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'psk',@var{m})
21 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'qask',@var{m})
22 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'qask/cir',@var{nsig},@var{amp},@var{phs})
23 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'qask/arb',@var{inphase},@var{quadr})
24 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},@var{fd},@var{fs},'qask/arb',@var{map})
25 ## @deftypefnx {Function File}  {z = } demodmap (@var{y},[@var{fd}, @var{off}],@var{...})
26 ##
27 ## Demapping of an analog signal to a digital signal. The function 
28 ## @dfn{demodmap} must have at least three input arguments and one
29 ## output argument. Argument @var{y} is a complex variable representing
30 ## the analog signal to be demapped. The variables @var{fd} and @var{fs} are
31 ## the sampling rate of the of digital signal and the sampling rate of the
32 ## analog signal respectively. It is required that @code{@var{fs}/@var{fd}}
33 ## is an integer.
34 ##
35 ## The available mapping of the digital signal are
36 ##
37 ## @table @asis
38 ## @item 'ask'
39 ## Amplitude shift keying
40 ## @item 'fsk'
41 ## Frequency shift keying
42 ## @item 'msk'
43 ## Minimum shift keying
44 ## @item 'psk'
45 ## Phase shift keying
46 ## @item 'qask'
47 ## @itemx 'qsk'
48 ## @itemx 'qam' 
49 ## Quadraure amplitude shift keying
50 ## @end table
51 ##
52 ## In addition the 'qask', 'qsk' and 'qam' method can be modified with the
53 ## flags '/cir' or '/arb'. That is 'qask/cir' and 'qask/arb', etc are valid
54 ## methods and give circular- and arbitrary-qask mappings respectively. Also
55 ## the method 'fsk' and 'msk' can be modified with the flag '/max', in
56 ## which case @var{y} is assumed to be a matrix with @var{m} columns,
57 ## representing the symbol correlations.
58 ##
59 ## The variable @var{m} is the order of the modulation to use. By default
60 ## this is 2, and in general should be specified.
61 ##
62 ## For 'qask/cir', the additional arguments are the same as for 
63 ## @dfn{apkconst}, and you are referred to @dfn{apkconst} for the definitions
64 ## of the additional variables.
65 ##
66 ## For 'qask/arb', the additional arguments @var{inphase} and @var{quadr} give
67 ## the in-phase and quadrature components of the mapping, in a similar mapping
68 ## to the outputs of @dfn{qaskenco} with one argument. Similar @var{map}
69 ## represents the in-phase and quadrature components of the mapping as
70 ## the real and imaginary parts of the variable @var{map}.
71 ## @end deftypefn
72 ## @seealso{modmap,ddemodce,ademodce,apkconst,qaskenco}
73
74 function z = demodmap (y, fd, fs, varargin)
75
76   if (nargin < 3)
77     error ("demodmap: too few arguments");
78   endif
79
80   if (!isscalar(fs) || !isreal(fs) || !isreal(fd) ||(fs <= 0) || (fd <= 0))
81     error ("demodmap: sampling rates must be positive real values");
82   endif
83   if (abs(fs/fd - floor(fs/fd)) > eps)
84     error ("demodmap: the sample rate Fs must be an integer multiple of Fd");
85   endif
86
87   if (!isscalar(fd))
88     if (isequal(size(fd),[1,2]))
89       off = fd(2);
90       fd = fd(1);
91     else
92       error ("demodmap: sampling rate Fd must be a scalar or two-element row-vector");
93     endif
94   else
95     off = 0;
96   endif
97
98   if (nargin > 3)
99     method = varargin{1};
100     if (!ischar(method) || (!strcmp(method,"ask") && ...
101                                   isempty(findstr(method,"msk")) && isempty(findstr(method,"fsk")) && ...
102                                   isempty(findstr(method,"samp")) && !strcmp(method,"psk") && ...
103                                   !strcmp(method,"qask") && !strcmp(method,"qam") && ...
104                                   !strcmp(method,"qsk") && !strcmp(method,"qask/cir") && ...
105                                   !strcmp(method,"qam/cir") && !strcmp(method,"qsk/cir") && ...
106                                   !strcmp(method,"qask/arb") && !strcmp(method,"qam/arb") && ...
107                                   !strcmp(method,"qsk/arb")))
108       error ("modmap: unknown mapping method");
109     endif
110   else
111     method = "sample";
112   endif
113
114   if (!isreal(off) || (off < 0) || (off != floor(off)) || ...
115       (off >= fs/fd))
116     error ("demodmap: offset must be an integer in the range [0, Fs/Fd)");
117   endif
118   if (off == 0)
119     off = round(fs/fd);
120   endif
121
122   if (min(size(y)) == 1)
123     y = y(off:round(fs/fd):length(y));
124   else
125     y = y(off:round(fs/fd):size(y,1),:);
126   endif
127
128   if (strcmp(method,"ask") || !isempty(findstr(method,"fsk")) || ...
129       strcmp(method,"psk") || strcmp(method,"qask") || ...
130       strcmp(method,"qam") || strcmp(method,"qsk"))
131     if (nargin > 4)
132       M = varargin{2};
133     else
134       M = 2;
135     endif
136     if (!isempty(findstr(method,"fsk")) && (nargin > 5))
137       error ("demodmap: too many arguments");
138     endif
139   endif
140
141   z = [];
142   if (!isempty(findstr(method,"fsk")) || !isempty(findstr(method,"msk")))
143     if (findstr(method,"msk"))
144       if (nargin > 4)
145               error ("demodmap: too many arguments");
146       endif
147       M = 2;
148       tone = fd/2;
149     else
150       if (nargin > 5)
151               tone = varargin{3};
152       else
153               tone = fd;
154       endif
155       if (nargin > 6)
156               error ("demodmap: too many arguments");
157       endif
158     endif
159
160     if (findstr(method,"/max"))
161       if (size(y,2) != M)
162               error ("demodmap: when using correlation must have M columns");
163       endif
164       ## We have an M-column maximum from which with pick index of the maximum
165       ## value in each row as the decoded value
166       [a, b] = max(y');
167       z = (b - 1)';
168     else
169       c = [0:M-1]*tone;
170     endif
171   elseif (strcmp(method,"ask"))
172     if (floor(M/2) == M/2)
173       c = [ -2*([M/2:-1:1]-0.5)/(M-1),  2*([1:M/2]-0.5)/(M-1)];
174     else
175       c = [ -2*([floor(M/2):-1:1])/(M-1),  0, 2*([1:floor(M/2)])/(M-1)];
176     endif
177   elseif (strcmp(method,"psk"))
178     c = apkconst(M,[],[]);
179   elseif (!isempty(findstr(method,"qask")) || ...
180                 !isempty(findstr(method,"qsk")) || ... 
181                 !isempty(findstr(method,"qam")))
182     if (findstr(method,"/cir"))
183       nsig = 2;
184       amp = [];
185       phs = [];
186       if (nargin > 4)
187               nsig = varargin{2};
188               if (!isvector(nsig))
189                 error ("modmap: invalid number of constellation point in qask/cir");
190               endif
191       endif
192       if (nargin > 5)
193               amp = varargin{3};
194       endif
195       if (nargin > 6)
196               phs = varargin{4};
197       endif
198       c = apkconst(nsig,amp,phs);
199       M = length(c);
200     elseif (findstr(method,"/arb"))
201       if (nargin == 4)
202               c = qaskenco(2);
203       elseif (nargin == 5)
204               c = varargin{2}; 
205       elseif (nargin == 6)
206               inphase = varargin{2}; 
207               quadr = varargin{3};
208               c = inphase + 1i*quadr;
209       elseif (nargin > 6)
210               error ("demodmap: too many arguments");
211       endif
212       M = length(c);
213     else
214       ## Could do "c = qaskenco(M)", but qaskdeco's speed is not dependent
215       ## on M, while speed of code below is O(M).
216       z = qaskdeco(y,M);
217     endif
218   endif
219
220   ## Have we decoded yet? If not have a mapping that we can use.
221   if (isempty(z))
222     c = c(:);
223     z = zeros(size(y));
224     if (size(y,1) == 1)
225       [a, b] = min(abs(repmat(y(:).',M,1) - repmat(c,1,size(y,2))));
226       z = b - 1;
227     elseif (size(y,1) == 1)
228       [a, b] = min(abs(repmat(y(:),M,1) - repmat(c,1,size(y,1))));
229       z = (b - 1).';
230     else
231       for i=1:size(y,1)
232               [a, b] = min(abs(repmat(y(i,:),M,1) - repmat(c,1,size(y,2))));
233               z(i,:) = b - 1;
234       end
235     endif
236   endif
237
238 endfunction
239
240