ShortTimeFourierTransform - Maple Help

SignalProcessing

 ShortTimeFourierTransform
 compute the short-time Fourier transform of a signal

 Calling Sequence ShortTimeFourierTransform( signal, options )

Parameters

 signal - 1-D rtable or list of data.

Options

 • samplerate: (optional) Positive numeric value for the sampling rate. The default is 1.0.
 • overlapsize: (optional) Non-negative integer which specifies the target minimum overlap size of the segments. The default is 0.
 • segmentsize: (optional) Positive integer for the size of the overlapping segments. The default is the largest power of 2 that is not larger than the size of signal.
 • fftnormalization: (optional) One of none, symmetric, or full, indicates the normalization to be applied when using the Fast Fourier Transform (FFT). The default is symmetric.
 • temperendpoints: (optional) Either true or false, specifies whether the short-time power spectra are to be tempered at the endpoints. The default is false.
 • window: (optional) Either a list, name, or string, specifies the windowing command to be applied to the overlapping segments. The default is "none" (for no windowing to be applied). If a list is passed, the first element provides the name of the windowing command, and any remaining terms are passed as options to the command.
 • windownormalization (optional) Either true or false, indicates if the windowing function is to be normalized. The default is true.
 • frequencyunit: (optional) Unit which specifies the unit of frequency. The default is Unit(Hz). Either of the forms algebraic or Unit(algebraic) is accepted, and the unit must be convertible to a valid unit of frequency.
 • timeunit: (optional) Unit which specifies the unit of time. The default is Unit(s). Either of the forms algebraic or Unit(algebraic) is accepted, and the unit must be convertible to a valid unit of time.
 • powerscale: (optional) Unit which indicates the scaling, if any, to be applied to the power spectrum. Either of the forms algebraic or Unit(algebraic) is accepted, and the unit must be convertible to a valid unit of power (see below for more details). The default is Unit(1/Hz).
 • downsample: (optional) Positive integer, which specifies the down-sample factor applied to the spectrogram. The default is 1.
 • spectrogramoptions: (optional) List of additional plot options to be passed when creating the spectrogram. The default is [].
 • output: (optional) The type of output. The supported options are:
 – stft: Returns a Matrix of float[8] datatype containing the Short-Time Fourier Transform (STFT). This is the default.
 – stps: Returns a Matrix of float[8] datatype containing the Short-Time Power Spectrum (STPS).
 – signal: Returns a Matrix of float[8] or complex[8] datatype containing the signal, with each column representing a short-time segment.
 – frequencies: Returns a Vector, of float[8] datatype and length the same as signal, containing the frequencies.
 – times: Returns a Vector, of float[8] datatype and length the same as signal, containing the times.
 – spectrogram: Returns the spectrogram of the STPS.
 – record: Returns a record with the previous options.
 – list of any of the above options: Returns an expression sequence with the corresponding outputs, in the same order.

