Edinburgh Speech Tools  2.1-release
spectrogram.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1994,1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor */
34 /* Date : December 96 */
35 /*-----------------------------------------------------------------------*/
36 /* Spectrogram Generation */
37 /* */
38 /*=======================================================================*/
39 #include <cmath>
40 #include <climits>
41 #include <cfloat> /* needed for FLT_MAX */
42 #include "EST_error.h"
43 #include "EST_Track.h"
44 #include "EST_Wave.h"
45 #include "sigpr/EST_Window.h"
46 #include "EST_Option.h"
47 #include "sigpr/EST_fft.h"
48 #include "sigpr/EST_spectrogram.h"
49 #include "sigpr/EST_misc_sigpr.h"
50 
51 using namespace std;
52 
54 {
55  EST_Wave psig;
56 
57  EST_pre_emphasis(sig, psig, op.F("preemph"));
58 
59  // calculate raw spectrogram
60  raw_spectrogram(sp, psig, op.F("frame_length"), op.F("frame_shift"),
61  op.I("frame_order"), op.present("slow_fft"));
62 
63  if (op.present("raw"))
64  {
65  cout << "no scaling\n";
66  return;
67  }
68  // coerce the values so as to emphasis important features
69 
70  if (op.present("sp_range") || op.present("sp_wcut") || op.present("sp_bcut"))
71  {
72  if (!op.present("sp_range"))
73  op.set("sp_range", 1.0);
74 
75  if (!op.present("sp_wcut"))
76  op.set("sp_wcut", 1.0);
77 
78  if (!op.present("sp_bcut"))
79  op.set("sp_bcut", 0.0);
80  scale_spectrogram(sp, op.F("sp_range"),op.F("sp_wcut"),op.F("sp_bcut"));
81  }
82 }
83 
84 void scale_spectrogram(EST_Track &sp, float range, float wcut, float bcut)
85 {
86  float max, min, scale, v;
87  int i, j;
88 
89  max = -FLT_MIN;
90  min = FLT_MAX;
91 
92  // find min and max values
93  for (i = 0; i < sp.num_frames(); ++i)
94  for (j = 0; j < sp.num_channels(); ++j)
95  {
96  float vv = sp.a_no_check(i, j);
97 
98  if (vv > max)
99  max = vv;
100  if (vv < min)
101  min = vv;
102  }
103  scale = (max - min);
104 
105  // for every value:
106  // 1. Effectively scale in range 0 to 1
107  // 2. Impose white and black cut offs
108  // 3. Rescale to 0 and 1
109  // 4. scale to fit in "range"
110  // this can obviously be done more efficiently
111 
112  float mag = (float)range / (float)(bcut - wcut);
113  for (i = 0; i < sp.num_frames(); ++i)
114  for (j = 0; j < sp.num_channels(); ++j)
115  {
116  v = (((sp.a_no_check(i, j) - min) / scale) - wcut) * mag;
117  if (v > range) v = range;
118  if (v < 0.0) v = 0.0;
119  sp.a_no_check(i, j) = v;
120  }
121 }
122 
124  float length,
125  float shift,
126  int order,
127  bool slow)
128 {
129  int frame_length = (int) (length * (float) sig.sample_rate() +0.5);
130  int frame_shift = (int) (shift * (float) sig.sample_rate() +0.5);
131 
132  EST_WindowFunc *make_window = EST_Window::creator("hamming");
133 
134  // sanity check, we can't analyse more signal than order allows.
135  if (frame_length > order)
136  {
137  EST_warning("frame_length reduced to %f (%d samples) to fit order\n",
138  (float)order/(float) sig.sample_rate(), order);
139  frame_length=order;
140  }
141 
142  // enough frames to cover the entire signal
143  int num_frames= (int)ceil(sig.num_samples()/(float)frame_shift);
144 
145  // spectrogram gets order/2 powers, the moduli of order/2
146  // complex numbers
147  sp.resize(num_frames, order/2, FALSE);
148 
149  EST_FVector real(order);
150  EST_FVector imag(order);
151 
152  // create the window shape
153  EST_TBuffer<float> window_vals(frame_length);
154  make_window(frame_length, window_vals,-1);
155 
156  for (int k = 0 ; k < num_frames ; k++)
157  {
158  int pos = frame_shift * k;
159  int window_start = pos - frame_length/2;
160 
161  real.empty();
162 
163  // imag not used in old FFT code
164  if (slow)
165  imag.empty();
166 
168  window_vals,
169  window_start,
170  frame_length,
171  real, FALSE);
172 
173  int state = slow?power_spectrum_slow(real, imag):power_spectrum(real, imag);
174  if (state != 0)
175  {
176  fprintf(stderr, "FFT Failed for frame %d\n", k);
177  for (int i = 0; i < order /2; ++i)
178  sp.a_no_check(k, i) = 0;
179  }
180  else
181  sp.copy_frame_in(k, real);
182  }
183  sp.fill_time(shift);
184 }
185 
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
Definition: EST_Wave.h:64
static Func * creator(const char *name, bool report_error=false)
Return the creation function for the given window type.
Definition: EST_Window.cc:218
static void window_signal(const EST_Wave &sig, EST_WindowFunc *make_window, int start, int size, EST_TBuffer< float > &frame)
Definition: EST_Window.cc:279
void raw_spectrogram(EST_Track &sp, EST_Wave &sig, float length, float shift, int order, bool slow)
Compute the power-spectrogram.
Definition: spectrogram.cc:123
A vector class for floating point numbers. EST_FVector x should be used instead of float *x wherever ...
Definition: EST_FMatrix.h:119
int num_channels() const
return number of channels in track
Definition: EST_Track.h:657
ssize_t num_samples() const
return the number of samples in the waveform
Definition: EST_Wave.h:143
void set(const EST_String &name, int ival)
Definition: EST_Features.h:186
void resize(ssize_t num_frames, int num_channels, bool preserve=1)
Definition: EST_Track.cc:214
float & a_no_check(ssize_t i, int c=0)
Definition: EST_Track.h:420
float max(float a, float b)
Definition: EST_cluster.cc:143
#define FLT_MAX
Definition: EST_math.h:134
float min(float a, float b)
Definition: EST_cluster.cc:138
int power_spectrum_slow(EST_FVector &real, EST_FVector &imag)
Power spectrum using the slowFFT function.
Definition: fft.cc:209
#define FALSE
Definition: EST_bool.h:119
int present(const EST_String &name) const
void scale_spectrogram(EST_Track &sp, float range, float wcut, float bcut)
Manipulate the spectrogram to.
Definition: spectrogram.cc:84
ssize_t num_frames() const
return number of frames in track
Definition: EST_Track.h:651
void EST_WindowFunc(int size, EST_TBuffer< float > &r_window, int window_centre)
Function which creates a window.
Definition: EST_Window.h:52
void EST_pre_emphasis(EST_Wave &signal, EST_Wave &psignal, float a)
Pre process to emphasise higher frequencies.
Definition: misc.cc:55
getString int
Definition: EST_item_aux.cc:50
void copy_frame_in(int n, const float *buf, int offset=0, int num=EST_ALL)
Definition: EST_Track.h:346
int sample_rate() const
return the sampling rate (frequency)
Definition: EST_Wave.h:147
void make_spectrogram(EST_Wave &sig, EST_Track &sp, EST_Features &op)
Definition: spectrogram.cc:53
#define EST_warning
Definition: EST_error.h:106
int I(const EST_String &path) const
Definition: EST_Features.h:147
Extending buffer class.
Definition: EST_TBuffer.h:86
void empty()
Fill vector with default value.
Definition: EST_TVector.h:294
void fill_time(float t, int start=1)
Definition: EST_Track.cc:789
float F(const EST_String &path) const
Definition: EST_Features.h:136
int power_spectrum(EST_FVector &real, EST_FVector &imag)
Power spectrum using the fastFFT function.
Definition: fft.cc:222