X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fcommunications-1.1.1%2Fmodmap.m;fp=octave_packages%2Fcommunications-1.1.1%2Fmodmap.m;h=147ef632afd3bf3a8a355464611ef676a54a764a;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/communications-1.1.1/modmap.m b/octave_packages/communications-1.1.1/modmap.m new file mode 100644 index 0000000..147ef63 --- /dev/null +++ b/octave_packages/communications-1.1.1/modmap.m @@ -0,0 +1,332 @@ +## Copyright (C) 2003 David Bateman +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} {} modmap (@var{method},@var{...}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'ask',@var{m}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'fsk',@var{m},@var{tone}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'msk') +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'psk',@var{m}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask',@var{m}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/cir',@var{nsig},@var{amp},@var{phs}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/arb',@var{inphase},@var{quadr}) +## @deftypefnx {Function File} {y = } modmap (@var{x},@var{fd},@var{fs},'qask/arb',@var{map}) +## +## Mapping of a digital signal to an analog signal. With no output arguments +## @dfn{modmap} plots the constellation of the mapping. In this case the +## first argument must be the string @var{method} defining one of 'ask', +## 'fsk', 'msk', 'qask', 'qask/cir' or 'qask/arb'. The arguments following +## the string @var{method} are generally the same as those after the +## corresponding string in the fucntion call without output arguments. +## The exception is @code{modmap('msk',@var{Fd})}. +## +## With an output argument, @var{y} is the complex mapped analog signal. In +## this case the arguments @var{x}, @var{fd} and @var{fs} are required. The +## variable @var{x} is the digital signal to be mapped, @var{fd} is the +## sampling rate of the of digital signal and the @var{fs} is the sampling +## rate of the analog signal. It is required that @code{@var{fs}/@var{fd}} +## is an integer. +## +## The available mapping of the digital signal are +## +## @table @asis +## @item 'ask' +## Amplitude shift keying +## @item 'fsk' +## Frequency shift keying +## @item 'msk' +## Minimum shift keying +## @item 'psk' +## Phase shift keying +## @item 'qask' +## @itemx 'qsk' +## @itemx 'qam' +## Quadraure amplitude shift keying +## @end table +## +## In addition the 'qask', 'qsk' and 'qam' method can be modified with the +## flags '/cir' or '/arb'. That is 'qask/cir' and 'qask/arb', etc are valid +## methods and give circular- and arbitrary-qask mappings respectively. +## +## The additional argument @var{m} is the order of the modulation to use. +## @var{m} must be larger than the largest element of @var{x}. The variable +## @var{tone} is the FSK tone to use in the modulation. +## +## For 'qask/cir', the additional arguments are the same as for +## @dfn{apkconst}, and you are referred to @dfn{apkconst} for the definitions +## of the additional variables. +## +## For 'qask/arb', the additional arguments @var{inphase} and @var{quadr} give +## the in-phase and quadrature components of the mapping, in a similar mapping +## to the outputs of @dfn{qaskenco} with one argument. Similar @var{map} +## represents the in-phase and quadrature components of the mapping as +## the real and imaginary parts of the variable @var{map}. +## @end deftypefn +## @seealso{demodmap,dmodce,amodce,apkconst,qaskenco} + +function y = modmap(varargin) + + method = "sample"; + if (nargout == 0) + if (nargin < 1) + error ("modmap: too few arguments"); + endif + method = varargin{1}; + optarg = 1; + M = 2; + fd = 1; + fs = 1; + elseif (nargout == 1) + if (nargin < 3) + error ("modmap: too few arguments"); + endif + x = varargin{1}; + fd = varargin{2}; + fs = varargin{3}; + if (nargin > 3) + method = varargin{4}; + endif + M = max(2,2^ceil(log2(max(x(:)) + 1))); + optarg = 4; + + if (!isscalar(fs) || !isscalar(fd) || !isreal(fs) || !isreal(fd) || ... + (fs <= 0) || (fd <= 0)) + error ("modmap: sampling rates must be positive real values"); + endif + if (abs(fs/fd - floor(fs/fd)) > eps) + error ("modmap: the sample rate Fs must be an integer multiple of Fd"); + endif + + nn = round(fs/fd); + if (min(size(x)) == 1) + n = length(x); + yy = zeros(n,1); + if (size(x,1) == 1) + yy = yy'; + end + for i=1:nn + yy(i:nn:nn*n) = x; + end + else + n = size(x,1); + yy = zeros(n*nn,size(x,2)); + for i=1:nn + yy(i:nn:nn*n,:) = x; + end + endif + x = yy; + else + error ("modmap: too many output arguments"); + endif + + if (!ischar(method)) + error ("modmap: mapping method to use must be a string"); + endif + + if (isempty(findstr(method,"/arb")) && isempty(findstr(method,"/cir"))) + if (nargin > optarg) + M = varargin{optarg+1}; + if (!isscalar(M) || !isreal(M) || (M < 0) || (M != floor(M))) + error ("modmap: modulation order must be a real positive integer"); + endif + endif + if ((nargout != 0) && (M < max(x(:)) + 1)) + error ("modmap: illegal symbol in data for modulation order"); + endif + endif + + if (strcmp(method,"ask")) + if (nargin > optarg + 1) + error ("modmap: too many arguments"); + endif + + if (nargout == 0) + if (floor(M/2) == M/2) + apkconst(2*ones(1,M/2),2*([1:M/2]-0.5)/(M-1)); + else + apkconst([1,2*ones(1,floor(M/2))],2*([0:floor(M/2)])/(M-1)); + endif + else + if (floor(M/2) == M/2) + c = [ -2*([M/2:-1:1]-0.5)/(M-1), 2*([1:M/2]-0.5)/(M-1)]; + else + c = [ -2*([floor(M/2):-1:1])/(M-1), 0, 2*([1:floor(M/2)])/(M-1)]; + endif + y = c(x+1); + if (size(x,2) == 1) + y = y'; + endif + endif + elseif (strcmp(method,"psk")) + if (nargin > optarg + 1) + error ("modmap: too many arguments"); + endif + if (nargout == 0) + apkconst(M,"n"); + else + c = apkconst(M); + y = c(x+1); + if (size(x,2) == 1) + y = y'; + endif + endif + elseif (strcmp(method,"msk")) + + if (nargout == 0) + if (nargin > optarg) + fd = varargin{optarg+1}; + if (!isscalar(fd)) + error ("modmap: the sampling rate must be a scalar"); + endif + endif + if (nargin > optarg + 1) + error ("modmap: too many arguments"); + endif + + ## This is an ugly plot, with little info. But hey!!! + try stem ([0, fd], [2, 1]); + catch + error ("modmap: can not find stem-plot function"); + end + title("MSK constellation"); + xlabel("Frequency (Hz)"); + ylabel(""); + axis([-fd, 2*fd, 0, 2]); + else + if (nargin > optarg) + error ("modmap: too many arguments"); + endif + tone = fd/2; + y = tone * x; + endif + elseif (strcmp(method,"fsk")) + if (nargin > optarg + 1) + tone = varargin{optarg+2}; + if (!isscalar(tone)) + error ("modmap: the FSK tone must be a scalar"); + endif + else + tone = fd; + endif + if (nargin > optarg + 2) + error ("modmap: too many arguments"); + endif + + if (nargout == 0) + ## This is an ugly plot, with little info. But hey!!! + try stem ([0:tone:(M-1)*tone], [2, ones(1,M-1)]); + catch + error ("modmap: can not find stem-plot function"); + end + title("FSK constellation"); + xlabel("Frequency (Hz)"); + ylabel(""); + axis([-tone, M*tone, 0, 2]); + else + y = tone * x; + endif + elseif ((strcmp(method,"qask")) || (strcmp(method,"qsk")) || ... + (strcmp(method,"qam"))) + if (nargin > optarg + 1) + error ("modmap: too many arguments"); + endif + if (nargout == 0) + qaskenco(M); + else + y = qaskenco(x, M); + endif + elseif ((strcmp(method,"qask/cir")) || (strcmp(method,"qsk/cir")) || ... + (strcmp(method,"qam/cir"))) + nsig = M; + amp = []; + phs = []; + if (nargin > optarg) + nsig = varargin{optarg+1}; + if (!isvector(nsig) || (sum(nsig) < M)) + error ("modmap: insufficient number of constellation point in qask/cir"); + endif + endif + if (nargin > optarg + 1) + amp = varargin{optarg+2}; + endif + if (nargin > optarg + 2) + phs = varargin{optarg+3}; + endif + if (nargout == 0) + apkconst(nsig,amp,phs,"n"); + else + c = apkconst(nsig,amp,phs); + y = c(x+1); + if (size(x,2) == 1) + y = y'; + endif + endif + elseif ((strcmp(method,"qask/arb")) || (strcmp(method,"qsk/arb")) || ... + (strcmp(method,"qam/arb"))) + if (nargin == optarg) + [inphase, quadr] = qaskenco(M); + elseif (nargin == optarg+1) + c = varargin{optarg+1}; + inphase = real(c); + quadr = imag(c); + elseif (nargin == optarg+2) + inphase = varargin{optarg+1}; + quadr = varargin{optarg+2}; + else + error ("modmap: incorrectly defined mapping in 'qask/arb'"); + endif + if (!isreal(inphase) || !isreal(quadr) || !isvector(inphase) || ... + !isvector(quadr) || !all(isfinite(inphase)) || ... + !all(isfinite(quadr)) ||(length(inphase) < M)) + error ("modmap: invalid arbitrary qask mapping"); + endif + + if (nargout == 0) + inphase = inphase(:); + quadr = quadr(:); + plot (inphase, quadr, "+r"); + title("QASK Constellation"); + xlabel("In-phase"); + ylabel("Quadrature"); + axis([min(inphase)-1, max(inphase)+1, min(quadr)-1, max(quadr)+1]); + xd = 0.02 * max(inphase); + if (nargin == 2) + msg = msg(:); + for i=1:length(inphase) + text(inphase(i)+xd,quadr(i),num2str(msg(i))); + end + else + for i=1:length(inphase) + text(inphase(i)+xd,quadr(i),num2str(i-1)); + end + endif + refresh; + else + y = inphase(x+1) + 1i * quadr(x+1); + if (size(x,2) == 1) + y = y'; + endif + endif + elseif (strcmp(method,"sample")) + if (nargout == 0) + error ("modmap: no constellation for resampling"); + endif + ## Just for resampling !!! So don't need anything else here + y = x; + else + error ("modmap: unknown mapping method"); + endif + +endfunction