summaryrefslogtreecommitdiff
path: root/graphics/pstricks
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-11-09 03:02:39 +0000
committerNorbert Preining <norbert@preining.info>2023-11-09 03:02:39 +0000
commit3425ad695d75cc781b0fe3412db3aa2ad5985959 (patch)
tree9ec65bca1de4085db47511e67369ea2b71a488fa /graphics/pstricks
parentdada699771828d1aa3c78ecf55a2131e5f5799f3 (diff)
CTAN sync 202311090302
Diffstat (limited to 'graphics/pstricks')
-rw-r--r--graphics/pstricks/contrib/dsptricks/README4
-rw-r--r--graphics/pstricks/contrib/dsptricks/dspTricksManual.pdfbin212782 -> 202907 bytes
-rw-r--r--graphics/pstricks/contrib/dsptricks/dspTricksManual.tex172
-rw-r--r--graphics/pstricks/contrib/dsptricks/dspblocks.sty11
-rw-r--r--graphics/pstricks/contrib/dsptricks/dspfunctions.sty97
-rw-r--r--graphics/pstricks/contrib/dsptricks/dsptricks.sty4
6 files changed, 212 insertions, 76 deletions
diff --git a/graphics/pstricks/contrib/dsptricks/README b/graphics/pstricks/contrib/dsptricks/README
index 8252f6138a..b7584fe8ca 100644
--- a/graphics/pstricks/contrib/dsptricks/README
+++ b/graphics/pstricks/contrib/dsptricks/README
@@ -1,7 +1,7 @@
DSPTricks (with DSPFunctios and DSPBlocks)
-v1.0 - July 2014
+v1.1 - November 2023
-(c) Paolo Prandoni, 2014, paolo.prandoni@epfl.ch
+(c) Paolo Prandoni, 2014-2023, paolo.prandoni@epfl.ch
The package DSPTricks is a set of LaTeX macros
(based on PSTricks) for plotting the kind of graphs
diff --git a/graphics/pstricks/contrib/dsptricks/dspTricksManual.pdf b/graphics/pstricks/contrib/dsptricks/dspTricksManual.pdf
index ae5f6ebc7d..4a4635802b 100644
--- a/graphics/pstricks/contrib/dsptricks/dspTricksManual.pdf
+++ b/graphics/pstricks/contrib/dsptricks/dspTricksManual.pdf
Binary files differ
diff --git a/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex b/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex
index 2b733a9faa..e8be7a5bf1 100644
--- a/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex
+++ b/graphics/pstricks/contrib/dsptricks/dspTricksManual.tex
@@ -1,13 +1,13 @@
% User manual for the DSPTricks package
-% (c) Paolo Prandoni, 2014
-% v1.0, July 2014
+% (c) Paolo Prandoni, 2014-2023
+% v1.1, November 2023
% For more information, authors@sp4comm.org
-\documentclass[a4paper,10pt]{ltxdoc}
+\documentclass[a4paper,14pt]{ltxdoc}
\usepackage{float}
\usepackage{fancyvrb}
\usepackage{enumitem}
-\usepackage[utopia]{mathdesign}
+\usepackage{newpxtext,newpxmath}
\usepackage{url}
\usepackage{dsptricks,dspfunctions,dspblocks}
@@ -41,29 +41,37 @@
\begin{document}
-\title{\dspt \\ A Set of Macros for Digital Signal Processing Plots}
+\title{\dspt: a Set of Macros \\ for Digital Signal Processing Plots}
\author{Paolo Prandoni}
-\date{}
+%\date{}
\maketitle
-The package \dspt\ is a set of \LaTeX\ macros for plotting the kind of graphs and figures that are usually employed in digital signal processing publications\footnote{The original macros have been written by the author while working on the manuscript for~\cite{PV}.}; the package relies on \psTricks~\cite{TVZ93,HV} to generate its graphic output.
+The package \dspt\ provides a set of \LaTeX\ macros for plotting the kind of graphs and figures that are usually employed in digital signal processing publications\footnote{The original macros have been written by the author while working on the manuscript for~\cite{PV}.}; the package relies on \psTricks~\cite{TVZ93,HV} to generate its graphic output.
%\footnote{Please note that these macros have been written rather quickly and chiefly for personal use. Use at your own risk and caveat emptor.}
+\\
+
+The basic \dspt\ plot is a boxed chart displaying a discrete-time or a continuous-time signal, or a superposition of both; discrete-time signals are plotted using the ``lollipop'' formalism while continuous-time functions are rendered as smooth curves. Other types of plots that commonly occur in the signal processing literature, and for which \dspt\ offers macros, are frequency-domain plots and pole-zero plots. \dspt\ comes with two companion packages:
+\begin{itemize}
+ \item \dspb\ provides a set of macros to design simple signal processing block diagrams;
+ \item \dspf\ provides a set of signal shapes commonly used in basic signal processing in terms of PostScript primitives (such as rect, sinc, etc), as well as macros to compute DFTs, frequency responses, and filter outputs on the fly.
+\end{itemize}
-The basic \dspt\ plot is a boxed chart displaying a discrete-time or a continuous-time signal, or a superposition of both; discrete-time signals are plotted using the ``lollipop'' formalism while continuous-time functions are rendered as smooth curves. Other types of plots that commonly occur in the signal processing literature, and for which \dspt\ offers macros, are frequency plots and pole-zero plots. The companion package \dspf\ defines some signals commonly used in basic signal processing in terms of PostScript primitives, while the package \dspb\ provides a set of macros to design simple signal processing block diagrams.
+
+The idea behind these macros is to be able to write a completely self-contained signal processing manuscript without the need of an external numerical package to precompute the necessary signals.
\section{Drawing Signals}
-Signal plots in \dspt\ are defined by a Cartesian grid enclosed by a box; there are three fundamental types of plots:
+Signal plots in \dspt\ use a Cartesian grid enclosed by a box; there are three fundamental types of plots:
\begin{itemize}
\item discrete-time plots,
\item continuous-time plots,
\item frequency-domain plots;
\end{itemize}
-discrete- and continuous-time plots can be mixed, whereas frequency-domain plots involve a re-labeling of the horizontal axis in trigonometric units.
+discrete- and continuous-time plots can be mixed in the same box, whereas frequency-domain plots involve a re-labeling of the horizontal axis using trigonometric units.
\subsection{The {\tt dspPlot} environment}
@@ -101,7 +109,7 @@ This sets up a data plot with the horizontal axis spanning the \meta{xmin}-\meta
-Within a |dspPlot| environment you can use the plotting commands described in the next sections, as well as any \psTricks\ command; in the latter case, the \psTricks\ values for |xunit| and |yunit| are scaled to the axes (i.e., they correspond to the cartesian values of the plot). Other useful commands for all data plots are the following:
+Within a |dspPlot| environment you can use the plotting commands described in the next sections, as well as any \psTricks\ command; in the latter case, the \psTricks\ values for |xunit| and |yunit| are equal to the units used for the axes. Other useful commands for all data plots are the following:
\begin{itemize}
\item \DescribeEnv{dspClip} in order to make sure that all drawing commands are clipped to the bounding box defined by the box chart, you can enclose them individually in a predefined |dspClip| environment. See section~\ref{clipEx} for an example.
\item \DescribeMacro{dspPlotFrame} to redraw the framing box (useful to ``smooth out'' plots touching the frame) you can issue the command |\dspPlotFrame|
@@ -109,7 +117,9 @@ Within a |dspPlot| environment you can use the plotting commands described in th
\begin{quote}
|\dspCustomTicks|\oarg{options}\marg{pos label pos label ...}
\end{quote}
- where the axis is specified in the options field as either |axis=x| (default) or |axis=y| and where the argument is a list of space-separated coordinate-label pairs. If you use math mode for the labels, \emph{do not use spaces in your formulas} since that will confuse the list-parsing macros.
+ where the axis is specified in the options field as either |axis=x| (default) or |axis=y| and where the argument is a list of space-separated coordinate-label pairs. If you use math mode for the labels, \emph{do not use spaces in your formulas} since that will confuse the list-parsing macros.
+
+ \textbf{NOTE}: there is an incompatibility between |\dspCustomTicks| and the |tabular| environment. When using |\dspCustomTicks| in a table, enclose all lines between |\begin{dspPlot}| and |\end{dspPlot}| in a group (\{ ~\}).
\item \DescribeMacro{dspText} place a text label anywhere in the plot using the axes coordinates:
\begin{quote}
|\dspText|(x, y)\marg{label}
@@ -145,7 +155,7 @@ The following commands generate stem (or ``lollipop'') plots; available options
\end{quote}
The PostScript code must use the variable |x| as the independent variable; the |\dspPlot| environment sweeps |x| over all integers in the \meta{xmin}-\meta{xmax} interval defined for the plot; this can be changed for each individual signal by using the options \DescribeMacro{xmin,xmax} |xmin|=\meta{m} and/or |xmax|=\meta{n}. If you use \TeX\ macros in your PS code, make sure you include a space at the end of the macro definition. For instance, use |\def\gain\{0.75|\textvisiblespace|}|.
- \item \DescribeMacro{dspSignalOpt} to perform a PostScript initialization sequence before evaluating the signal, use
+ \item \DescribeMacro{dspSignalOpt} to perform a PostScript initialization sequence before plotting the discrete-time signal, use
\begin{quote}
|\dspSignalOpt|\oarg{options}\marg{init}\marg{PostScript code}
\end{quote}
@@ -185,6 +195,12 @@ Continuous-time functions can be plotted with the following commands:
|\dspFunc|\oarg{options}\marg{PostScript code}
\end{quote}
again, the PostScript code must use |x| as the independent variable; the range for |x| is the \meta{xmin}-\meta{xmax} interval and can be controlled for each signal independently via the|xmin| and |xmax| options.
+
+ \item \DescribeMacro{\dspFuncOpt} to perform a PostScript initialization sequence before plotting the continuous-time signal, use
+ \begin{quote}
+ |\dspFuncOpt|\oarg{options}\marg{init}\marg{PostScript code}
+ \end{quote}
+ where \meta{init} is a valid PostScript sequence.
\item \DescribeMacro{dspFuncData} To plot a smooth function obtained by interpolating a list of space separated time-value pairs use
\begin{quote}
@@ -192,6 +208,12 @@ Continuous-time functions can be plotted with the following commands:
\end{quote}
the interpolation is performed by the PostScript interpreter and can be controlled if necessary by using the appropriate \psTricks\ options.
+ \item \DescribeMacro{dspFuncDataAt} To plot a smooth function obtained by interpolating a list of space separated values use
+ \begin{quote}
+ |\dspFuncDataAt|\oarg{options}\marg{start}\marg{data}
+ \end{quote}
+ This macro works like |\dspFuncData| but the time indices are assumed to be increasing integers beginning at \meta{start}.
+
\item \DescribeMacro{dspFuncFile} For a continuous-time smooth interpolation of a pre-computed set of data points, use
\begin{quote}
|\dspFuncFile|\oarg{options}\marg{fileName}
@@ -450,17 +472,16 @@ To plot analog spectra, just set up a plot environment as you would to plot a co
\vblock
\begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},%
- yticks=2,ylabel={$X(j\Omega)$}]{-10,10}{-1,5}
+ yticks=2,ylabel={$X(f)$}]{-10,10}{-1,5}
\dspFunc{x abs 4 gt {0} {x abs 2 div dup mul 4 exch sub} ifelse}
- \dspCustomTicks{-4 $-\Omega_N$ 0 $0$ 4 $\Omega_N$ 8 $\Omega_s$}
+ \dspCustomTicks[axis=x]{-4 $-f_N$ 0 $0$ 4 $f_N$ 8 $F_s$}
\end{dspPlot}
\end{Verbatim}
\begin{centerfig}
- \begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},%
- yticks=2,ylabel={$X(j\Omega)$}]{-10,10}{-1.5,5}
+ \begin{dspPlot}[xtype=freq,xticks=custom,xlabel={freq. (Hz)},yticks=2,ylabel={$X(f)$}]{-10,10}{0,5}
\dspFunc{x abs 4 gt {0} {x abs 2 div dup mul 4 exch sub} ifelse}
- \dspCustomTicks{-4 $-\Omega_N$ 0 $0$ 4 $\Omega_N$ 8 $\Omega_s$}
+ \dspCustomTicks[axis=x]{-4 $-f_N$ 0 $0$ 4 $f_N$ 8 $F_s$}
\end{dspPlot}
\end{centerfig}
@@ -471,63 +492,73 @@ To facilitate the creation of plots that commonly occur in signal processing the
\subsubsection*{Basic Shapes:}
\begin{itemize}
- \item |\dspRect{a}{b}| computes a rectangular (box) function centered in $a$ and with support $2b$, i.e. $\mbox{rect}((x-a)/b)$ where
+ \item \DescribeMacro{\dspRect} |\dspRect{a}{b}| computes the function $\mbox{rect}((x-a)/b)$ where
\[
\mbox{rect}(x) = \left\{\begin{array}{ll}
1 & \mbox{if $|x|<1/2$} \\
0 & \mbox{otherwise}
\end{array}\right.
\]
- \item |\dspTri{a}{b}| computes a triangle function centered in $a$ and with support $2b$
- \item |\dspSinc{a}{b}| computes the scaled sinc function $\mbox{sinc}((x-a)/b)$, where
+ i.e. a rectangular (box) function centered in $a$ and with support $2b$.
+ \item \DescribeMacro{\dspTri} |\dspTri{a}{b}| computes a triangular function centered in $a$ and with support $2b$
+ \item \DescribeMacro{\dspSinc} |\dspSinc{a}{b}| computes the scaled sinc function $\mbox{sinc}((x-a)/b)$, where
\[
\mbox{sinc}(x) = \frac{\sin(\pi x)}{\pi x}
\]
- \item |\dspQuad{a}{b}| computes a quadratic function (inverted parabola) centered in $a$ and with support $2b$
- \item |\dspExpDec{a}{b}| computes the decaying exponential response $b^(x-a)u[x-a]$
- \item |\dspPorkpie{a}{b}| computes a ``porkpie hat'' shape centered in $a$ and with support $2b$
- \item |\dspRaisedCos{a}{b}{r}| computes a raised cosine centered in $a$ with cutoff $b$ and rolloff $r$
+ \item \DescribeMacro{\dspQuad} |\dspQuad{a}{b}| computes a quadratic function (inverted parabola) centered in $a$ and with support $2b$
+ \item \DescribeMacro{\dspExpDec} |\dspExpDec{a}{b}| computes the decaying exponential response $b^{(x-a)}u[x-a]$
+ \item \DescribeMacro{\dspPorkpie} |\dspPorkpie{a}{b}| computes a ``porkpie hat'' shape centered in $a$ and with support $2b$
+ \item \DescribeMacro{\dspRaisedCos} |\dspRaisedCos{a}{b}{r}| computes a raised cosine centered in $a$ with cutoff $b$ and rolloff $r$
+ \item \DescribeMacro{\dspSincS} |\dspSincS{a}{N}| computes the function
+ \[
+ \frac{\sin(\omega(2N+1)/2)}{\sin(\omega/2)} \qquad{\omega = \pi(x-a)}
+ \]
+ that is, the Discrete-Time Fourier transform (DTFT) of a zero-centered, symmetric $2N+1$-tap rectangular signal. This is used in frequency plots and in this case the free variable $x$, which ranges from $-1$ to $1$, is rescaled as $\omega = \pi x$.
+ The parameter $a$ can be used to shift the DTFT to the chosen center frequency over the $[-1, 1]$ interval.
+ \item \DescribeMacro{\dspSincC} |\dspSincC{a}{N}| computes the DTFT \textit{magnitude} for a causal $N$-tap rectangular signal:
+ \[
+ \vert \frac{\sin(\omega(N/2))}{\sin(\omega/2)} \vert \qquad {\omega = \pi(x-a)}
+ \]
+ See |\dspSincS{a}{N}| for details on $x$ and $a$.
\end{itemize}
\subsubsection*{Discrete Fourier Transform:}
\begin{itemize}
- \item |\dspDFTMAG{x_0 x_1 ... x_{N-1}}| computes the magnitude of the Discrete Fourier transform (DFT) of the provided data points\footnote{Please note that the underlying implementation of the macro is not optimized; the computing time will be quadratic in the number of data points.}; the input value should be an integer.
+ \item \DescribeMacro{\dspDFTMAG} |\dspDFTMAG{a_0 a_1 ... a_{N-1}}| computes the magnitude of the Discrete Fourier transform (DFT) of the provided data points\footnote{Please note that the underlying implementation of the macro is not optimized; the computing time will be quadratic in the number of data points.}:
\[
- X[k] = \vert \sum_{n=0}^{N-1}x[n]e^{j\frac{2\pi}{N}nk} \vert
+ \vert \sum_{n=0}^{N-1}a_n e^{j\frac{2\pi}{N}nk} \vert \qquad n = x;
\]
- \item |\dspDFTRE{x_0 x_1 ... x_{N-1}}| computes the real part of the DFT
- \item |\dspDFTIM{x_0 x_1 ... x_{N-1}}| computes the imaginary part of the DFT
+ the value of $x$ should range over integers only.
+ \item |\dspDFTRE{a_0 a_1 ... a_{N-1}}| computes the real part of the DFT
+ \item |\dspDFTIM{a_0 a_1 ... a_{N-1}}| computes the imaginary part of the DFT
\end{itemize}
-\subsubsection*{Notable DTFTs:}
-\begin{itemize}
- \item |\dspSincS{a}{N}| computes the Discrete-Time Fourier transform (DTFT) of a zero-centered, symmetric $2N+1$-tap rectangular signal:
- \[
- X(e^{j\omega}) = \frac{\sin(\omega(2N+1)/2)}{\sin(\omega/2)}
- \]
- The parameter $a$ can be used to shift the DTFT to the chosen center frequency.
- \item |\dspSincC{a}{N}| computes the DTFT magnitude of a causal $N$-tap rectangular signal:
- \[
- \vert X(e^{j\omega})\vert =\frac{\sin(\omega(N/2))}{\sin(\omega/2)}
- \]
- The parameter $a$ can be used to shift the DTFT to the chosen center frequency.
-\end{itemize}
\subsubsection*{Frequency Responses:}
\begin{itemize}
- \item |\dspFIRI{a_0 a_1 ... a_{N-1}}| computes the (real-valued) frequency response of a zero centered $(2N+1)$-tap Type-I FIR filter with coefficients
+ \item \DescribeMacro{\dspFIRI} |\dspFIRI{b_0 b_1 ... b_{N-1}}| computes the (real-valued) frequency response for $\omega = \pi x$ of a zero centered $(2N-1)$-tap Type-I FIR filter with coefficients
\[
- a_{N-1}, a_{N-2}, \ldots, a_{1}, a_{0}, a_{1}, a_{2}, \ldots, a_{N-1}.
+ b_{N-1}, b_{N-2}, \ldots, b_{1}, b_{0}, b_{1}, b_{2}, \ldots, b_{N-1}.
\]
- The coefficient $a_0$ is the center tap and you need only specify the coefficients from $a_0$ to $a_{N-1}$.
+ The coefficient $b_0$ is the center tap and you need only specify the coefficients from $b_0$ to $b_{N-1}$.
- \item |\dspTFM{a_0 a_1 ... a_{N-1}}{b_1 b_2 ... b_{M-1}}| computes the magnitude response of a generic digital filter defined by the constant-coefficient difference equation:
+ \item \DescribeMacro{\dspTFM} |\dspTFM{b_0 b_1 b_2 ... b_{M-1}}{a_1 ... a_{N-1}}| computes the magnitude response for $\omega = \pi x$ of a generic digital filter defined by the constant-coefficient difference equation:
\[
- y[n] = a_0 x[n] + ... + a_{N-1} x[n-N+1] - b_1 y[n-1] - ... - b_{M-1} y[n-M+1]
+ y[n] = b_0 x[n] + ... + b_{N-1} x[n-N+1] - a_1 y[n-1] - ... - a_{M-1} y[n-M+1]
\]
\end{itemize}
+\subsubsection*{Filtering Data:}
+\begin{itemize}
+ \item \DescribeMacro{\dspFilter} |\dspFilter| computes the output of a generic IIR filter
+ \[
+ y[n] = b_0 x + b_1 x[n-1] + ... + b_{N-1} x[n-N+1] - a_1 y[n-1] - ... - a_{M-1} y[n-M+1]
+ \]
+ The filter coefficients should be set in the initialization portion of either |\dspSignalOpt| or |\dspFuncOpt| via the macro:\\ |\dspSetFilter{b_0 b_1 ... b_{M-1}}{a_1 ... a_{N-1}}}|
+\end{itemize}
+
+
For instance:
\vblock
@@ -590,10 +621,9 @@ The magnitude of simple FIR and IIR filter can be graphed easily like so:
\dspFunc{x \dspTFM{0.000008952611389 0.000071620891113
0.000250673118897 0.000501346237795 0.000626682797244
0.000501346237795 0.000250673118897 0.000071620891113
- 0.000008952611389}{ 1.000000000000000 -5.975292291885454
- 16.581223292021008 -27.714232735429224 30.395097583553124
- -22.347296704268793 10.745098004349103 -3.089246336974975
- 0.407076858898017}}
+ 0.000008952611389}{ -5.975292291885454 16.581223292021008
+ -27.714232735429224 30.395097583553124 -22.347296704268793
+ 10.745098004349103 -3.089246336974975 0.407076858898017}}
\end{dspPlot}
\end{Verbatim}
@@ -604,14 +634,46 @@ The magnitude of simple FIR and IIR filter can be graphed easily like so:
\dspFunc{x \dspTFM{0.000008952611389 0.000071620891113
0.000250673118897 0.000501346237795 0.000626682797244
0.000501346237795 0.000250673118897 0.000071620891113
- 0.000008952611389}{ 1.000000000000000 -5.975292291885454
- 16.581223292021008 -27.714232735429224 30.395097583553124
- -22.347296704268793 10.745098004349103 -3.089246336974975
- 0.407076858898017}}
+ 0.000008952611389}{ -5.975292291885454 16.581223292021008
+ -27.714232735429224 30.395097583553124 -22.347296704268793
+ 10.745098004349103 -3.089246336974975 0.407076858898017}}
\end{dspPlot}
\end{centerfig}
+In this example we plot a triangular signal and its filtered version using the Chebyshev lowpass filter defined above:
+
+\vblock
+\begin{dspPlot}[xtype=freq,xticks=4]{-1,1}{0,1.1}
+\begin{dspPlot}[xout=true]{0,40}{-.4,1.1}
+ \dspSignal[linecolor=lightgray]{x \dspTri{5}{5}}
+ \dspSignalOpt[linecolor=blue!60]{
+ \dspSetFilter{0.000008952611389 0.000071620891113
+ 0.000250673118897 0.000501346237795 0.000626682797244
+ 0.000501346237795 0.000250673118897 0.000071620891113
+ 0.000008952611389}{ -5.975292291885454 16.581223292021008
+ -27.714232735429224 30.395097583553124 -22.347296704268793
+ 10.745098004349103 -3.089246336974975 0.407076858898017}}
+ {x \dspTri{5}{5} \dspFilter}
+\end{dspPlot}
+\end{Verbatim}
+
+\begin{centerfig}
+ \begin{dspPlot}[xout=true]{0,40}{-.4,1.1}
+ \dspSignal[linecolor=lightgray]{x \dspTri{5}{5}}
+ \dspSignalOpt[linecolor=blue!60]{\dspSetFilter{0.000008952611389 0.000071620891113
+ 0.000250673118897 0.000501346237795 0.000626682797244
+ 0.000501346237795 0.000250673118897 0.000071620891113
+ 0.000008952611389}{ -5.975292291885454 16.581223292021008
+ -27.714232735429224 30.395097583553124 -22.347296704268793
+ 10.745098004349103 -3.089246336974975 0.407076858898017}}
+ {x \dspTri{5}{5} \dspFilter}
+ \end{dspPlot}
+\end{centerfig}
+
+
+
+
\section{Drawing Regions of Convergence, Poles and Zeros}
diff --git a/graphics/pstricks/contrib/dsptricks/dspblocks.sty b/graphics/pstricks/contrib/dsptricks/dspblocks.sty
index b7aba995a9..9c19970ef2 100644
--- a/graphics/pstricks/contrib/dsptricks/dspblocks.sty
+++ b/graphics/pstricks/contrib/dsptricks/dspblocks.sty
@@ -11,7 +11,7 @@
%% set of macros to draw the types of block diagrams commonly
%% used in DSP theory
%%
-%% v1.0, July 2014
+%% v1.1, November 2023
%%
% required packages:
@@ -103,6 +103,15 @@
\psline{->}(0,-1.8)(0,2)%
\psplot[linewidth=1pt, plotpoints=500,linejoin=1]{-2.5}{2.5}{x \dspSinc{0}{0.5} 1.5 mul .5 sub}%
\endpspicture}}}
+\newcommand{\BDclip}[1][1em]{
+ \newskip\tmpLen \tmpLen=#1%
+ \raisebox{-1.5\tmpLen}{%
+ \psframebox[linewidth=1.2pt]{%
+ \psset{unit=#1,linearc=0,linewidth=2pt}%
+ \pspicture(-3,-2)(3,2)%
+ \psline[linecolor=gray](-2,-0)(2,-0)%
+ \psline(-1.5,-1.7)(0,-1.7)(0,1.7)(1.5,1.7)%
+ \endpspicture}}}
\newenvironment{dspBlocks}[2]{%
\begin{psmatrix}[colsep=#1,rowsep=#2,emnode=R] }{%
diff --git a/graphics/pstricks/contrib/dsptricks/dspfunctions.sty b/graphics/pstricks/contrib/dsptricks/dspfunctions.sty
index ae63eccaa0..c42588a55d 100644
--- a/graphics/pstricks/contrib/dsptricks/dspfunctions.sty
+++ b/graphics/pstricks/contrib/dsptricks/dspfunctions.sty
@@ -11,7 +11,7 @@
%% set of postscript macros to compute the value of various DSP
%% common functions
%%
-%% v1.0, July 2014
+%% v1.1, November 2023
%%
\ProvidesPackage{dspfunctions}[2014/07/24 package for signal processing graphics]
@@ -108,6 +108,27 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
+% \dspAudio{a}{b} zero-DC baseband shape (e.g. an audio signal)
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspAudio#1#2{%
+ #1 sub #2 div
+ abs
+ dup 1 gt
+ {pop 0}%
+ {dup 0.01 le
+ {pop 0}
+ {dup 0.2 lt
+ {-30 mul}
+ {1 exch sub -8 mul}
+ ifelse
+ 2.7 exch exp 1 add 1 exch div 0.5 sub 2 mul
+ }
+ ifelse}
+ ifelse}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
% Fourier transform of a symmetric 2N+1 tap rect
% \dspSincS{a}{N} sin((x-a)(2N+1)/2)/sin((x-a)/2)
%
@@ -200,12 +221,12 @@
%
% Magnitude response of a generic digital filter defined by the
% constant-coefficient difference equation:
-% y[n] = a_0 x[n] + a_1 x[n-1] + ... + a_{N-1} x[n-N+1]
-% - b_1 y[n-1] - ... - b_{M-1} y[n-M+1]
+% y[n] = b_0 x[n] + b_1 x[n-1] + ... + b_{N-1} x[n-N+1]
+% - a_1 y[n-1] - ... - a_{M-1} y[n-M+1]
%
% The response is computed at the given normalized frequency value
%
-% \dspTFM{a_0 a_1 ... a_{N-1}}{b_1 b_2 ... b_{M-1}}
+% \dspTFM{b_0 b_1 b_2 ... b_{M-1}}{a_0 a_1 ... a_{N-1}}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\dspTFM#1#2{%
@@ -214,17 +235,17 @@
0 % index n
0 % accumulator Re
0 % accumulator Im
- [#1] % coefficients a_n
+ [#1] % coefficients b_n
{ % STACK (neglecting saved input at bottom):
- % x n re im a_n
- dup % x n re im a_n a_n
- 5 index % x n re im a_n a_n x
- 5 index % x n re im a_n a_n x n
- mul dup % x n re im a_n a_n nx nx
- sin exch cos % x n re im a_n a_n sin(nx) cos(nx)
- 4 1 roll mul % x n re im cos(nx) a_n (a_n)sin(nx)
- 3 1 roll mul % x n re im (a_n)sin(nx) (a_n)cos(nx)
- 4 1 roll add % x n (a_n)cos(nx) re im'
+ % x n re im b_n
+ dup % x n re im b_n b_n
+ 5 index % x n re im b_n b_n x
+ 5 index % x n re im b_n b_n x n
+ mul dup % x n re im b_n b_n nx nx
+ sin exch cos % x n re im b_n b_n sin(nx) cos(nx)
+ 4 1 roll mul % x n re im cos(nx) b_n (b_n)sin(nx)
+ 3 1 roll mul % x n re im (b_n)sin(nx) (b_n)cos(nx)
+ 4 1 roll add % x n (b_n)cos(nx) re im'
3 1 roll add exch % x n re' im'
3 2 roll 1 add % x re' im' n'
3 1 roll % x n re im
@@ -233,10 +254,10 @@
dup mul exch dup mul add % (re^2 + im^2)
sqrt % mag of the numerator of transfer function
exch % bring up saved input copy
- 0 % same loop for the b_n coefficients
+ 0 % same loop for the a_n coefficients
0
0
- [#2]
+ [1 #2]
{
dup
5 index
@@ -256,3 +277,47 @@
div %0 eq {pop pop 0} {div} ifelse
}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Filter the data with a system implementing the transfer function
+% y[n] = b_0 x[n] + b_1 x[n-1] + ... + b_{N-1} x[n-N+1]
+% - a_1 y[n-1] - ... - a_{M-1} y[n-M+1]
+%
+% Use the setFilter macro in the setup part of the drawing command
+% and then \dspFilter{b_0 b_1 b_2 ... b_{M-1}}{a_1 ... a_{N-1}}
+%
+% \dspSignalOpt{\dspSetFilter{b_0 b_1 b_2 ... b_{M-1}}{a_1 ... a_{N-1}}}{x ... \dspFilter}
+%
+% NB: skip a_0 (assumed = 1) from the feedback part!
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\dspSetFilter#1#2{%
+ /b [#1] def
+ /xlen b length def
+ /xbuf [xlen {0} repeat] def
+ /a [#2] def
+ /ylen a length def
+ /ybuf [ylen {0} repeat] def
+}
+\def\dspFilter{
+ xbuf aload pop pop xbuf astore /xbuf exch def
+ 0
+ 0 1 xlen 1 sub {
+ dup
+ xbuf exch get
+ exch
+ b exch get
+ mul add
+ } for
+ 0 1 ylen 1 sub {
+ dup
+ ybuf exch get
+ exch
+ a exch get
+ mul sub
+ } for
+ dup
+ ybuf aload pop pop ybuf astore /ybuf exch def
+}
+
diff --git a/graphics/pstricks/contrib/dsptricks/dsptricks.sty b/graphics/pstricks/contrib/dsptricks/dsptricks.sty
index 5b075c043c..e5a022d043 100644
--- a/graphics/pstricks/contrib/dsptricks/dsptricks.sty
+++ b/graphics/pstricks/contrib/dsptricks/dsptricks.sty
@@ -12,7 +12,7 @@
%% while writing the textbook "Signal Processing for Communication" by P. Prandoni
%% and M. Vetterli, freely available at www.sp4comm.org
%%
-%% v1.0, July 2014
+% v1.1, November 2023
%%
\RequirePackage{pstricks}
\RequirePackage{pstricks-add}
@@ -207,7 +207,7 @@
\def\dspMkTk##1##2{{\dspTickLabelYR{##1}{##2}}}%
\fi
\def\dspMakeTicks##1 ##2 ##3\relax{%
- \ifx&##3&
+ \ifx\relax##3\relax
\dspMkTk{##1}{##2} %
\else
\dspMkTk{##1}{##2} \relax %