1######################################################################## 2## 3## Copyright (C) 1995-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {@var{y} =} stft (@var{x}) 28## @deftypefnx {} {@var{y} =} stft (@var{x}, @var{win_size}) 29## @deftypefnx {} {@var{y} =} stft (@var{x}, @var{win_size}, @var{inc}) 30## @deftypefnx {} {@var{y} =} stft (@var{x}, @var{win_size}, @var{inc}, @var{num_coef}) 31## @deftypefnx {} {@var{y} =} stft (@var{x}, @var{win_size}, @var{inc}, @var{num_coef}, @var{win_type}) 32## @deftypefnx {} {[@var{y}, @var{c}] =} stft (@dots{}) 33## Compute the short-time Fourier transform of the vector @var{x} with 34## @var{num_coef} coefficients by applying a window of @var{win_size} data 35## points and an increment of @var{inc} points. 36## 37## Before computing the Fourier transform, one of the following windows 38## is applied: 39## 40## @table @asis 41## @item @qcode{"hanning"} 42## win_type = 1 43## 44## @item @qcode{"hamming"} 45## win_type = 2 46## 47## @item @qcode{"rectangle"} 48## win_type = 3 49## @end table 50## 51## The window names can be passed as strings or by the @var{win_type} number. 52## 53## The following defaults are used for unspecified arguments: 54## @var{win_size} = 80, @var{inc} = 24, @var{num_coef} = 64, and 55## @var{win_type} = 1. 56## 57## @code{@var{y} = stft (@var{x}, @dots{})} returns the absolute values of the 58## Fourier coefficients according to the @var{num_coef} positive frequencies. 59## 60## @code{[@var{y}, @var{c}] = stft (@var{x}, @dots{})} returns the entire 61## STFT-matrix @var{y} and a 3-element vector @var{c} containing the window 62## size, increment, and window type, which is needed by the @code{synthesis} 63## function. 64## @seealso{synthesis} 65## @end deftypefn 66 67function [y, c] = stft (x, win_size = 80, inc = 24, num_coef = 64, win_type = 1) 68 69 if (nargin < 1 || nargin > 5) 70 print_usage (); 71 endif 72 73 if (ischar (win_type)) 74 switch (tolower (win_type)) 75 case "hanning" win_type = 1; 76 case "hamming" win_type = 2; 77 case "rectangle" win_type = 3; 78 otherwise 79 error ("stft: unknown window type '%s'", win_type); 80 endswitch 81 endif 82 83 ## Check whether X is a vector. 84 if (! isvector (x)) 85 error ("stft: X must be a vector"); 86 endif 87 x = x(:); 88 89 ncoef = 2 * num_coef; 90 if (win_size > ncoef) 91 win_size = ncoef; 92 printf ("stft: window size adjusted to %f\n", win_size); 93 endif 94 num_win = fix ((rows (x) - win_size) / inc); 95 96 ## compute the window coefficients 97 switch (win_type) 98 case 1 win_coef = hanning (win_size); 99 case 2 win_coef = hamming (win_size); 100 case 3 win_coef = ones (win_size, 1); 101 endswitch 102 103 ## Create a matrix Z whose columns contain the windowed time-slices. 104 z = zeros (ncoef, num_win + 1); 105 start = 1; 106 for i = 0:num_win 107 z(1:win_size, i+1) = x(start:start+win_size-1) .* win_coef; 108 start += inc; 109 endfor 110 111 y = fft (z); 112 113 if (nargout == 1) 114 y = abs (y(1:num_coef, :)); 115 else 116 c = [win_size, inc, win_type]; 117 endif 118 119endfunction 120