Nsound  0.9.4
Public Member Functions | Protected Attributes | List of all members
Nsound::Spectrogram Class Reference

The result from an STFT. More...

#include <Nsound/Spectrogram.h>

Public Member Functions

 Spectrogram (const Buffer &x, const float64 &sample_rate, const float64 &time_window, const float64 &time_step, const WindowType &type)
 
 Spectrogram (const Spectrogram &copy)
 
 ~Spectrogram ()
 
Buffer getFrequencyAxis () const
 
AudioStream getMagnitude () const
 
Buffer getTimeAxis () const
 
Spectrogramoperator= (const Spectrogram &rhs)
 
void plot (const std::string &title="", const boolean &use_dB=true, const float64 &squash=0.5) const
 
Buffer computeMagnitude (const Buffer &x)
 

Protected Attributes

float64 sample_rate_
 
Bufferfrequency_axis_
 
Buffertime_axis_
 
AudioStreamreal_
 
AudioStreamimag_
 
Bufferfft_window_
 
uint32 nfft_
 
uint32 n_window_samples_
 
FFTransformfft_
 

Detailed Description

The result from an STFT.

Definition at line 47 of file Spectrogram.h.

Constructor & Destructor Documentation

Spectrogram::Spectrogram ( const Buffer x,
const float64 sample_rate,
const float64 time_window,
const float64 time_step,
const WindowType type 
)

Definition at line 44 of file Spectrogram.cc.

References Nsound::Generator::drawWindow(), Nsound::FFTransform::fft(), fft_, fft_window_, frequency_axis_, Nsound::Buffer::getLength(), imag_, n_window_samples_, nfft_, real_, Nsound::FFTransform::roundUp2(), sample_rate_, Nsound::Generator::silence(), sr, Nsound::Buffer::subbuffer(), and time_axis_.

