SigPack - the C++ signal processing library
 
Loading...
Searching...
No Matches
spectrum.h
Go to the documentation of this file.
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4#ifndef SP_SPECTRUM_H
5#define SP_SPECTRUM_H
6
7namespace sp
8{
13
23template <class T1> arma::cx_vec spectrum( const arma::Col<T1>& x, const arma::vec& W )
24{
25 arma::cx_vec Pxx( x.size() );
26 double wc = sum( W ); // Window correction factor
27 Pxx = fft( x % W ) / wc; // FFT calc
28 return Pxx;
29}
30
37template <class T1> arma::vec psd( const arma::Col<T1>& x, const arma::vec& W )
38{
39 arma::cx_vec X( x.size() );
40 arma::vec Pxx( x.size() );
41 X = spectrum( x, W ); // FFT calc
42 Pxx = real( X % conj( X ) ); // Calc power spectra
43 return Pxx;
44}
45
51template <class T1> arma::vec psd( const arma::Col<T1>& x )
52{
53 arma::vec W;
54 W = hamming( x.size() );
55 return psd( x, W );
56}
57
67template <class T1> arma::cx_mat specgram_cx( const arma::Col<T1>& x, const arma::uword Nfft = 512, const arma::uword Noverl = 256 )
68{
69 arma::cx_mat Pw;
70
71 // Def params
72 arma::uword N = x.size();
73 arma::uword D = Nfft - Noverl;
74 arma::uword m = 0;
75 if( N > Nfft )
76 {
77 arma::Col<T1> xk( Nfft );
78 arma::vec W( Nfft );
79
80 W = hamming( Nfft );
81 arma::uword U = static_cast<arma::uword>( floor( ( N - Noverl ) / double( D ) ) );
82 Pw.set_size( Nfft, U );
83 Pw.zeros();
84
85 // Avg loop
86 for( arma::uword k = 0; k < N - Nfft; k += D )
87 {
88 xk = x.rows( k, k + Nfft - 1 ); // Pick out chunk
89 Pw.col( m++ ) = spectrum( xk, W ); // Calculate spectrum
90 }
91 }
92 else
93 {
94 arma::vec W( N );
95 W = hamming( N );
96 Pw.set_size( N, 1 );
97 Pw = spectrum( x, W );
98 }
99 return Pw;
100}
101
111template <class T1> arma::mat specgram( const arma::Col<T1>& x, const arma::uword Nfft = 512, const arma::uword Noverl = 256 )
112{
113 arma::cx_mat Pw;
114 arma::mat Sg;
115 Pw = specgram_cx( x, Nfft, Noverl );
116 Sg = real( Pw % conj( Pw ) ); // Calculate power spectrum
117 return Sg;
118}
119
129template <class T1> arma::mat specgram_ph( const arma::Col<T1>& x, const arma::uword Nfft = 512, const arma::uword Noverl = 256 )
130{
131 arma::cx_mat Pw;
132 arma::mat Sg;
133 Pw = specgram_cx( x, Nfft, Noverl );
134 Sg = angle( Pw ); // Calculate phase spectrum
135 return Sg;
136}
137
148template <class T1> arma::vec pwelch_ph( const arma::Col<T1>& x, const arma::uword Nfft = 512, const arma::uword Noverl = 256 )
149{
150 arma::mat Ph;
151 Ph = specgram_ph( x, Nfft, Noverl );
152 return arma::mean( Ph, 1 );
153}
154
166template <class T1> arma::vec pwelch( const arma::Col<T1>& x, const arma::uword Nfft = 512, const arma::uword Noverl = 256 )
167{
168 arma::mat Pxx;
169 Pxx = specgram( x, Nfft, Noverl );
170 return arma::mean( Pxx, 1 );
171}
172
182template <class T1> std::complex<double> goertzel( const arma::Col<T1>& x, const double f )
183{
184 // Constants
185 arma::uword N = x.size();
186 double Q = f / N;
187 double A = PI_2 * Q;
188 double B = 2 * cos( A );
189 std::complex<double> C( cos( A ), -sin( A ) );
190 // States
191 T1 s0 = 0;
192 T1 s1 = 0;
193 T1 s2 = 0;
194
195 // Accumulate data
196 for( arma::uword n = 0; n < N; n++ )
197 {
198 // Update filter
199 s0 = x( n ) + B * s1 - s2;
200
201 // Shift buffer
202 s2 = s1;
203 s1 = s0;
204 }
205 // Update output state
206 s0 = B * s1 - s2;
207
208 // Return the complex DFT output
209 return s0 - s1 * C;
210}
211
221template <class T1> arma::cx_vec goertzel( const arma::Col<T1>& x, const arma::vec f )
222{
223 arma::uword N = f.size();
224 arma::cx_vec P( N );
225 for( arma::uword n = 0; n < N; n++ )
226 {
227 P( n ) = goertzel( x, f( n ) );
228 }
229
230 // Return the complex DFT output vector
231 return P;
232}
233
235} // namespace sp
236#endif
double angle(const std::complex< T > &x)
Calculates angle in radians for complex input.
Definition base.h:67
const double PI_2
Definition base.h:15
arma::vec pwelch_ph(const arma::Col< T1 > &x, const arma::uword Nfft=512, const arma::uword Noverl=256)
Phase spectrum calculation using Welch's method.
Definition spectrum.h:148
arma::vec psd(const arma::Col< T1 > &x, const arma::vec &W)
Power spectrum density calculation using windowed data.
Definition spectrum.h:37
std::complex< double > goertzel(const arma::Col< T1 > &x, const double f)
DFT calculation of a single frequency using Goertzel's method.
Definition spectrum.h:182
arma::vec pwelch(const arma::Col< T1 > &x, const arma::uword Nfft=512, const arma::uword Noverl=256)
Power spectrum calculation using Welch's method.
Definition spectrum.h:166
arma::cx_mat specgram_cx(const arma::Col< T1 > &x, const arma::uword Nfft=512, const arma::uword Noverl=256)
Spectrogram calculation using Hamming windowed data.
Definition spectrum.h:67
arma::mat specgram_ph(const arma::Col< T1 > &x, const arma::uword Nfft=512, const arma::uword Noverl=256)
Phase spectrogram calculation.
Definition spectrum.h:129
arma::cx_vec spectrum(const arma::Col< T1 > &x, const arma::vec &W)
Windowed spectrum calculation.
Definition spectrum.h:23
arma::mat specgram(const arma::Col< T1 > &x, const arma::uword Nfft=512, const arma::uword Noverl=256)
Power spectrogram calculation.
Definition spectrum.h:111
arma_inline arma::vec hamming(const arma::uword N)
Hamming window.
Definition window.h:43
Definition base.h:8