Description

 • The ShortTimeFourierTransform command takes a 1-D rtable or list signal, and computes the Short-Time Fourier Transform using the provided options.
 • The STFT is calculated using the following steps:
 1 Divide the signal into segments of equal size with equal or nearly-equal overlaps.
 2 Apply the windowing procedure to each segment.
 3 Take the Discrete Fourier Transform (DFT) of each windowed segment.
 4 Form the STFT Matrix, with each column corresponding to a segment.
 • The values of $a=\mathrm{overlapsize}$, $b=\mathrm{segmentsize}$, and $n=\mathrm{numelems}\left(\mathrm{signal}\right)$ must satisfy $2\le n$, $0\le a$, $2\le b$, $a, and $b\le n$.
 • Since the DFT will be computed for each segment, it is suggested that, for larger signal lengths, segmentsize be a power of 2 and no less than 4, so that the FFT will be utilized.
 • The passed value of overlapsize is used to determine the number $c$ of overlapping segments of size $b=\mathrm{segmentsize}$. The values of $b$ and $c$ determine the smallest possible overlap size $p$ and the excess number $q$ of overlaps of size $p+1$. If we denote $n=\mathrm{numelems}\left(\mathrm{signal}\right)$, then $\mathrm{bc}=n+p\left(c-1-q\right)+\left(p+1\right)q$ for the $1 case. When $c=1$, there are no overlaps and the single segment is just the original signal.
 • The value of window, when not passed as a list, should be the name or string, with or without the Window suffix, that corresponds to the windowing command. For example, to use a Hamming window, you can pass window=Hamming or window="HammingWindow". In both cases, the command SignalProcessing[HammingWindow] will be used internally. Similarly, you can pass window=["Exponential",0.5] or window=[ExponentialWindow,0.5] to use SignalProcessing[ExponentialWindow] with parameter value 0.5.
 • To apply a window to a Vector $V$ of length $n$, the window is first applied to another Vector $W$ of size $n$ and filled with ones, and then $V$ is multiplied element-wise by $W$. When windownormalization=true, $W$ is first normalized with respect to its Root Mean Square (RMS).
 • The STPS is calculated from the STFT by taking the square of the absolute value of each element. To scale the STPS with the powerscale option, units which are dimensionally equivalent to the following are accepted:
 • 1: No further scaling is performed.
 • 1/Hz: The STPS is divided by $r=\mathrm{samplerate}$.
 • 1/rad/Hz: STPS is divided by $2\mathrm{\pi }r$.
 • dB: Each element $u$ of STPS is replaced with $10{\mathrm{Typesetting}:-\mathrm{_Hold}\left(\left[\mathrm{%log}\right]\right)}_{10}\left(u\right)$.
 • dB/Hz: Each element $u$ of STPS is replaced with $10{\mathrm{Typesetting}:-\mathrm{_Hold}\left(\left[\mathrm{%log}\right]\right)}_{10}\left(\frac{u}{r}\right)$.
 • dB/rad/Hz: Each element $u$ of STPS is replaced with $10{\mathrm{Typesetting}:-\mathrm{_Hold}\left(\left[\mathrm{%log}\right]\right)}_{10}\left(\frac{u}{2\mathrm{\pi }r}\right)$.
 • When temperendpoints=true, the values in the first and last rows of the unscaled STPS Matrix are halved. Note that the segment size must be three or more for tempering.
 • The frequencies and times Vectors are of size $n=\mathrm{numelems}\left(\mathrm{signal}\right)$, and have components defined by, respectively, ${F}_{i}=\frac{\left(i-1\right)r}{n}$ and ${T}_{i}=\frac{i-1}{r}$, where $r=\mathrm{samplerate}$.
 • The samplerate option can also include a unit of frequency. If a unit is provided, and it differs from frequencyunit, then the sample rate will be converted to use the same unit as frequencyunit.
 • If signal is an rtable of type AudioTools:-Audio, the sample rate is inferred from the attributes. Should samplerate also be passed, it will be overridden.
 • When the signal is real-valued and thus the STPS is symmetric, the spectrogram will display only the first half of frequency components, and the remaining STPS will be doubled in value.
 • Maple will attempt to coerce the provided signal to a 1-D Vector of either float[8] or complex[8] datatype, and an error will be thrown if this is not possible. For this reason, it is most efficient for the passed input to use this datatype.
 • The input signal cannot have an indexing function, and must use rectangular storage.
 • The ShortTimeFourierTransform command is not thread safe.
 • As the underlying implementation of the SignalProcessing package is a module, it is also possible to use the form SignalProcessing:-ShortTimeFourierTransform to access the command from the package. For more information, see Module Members.

Examples

 > $\mathrm{with}\left(\mathrm{SignalProcessing}\right):$