50  :
51  sample_rate_(sample_rate),
52  frequency_axis_(NULL),
53  time_axis_(NULL),
54  real_(NULL),
55  imag_(NULL),
56  fft_window_(new Buffer()),
57  nfft_(0),
59  fft_(new FFTransform(sample_rate))
60 {
62 
63  if(sample_rate <= 0.0)
64  {
65  cerr << "Nsound::Spectrogram(): "
66  << "sample_rate <= 0.0 ("
67  << sample_rate
68  << "<= 0.0)"
69  << endl;
70 
71  // Use some default.
72  sr = 44100.0;
73  }
74 
75  float64 time_w = time_window;
76 
77  if(time_window <= 0.0)
78  {
79  cerr << "Nsound::Spectrogram(): "
80  << "time_window <= 0.0 ("
81  << time_window
82  << "<= 0.0)"
83  << endl;
84 
85  // Use some default.
86  time_w = 0.020;
87  }
88 
89  float64 time_s = time_step;
90 
91  if(time_step <= 0.0)
92  {
93  cerr << "Nsound::Spectrogram(): "
94  << "time_step <= 0.0 ("
95  << time_step
96  << "<= 0.0)"
97  << endl;
98 
99  // Use some default.
100  time_s = 0.020;
101  }
102 
103  n_window_samples_ = static_cast<int32>(time_w * sr + 0.5);
104  uint32 window_step = static_cast<int32>(time_s * sr + 0.5);
105 
106  // Calculate the fft size.
108 
109  Generator gen(1);
110 
111  *fft_window_ = gen.drawWindow(n_window_samples_, type);
112 
113  int32 n_samples = x.getLength();
114  int32 h_window_samples = n_window_samples_ / 2;
115 
116  int32 i = - h_window_samples;
117 
118  // Count how many windows we'll need.
119  uint32 k = 0;
120 
121  while(i < n_samples)
122  {
123  ++k;
124  i += window_step;
125  }
126 
127  // Allocate matricies.
128 
129  frequency_axis_ = new Buffer(1); // gets assigned to later.
130  time_axis_ = new Buffer(k);
131 
132  // Using AudioStreams for a matrix-like container where channels are rows
133  // and Buffer length is columns. Here I'm setting samplerate to 1 (doesn't
134  // really matter) and pre allocating the buffers to length 1, since they
135  // get assigned to later.
136  real_ = new AudioStream(1, k, 1);
137  imag_ = new AudioStream(1, k, 1);
138 
139  if(frequency_axis_ == NULL)
140  {
141  cerr << "Nsound::Spectrogram::Spectrogram(): "
142  << "failed to allocate memory for frequency_axis_"
143  << endl;
144 
145  return;
146  }
147 
148  if(time_axis_ == NULL)
149  {
150  cerr << "Nsound::Spectrogram::Spectrogram(): "
151  << "failed to allocate memory for time_axis_"
152  << endl;
153 
154  return;
155  }
156 
157  if(real_ == NULL)
158  {
159  cerr << "Nsound::Spectrogram::Spectrogram(): "
160  << "failed to allocate memory for real_"
161  << endl;
162 
163  return;
164  }
165 
166  if(imag_ == NULL)
167  {
168  cerr << "Nsound::Spectrogram::Spectrogram(): "
169  << "failed to allocate memory for imag_"
170  << endl;
171 
172  return;
173  }
174 
175  float64 time = 0.0;
176  boolean once = true;
177  k = 0;
178  i = - h_window_samples;
179  while(i < n_samples)
180  {
181  *time_axis_ << time;
182 
183  // Extract a sub signal.
184  int32 i0 = i;
185 
187 
188  // Range check
189  if(i0 < 0)
190  {
191  int32 n_left = i + n_window_samples_;
192  int32 n_zeros = n_window_samples_ - n_left;
193 
194  sub = gen.silence(n_zeros)
195  << (x.subbuffer(0, n_left) * gen.drawWindow(n_left, type));
196  }
197  else
198  {
199  sub = x.subbuffer(i0, n_window_samples_) * *fft_window_;
200  }
201 
202  // Pad with zeros if at the end.
203  if(sub.getLength() < n_window_samples_)
204  {
205  int32 n_left = sub.getLength();
206  int32 n_zeros = n_window_samples_ - n_left ;
207 
208  sub *= gen.drawWindow(n_left, type);
209 
210  sub << gen.silence(n_zeros);
211  }
212 
213  // Forward FFT
214  FFTChunkVector vec = fft_->fft(sub, nfft_, 0);
215 
216  (*real_)[k] = vec[0].getReal();
217  (*imag_)[k] = vec[0].getImaginary();
218  ++k;
219 
220  if(once)
221  {
222  once = false;
223  *frequency_axis_ = vec[0].getFrequencyAxis().subbuffer(1);
224  }
225 
226  i += window_step;
227  time += time_step;
228  }
229 }
Buffer subbuffer(uint32 start_index, uint32 n_samples=0) const
Slice the Buffer.
Definition: Buffer.cc:2073
unsigned int uint32
Definition: Nsound.h:153
Buffer * frequency_axis_
Definition: Spectrogram.h:88
double float64
Definition: Nsound.h:146
static int32 roundUp2(int32 raw)
Returns nearest power of 2 >= raw.
Definition: FFTransform.cc:274
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
uint32 n_window_samples_
Definition: Spectrogram.h:96
AudioStream * imag_
Definition: Spectrogram.h:92
AudioStream * real_
Definition: Spectrogram.h:91
A Class that performes the Fast Fouier Transfrom on a Buffer.
Definition: FFTransform.h:57
Buffer * fft_window_
Definition: Spectrogram.h:94
A Buffer for storing audio samples.
Definition: Buffer.h:60
FFTransform * fft_
Definition: Spectrogram.h:97
signed int int32
Definition: Nsound.h:142
Buffer fft(const Buffer &time_domain) const
Transforms the time_domain signal and calculates the FFT.
Definition: FFTransform.cc:50
std::vector< FFTChunk > FFTChunkVector
Definition: FFTChunk.h:119
A class the provides draw utilities and a wavetable oscillator.
Definition: Generator.h:50
float64 sr
Definition: example3.cc:24
Spectrogram::Spectrogram ( const Spectrogram copy)

Definition at line 232 of file Spectrogram.cc.

233  :
235  time_axis_(new Buffer(*copy.time_axis_)),
236  real_(new AudioStream(*copy.real_)),
237  imag_(new AudioStream(*copy.imag_)),
238  fft_window_(new Buffer(*copy.fft_window_)),
239  nfft_(copy.nfft_),
241  fft_(new FFTransform(*copy.fft_))
242 {
243 }
Buffer * frequency_axis_
Definition: Spectrogram.h:88
uint32 n_window_samples_
Definition: Spectrogram.h:96
AudioStream * imag_
Definition: Spectrogram.h:92
AudioStream * real_
Definition: Spectrogram.h:91
A Class that performes the Fast Fouier Transfrom on a Buffer.
Definition: FFTransform.h:57
Buffer * fft_window_
Definition: Spectrogram.h:94
A Buffer for storing audio samples.
Definition: Buffer.h:60
FFTransform * fft_
Definition: Spectrogram.h:97
Spectrogram::~Spectrogram ( )

