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