Example 1

 • Here, we will create a signal, and then find the STFT along with the spectrogram. First, create Vectors for the times and signal:
 > $T≔\mathrm{Vector}\left(\left[\mathrm{seq}\right]\left(0..599\right),\mathrm{datatype}=\mathrm{float}\left[8\right]\right)$
 ${T}{≔}\begin{array}{c}\left[\begin{array}{c}{0.}\\ {1.}\\ {2.}\\ {3.}\\ {4.}\\ {5.}\\ {6.}\\ {7.}\\ {8.}\\ {9.}\\ {⋮}\end{array}\right]\\ \hfill {\text{600 element Vector[column]}}\end{array}$ (1)
 > $g≔t↦2\cdot \mathrm{cos}\left(\frac{\mathrm{\pi }\cdot t}{5}\right)+9\cdot \mathrm{sin}\left(\frac{3\cdot \mathrm{\pi }\cdot t}{4}\right)$
 ${g}{≔}{t}{↦}{2}{\cdot }{\mathrm{cos}}{}\left(\frac{{\mathrm{\pi }}{\cdot }{t}}{{5}}\right){+}{9}{\cdot }{\mathrm{sin}}{}\left(\frac{{3}{\cdot }{\mathrm{\pi }}{\cdot }{t}}{{4}}\right)$ (2)
 > $X≔\mathrm{map}\left[\mathrm{evalhf}\right]\left(g,T\right)$
 ${X}{≔}\begin{array}{c}\left[\begin{array}{c}{2.}\\ {7.98199501942882}\\ {-8.38196601125011}\\ {5.74592704192903}\\ {-1.61803398874989}\\ {-8.36396103067894}\\ {7.38196601125011}\\ {-6.98199501942882}\\ {0.618033988749888}\\ {7.98199501942883}\\ {⋮}\end{array}\right]\\ \hfill {\text{600 element Vector[column]}}\end{array}$ (3)
 • Second, define a sampling rate:
 > $r≔1.0$
 ${r}{≔}{1.0}$ (4)
 • Third, we choose overlap and segment sizes:
 > $a≔50$
 ${a}{≔}{50}$ (5)
 > $b≔64$
 ${b}{≔}{64}$ (6)
 • Finally, we find the STFT and spectrogram, which can be exported in a record, to prevent re-calculation:
 > $R≔\mathrm{ShortTimeFourierTransform}\left(X,\mathrm{samplerate}=r,\mathrm{overlapsize}=a,\mathrm{segmentsize}=b,\mathrm{powerscale}=\frac{\mathrm{dB}}{\mathrm{Hz}},\mathrm{output}=\mathrm{record}\right):$
 > $R\left[\mathrm{stft}\right]$
 $\begin{array}{c}\left[\begin{array}{ccccccccccc}{0.452254248593765}{+}{0.}{}{I}& {-0.731762745781191}{+}{0.}{}{I}& {0.731762745781163}{+}{0.}{}{I}& {-0.452254248593760}{+}{0.}{}{I}& {5.29576382746200}{×}{{10}}^{{-14}}{+}{0.}{}{I}& {0.452254248593693}{+}{0.}{}{I}& {-0.731762745781219}{+}{0.}{}{I}& {0.731762745781136}{+}{0.}{}{I}& {-0.452254248593777}{+}{0.}{}{I}& {-1.14686038443779}{×}{{10}}^{{-13}}{+}{0.}{}{I}& {\dots }\\ {0.458103081239895}{+}{0.119055723572651}{}{I}& {-0.747075188443345}{-}{0.0735804837231072}{}{I}& {0.750689965813126}{-}{5.09639710695945}{×}{{10}}^{{-14}}{}{I}& {-0.467566691255788}{+}{0.0735804837230584}{}{I}& {0.00584883264628924}{-}{0.119055723572561}{}{I}& {0.458103081239808}{+}{0.119055723572706}{}{I}& {-0.747075188443415}{-}{0.0735804837231341}{}{I}& {0.750689965813138}{-}{1.21076262499908}{×}{{10}}^{{-13}}{}{I}& {-0.467566691255696}{+}{0.0735804837230264}{}{I}& {0.00584883264627392}{-}{0.119055723572590}{}{I}& {\dots }\\ {0.477549775416864}{+}{0.256829793879361}{}{I}& {-0.797987294767435}{-}{0.158729541941084}{}{I}& {0.813620790107453}{-}{3.07278826385311}{×}{{10}}^{{-14}}{}{I}& {-0.518478797579915}{+}{0.158729541941136}{}{I}& {0.0252955268231243}{-}{0.256829793879352}{}{I}& {0.477549775416892}{+}{0.256829793879322}{}{I}& {-0.797987294767507}{-}{0.158729541941026}{}{I}& {0.813620790107494}{-}{1.13901281869386}{×}{{10}}^{{-13}}{}{I}& {-0.518478797579869}{+}{0.158729541941184}{}{I}& {0.0252955268231298}{-}{0.256829793879433}{}{I}& {\dots }\\ {0.518078600347356}{+}{0.443751734464053}{}{I}& {-0.904093135959439}{-}{0.274253654465539}{}{I}& {0.944774822630554}{-}{1.13375261133164}{×}{{10}}^{{-14}}{}{I}& {-0.624584638771976}{+}{0.274253654465603}{}{I}& {0.0658243517537162}{-}{0.443751734464020}{}{I}& {0.518078600347254}{+}{0.443751734463960}{}{I}& {-0.904093135959505}{-}{0.274253654465477}{}{I}& {0.944774822630644}{+}{3.17026638561705}{×}{{10}}^{{-15}}{}{I}& {-0.624584638771924}{+}{0.274253654465483}{}{I}& {0.0658243517536304}{-}{0.443751734463908}{}{I}& {\dots }\\ {0.602110787484806}{+}{0.753379696120457}{}{I}& {-1.12409225803439}{-}{0.465614258636399}{}{I}& {1.21670869250566}{+}{7.70217223333702}{×}{{10}}^{{-15}}{}{I}& {-0.844583760846963}{+}{0.465614258636476}{}{I}& {0.149856538891093}{-}{0.753379696120308}{}{I}& {0.602110787484814}{+}{0.753379696120499}{}{I}& {-1.12409225803430}{-}{0.465614258636470}{}{I}& {1.21670869250568}{-}{1.02001740387436}{×}{{10}}^{{-13}}{}{I}& {-0.844583760846907}{+}{0.465614258636378}{}{I}& {0.149856538890960}{-}{0.753379696120307}{}{I}& {\dots }\\ {0.818498982177274}{+}{1.46213093609298}{}{I}& {-1.69060390650374}{-}{0.903646614508081}{}{I}& {1.91695560005889}{-}{5.13550186955885}{×}{{10}}^{{-15}}{}{I}& {-1.41109540931637}{+}{0.903646614508082}{}{I}& {0.366244733583425}{-}{1.46213093609300}{}{I}& {0.818498982177135}{+}{1.46213093609273}{}{I}& {-1.69060390650360}{-}{0.903646614508379}{}{I}& {1.91695560005917}{-}{1.60119114358006}{×}{{10}}^{{-13}}{}{I}& {-1.41109540931592}{+}{0.903646614508157}{}{I}& {0.366244733583586}{-}{1.46213093609269}{}{I}& {\dots }\\ {2.14957489287454}{+}{5.59531630310445}{}{I}& {-5.17540588231530}{-}{3.45809565312495}{}{I}& {6.22440773028770}{-}{4.83249175788398}{×}{{10}}^{{-14}}{}{I}& {-4.89589738512782}{+}{3.45809565312492}{}{I}& {1.69732064428080}{-}{5.59531630310444}{}{I}& {2.14957489287458}{+}{5.59531630310431}{}{I}& {-5.17540588231510}{-}{3.45809565312477}{}{I}& {6.22440773028744}{+}{6.64822040565860}{×}{{10}}^{{-14}}{}{I}& {-4.89589738512772}{+}{3.45809565312475}{}{I}& {1.69732064428082}{-}{5.59531630310438}{}{I}& {\dots }\\ {-0.973278223662599}{-}{3.98409636106183}{}{I}& {3.00032971865245}{+}{2.46230696559101}{}{I}& {-3.88135723857348}{-}{5.89034126019999}{×}{{10}}^{{-14}}{}{I}& {3.27983821583988}{-}{2.46230696559097}{}{I}& {-1.42553247225628}{+}{3.98409636106177}{}{I}& {-0.973278223662480}{-}{3.98409636106180}{}{I}& {3.00032971865231}{+}{2.46230696559105}{}{I}& {-3.88135723857336}{-}{9.91526871604398}{×}{{10}}^{{-14}}{}{I}& {3.27983821583980}{-}{2.46230696559082}{}{I}& {-1.42553247225621}{+}{3.98409636106156}{}{I}& {\dots }\\ {-0.197642353760559}{-}{1.56898919154386}{}{I}& {0.969688648355291}{+}{0.969688648355338}{}{I}& {-1.37134683778327}{+}{3.55271367880050}{×}{{10}}^{{-14}}{}{I}& {1.24919714554286}{-}{0.969688648355371}{}{I}& {-0.649896602354277}{+}{1.56898919154376}{}{I}& {-0.197642353760571}{-}{1.56898919154376}{}{I}& {0.969688648355313}{+}{0.969688648355366}{}{I}& {-1.37134683778325}{-}{2.79599688422156}{×}{{10}}^{{-14}}{}{I}& {1.24919714554277}{-}{0.969688648355298}{}{I}& {-0.649896602354275}{+}{1.56898919154378}{}{I}& {\dots }\\ {-0.0211842963533224}{-}{1.00100170050692}{}{I}& {0.507715456474521}{+}{0.618653073709642}{}{I}& {-0.800316568836095}{-}{2.76903279478891}{×}{{10}}^{{-14}}{}{I}& {0.787223953661978}{-}{0.618653073709686}{}{I}& {-0.473438544947025}{+}{1.00100170050691}{}{I}& {-0.0211842963533259}{-}{1.00100170050681}{}{I}& {0.507715456474500}{+}{0.618653073709691}{}{I}& {-0.800316568836079}{-}{6.21486467755365}{×}{{10}}^{{-15}}{}{I}& {0.787223953661960}{-}{0.618653073709622}{}{I}& {-0.473438544947115}{+}{1.00100170050684}{}{I}& {\dots }\\ {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {⋮}& {}\end{array}\right]\\ \hfill {\text{64 × 40 Matrix}}\end{array}$ (7)
 > $R\left[\mathrm{spectrogram}\right]$

Example 2

 • The signal can also originate from a WAV file recording of a violin:
 > $\mathrm{with}\left(\mathrm{AudioTools}\right):$
 > $\mathrm{file}≔\mathrm{cat}\left(\mathrm{kernelopts}\left(\mathrm{datadir}\right),\mathrm{kernelopts}\left(\mathrm{dirsep}\right),"audio",\mathrm{kernelopts}\left(\mathrm{dirsep}\right),"ViolinThreePosVibrato.wav"\right)$
 ${\mathrm{file}}{≔}{"/maple/cbat/active/169462/data/audio/ViolinThreePosVibrato.wav"}$ (8)
 > $\mathrm{Violin}≔\mathrm{ToMono}\left(\mathrm{Read}\left(\mathrm{file},\mathrm{samples}=1000..5000\right)\right)$
 ${\mathrm{Violin}}{≔}\left[\begin{array}{cc}{"Sample Rate"}& {44100}\\ {"File Format"}& {\mathrm{PCM}}\\ {"File Bit Depth"}& {16}\\ {"Channels"}& {1}\\ {"Samples/Channel"}& {4001}\\ {"Duration"}& {0.09073}{}{s}\end{array}\right]$ (9)
 • Visually:
 > $a≔128$
 ${a}{≔}{128}$ (10)
 > $b≔256$
 ${b}{≔}{256}$ (11)
 > $\mathrm{ShortTimeFourierTransform}\left(\mathrm{Violin},\mathrm{overlapsize}=a,\mathrm{segmentsize}=b,\mathrm{frequencyunit}=\mathrm{kHz},\mathrm{powerscale}=\frac{\mathrm{dB}}{\mathrm{Hz}},\mathrm{output}=\mathrm{spectrogram}\right)$
 • The spectrogram can be generated with less points by using down sampling. For instance, the following reduces the number of elements in each column of the STPS by a factor of 4:
 > $\mathrm{ShortTimeFourierTransform}\left(\mathrm{Violin},\mathrm{overlapsize}=a,\mathrm{segmentsize}=b,\mathrm{frequencyunit}=\mathrm{kHz},\mathrm{powerscale}=\frac{\mathrm{dB}}{\mathrm{Hz}},\mathrm{downsample}=4,\mathrm{output}=\mathrm{spectrogram}\right)$

Compatibility

 • The SignalProcessing[ShortTimeFourierTransform] command was introduced in Maple 2021.