Definition at line 246 of file Spectrogram.cc.

References fft_, fft_window_, frequency_axis_, imag_, real_, and time_axis_.

247 {
248  delete frequency_axis_;
249  delete time_axis_;
250  delete real_;
251  delete imag_;
252  delete fft_window_;
253  delete fft_;
254 };
Buffer * frequency_axis_
Definition: Spectrogram.h:88
AudioStream * imag_
Definition: Spectrogram.h:92
AudioStream * real_
Definition: Spectrogram.h:91
Buffer * fft_window_
Definition: Spectrogram.h:94
FFTransform * fft_
Definition: Spectrogram.h:97

Member Function Documentation

Buffer Spectrogram::getFrequencyAxis ( ) const

Definition at line 258 of file Spectrogram.cc.

References frequency_axis_.

Referenced by my_main().

259 {
260  return Buffer(*frequency_axis_);
261 }
Buffer * frequency_axis_
Definition: Spectrogram.h:88
A Buffer for storing audio samples.
Definition: Buffer.h:60
AudioStream Spectrogram::getMagnitude ( ) const

Definition at line 265 of file Spectrogram.cc.

References imag_, and real_.

Referenced by my_main(), and plot().

266 {
267  return ((*real_^2.0) + (*imag_^2.0))^0.5;
268 }
AudioStream * imag_
Definition: Spectrogram.h:92
AudioStream * real_
Definition: Spectrogram.h:91
Buffer Spectrogram::getTimeAxis ( ) const

Definition at line 272 of file Spectrogram.cc.

References time_axis_.

Referenced by my_main().

273 {
274  return Buffer(*time_axis_);
275 }
A Buffer for storing audio samples.
Definition: Buffer.h:60
Spectrogram & Spectrogram::operator= ( const Spectrogram rhs)

Definition at line 279 of file Spectrogram.cc.

References fft_, fft_window_, frequency_axis_, imag_, n_window_samples_, nfft_, real_, sample_rate_, and time_axis_.

280 {
281  if(this == &rhs)
282  {
283  return *this;
284  }
285 
288  *time_axis_ = *rhs.time_axis_;
289  *real_ = *rhs.real_;
290  *imag_ = *rhs.imag_;
291  *fft_window_ = *rhs.fft_window_;
292  nfft_ = rhs.nfft_;
294  *fft_ = *rhs.fft_;
295 
296  return *this;
297 }
Buffer * frequency_axis_
Definition: Spectrogram.h:88
uint32 n_window_samples_
Definition: Spectrogram.h:96
AudioStream * imag_
Definition: Spectrogram.h:92
AudioStream * real_
Definition: Spectrogram.h:91
Buffer * fft_window_
Definition: Spectrogram.h:94
FFTransform * fft_
Definition: Spectrogram.h:97
void Spectrogram::plot ( const std::string &  title = "",
const boolean use_dB = true,
const float64 squash = 0.5 
) const

Definition at line 301 of file Spectrogram.cc.

References Nsound::AudioStream::dB(), Nsound::Plotter::figure(), frequency_axis_, getMagnitude(), Nsound::Plotter::imagesc(), time_axis_, Nsound::Plotter::title(), Nsound::AudioStream::transpose(), Nsound::Plotter::xlabel(), and Nsound::Plotter::ylabel().

Referenced by my_main().

305 {
306  AudioStream mag = getMagnitude();
307 
308  // Transpose so x is the time axis.
309  mag.transpose();
310 
311  if(use_dB)
312  {
313  mag += 1.0;
314  mag.dB();
315  }
316  else if(squash > 0.0)
317  {
318  mag ^= squash;
319  }
320  else
321  {
322  cerr << "Nsound::Spectrogram::plot(): "
323  << "use_dB is false and squash <= 0.0 ("
324  << squash
325  << " <= 0.0)"
326  << endl;
327 
328  return;
329  }
330 
331  Plotter pylab;
332 
333  pylab.figure();
334  pylab.imagesc(*time_axis_, *frequency_axis_, mag);
335  pylab.xlabel("Time (sec)");
336  pylab.ylabel("Frequency (Hz)");
337  pylab.title(title);
338 }
void xlabel(const std::string &label, const std::string &kwargs="")
Add a label x axis.
Definition: Plotter.cc:1154
Buffer * frequency_axis_
Definition: Spectrogram.h:88
void figure(const std::string &kwargs="") const
Creates a new figure window to plot in.
Definition: Plotter.cc:455
void title(const std::string &title, const std::string &kwargs="")
Add a title to the plot at the top and centered.
Definition: Plotter.cc:1127
void imagesc(const AudioStream &Z, const std::string &kwargs="")
Plots the AudioStream like a 2D matrix.
Definition: Plotter.cc:593
void transpose()
Treating the AudioStream as a matrix, this peforms a matrix transpose.
Definition: AudioStream.cc:875
void ylabel(const std::string &label, const std::string &kwargs="")
Add a label y axis.
Definition: Plotter.cc:1180
void dB()
Modifies the AudioStream so each sample is converted to dB, 20 * log10(sample).
Definition: AudioStream.cc:161
AudioStream getMagnitude() const
Definition: Spectrogram.cc:265
Buffer Spectrogram::computeMagnitude ( const Buffer x)

Definition at line 342 of file Spectrogram.cc.

References Nsound::FFTransform::fft(), fft_, fft_window_, Nsound::Buffer::getLength(), n_window_samples_, nfft_, Nsound::Buffer::subbuffer(), and Nsound::Buffer::zeros().

343 {
344  Buffer signal(n_window_samples_);
345 
346  uint32 n_samples = x.getLength();
347 
348  // grab last n samples
349  if(n_samples >= n_window_samples_)
350  {
351  uint32 index = n_samples - n_window_samples_;
352  signal = x.subbuffer(index, n_window_samples_);
353  }
354 
355  // pad with zeros
356  else
357  {
358  uint32 n_zeros = n_window_samples_ - n_samples;
359 
360  signal << x << Buffer::zeros(n_zeros);
361  }
362 
363  // Apply window
364  signal *= *fft_window_;
365 
366  // Forward FFT
367  FFTChunkVector vec = fft_->fft(signal, nfft_, 0);
368 
369  return vec[0].getMagnitude();
370 }
Buffer subbuffer(uint32 start_index, uint32 n_samples=0) const
Slice the Buffer.
Definition: Buffer.cc:2073
unsigned int uint32
Definition: Nsound.h:153
static Buffer zeros(const uint32 n_samples)
Returns a Buffer full of zeros of length n_samples.
Definition: Buffer.cc:2265
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
uint32 n_window_samples_
Definition: Spectrogram.h:96
Buffer * fft_window_
Definition: Spectrogram.h:94
A Buffer for storing audio samples.
Definition: Buffer.h:60
FFTransform * fft_
Definition: Spectrogram.h:97
Buffer fft(const Buffer &time_domain) const
Transforms the time_domain signal and calculates the FFT.
Definition: FFTransform.cc:50
std::vector< FFTChunk > FFTChunkVector
Definition: FFTChunk.h:119

Member Data Documentation

float64 Nsound::Spectrogram::sample_rate_
protected

Definition at line 86 of file Spectrogram.h.

Referenced by operator=(), and Spectrogram().

Buffer* Nsound::Spectrogram::frequency_axis_
protected

Definition at line 88 of file Spectrogram.h.

Referenced by getFrequencyAxis(), operator=(), plot(), Spectrogram(), and ~Spectrogram().

Buffer* Nsound::Spectrogram::time_axis_
protected

Definition at line 89 of file Spectrogram.h.

Referenced by getTimeAxis(), operator=(), plot(), Spectrogram(), and ~Spectrogram().

AudioStream* Nsound::Spectrogram::real_
protected

Definition at line 91 of file Spectrogram.h.

Referenced by getMagnitude(), operator=(), Spectrogram(), and ~Spectrogram().

AudioStream* Nsound::Spectrogram::imag_
protected

Definition at line 92 of file Spectrogram.h.

Referenced by getMagnitude(), operator=(), Spectrogram(), and ~Spectrogram().

Buffer* Nsound::Spectrogram::fft_window_
protected

Definition at line 94 of file Spectrogram.h.

Referenced by computeMagnitude(), operator=(), Spectrogram(), and ~Spectrogram().

uint32 Nsound::Spectrogram::nfft_
protected

Definition at line 95 of file Spectrogram.h.

Referenced by computeMagnitude(), operator=(), and Spectrogram().

uint32 Nsound::Spectrogram::n_window_samples_
protected

Definition at line 96 of file Spectrogram.h.

Referenced by computeMagnitude(), operator=(), and Spectrogram().

FFTransform* Nsound::Spectrogram::fft_
protected

Definition at line 97 of file Spectrogram.h.

Referenced by computeMagnitude(), operator=(), Spectrogram(), and ~Spectrogram().


The documentation for this class was generated from the following files: