|
1 |
| -function varargout = spectrum_from_signal(signal,conf) |
| 1 | +function varargout = spectrum_from_signal(signal,dim,conf) |
2 | 2 | %SPECTRUM_FROM_SIGNAL single-sided amplitude and phase spectra of signal
|
3 | 3 | %
|
4 |
| -% Usage: [amplitude,phase,f] = spectrum_from_signal(sig,conf) |
| 4 | +% Usage: [amplitude,phase,f] = spectrum_from_signal(sig,[dim],conf) |
5 | 5 | %
|
6 | 6 | % Input parameters:
|
7 | 7 | % signal - one channel audio (time) signal
|
| 8 | +% dim - dimension along which the fft is performed |
8 | 9 | % conf - configuration struct (see SFS_config)
|
9 | 10 | %
|
10 | 11 | % Output parameters:
|
|
52 | 53 |
|
53 | 54 | %% ===== Check input arguments ===========================================
|
54 | 55 | nargmin = 2;
|
55 |
| -nargmax = 2; |
| 56 | +nargmax = 3; |
56 | 57 | narginchk(nargmin,nargmax);
|
57 |
| -signal = column_vector(signal); |
| 58 | +if nargin == nargmin |
| 59 | + conf = dim; |
| 60 | + dim = find(size(signal)~=1, 1); % find first non-singleton dimension |
| 61 | +else |
| 62 | + isargpositivescalar(dim); |
| 63 | +end |
58 | 64 | isargstruct(conf);
|
59 | 65 |
|
| 66 | +Ndims = ndims(signal); |
| 67 | +dim = min(dim,Ndims); |
| 68 | +signal = permute(signal, [dim:Ndims, 1:dim-1]); % move dim to first dimension |
| 69 | +s = size(signal); |
| 70 | +Nx = s(1); |
| 71 | +signal = reshape(signal, Nx, []); % squeeze all other dimensions |
60 | 72 |
|
61 | 73 | %% ===== Configuration ===================================================
|
62 | 74 | fs = conf.fs;
|
|
65 | 77 |
|
66 | 78 | %% ===== Calcualate spectrum =============================================
|
67 | 79 | % Generate fast fourier transformation (=> complex output)
|
68 |
| -compspec = fft(signal); |
| 80 | +compspec = fft(signal,[],1); |
69 | 81 |
|
70 | 82 | % Length of the signal => number of points of fft
|
71 | 83 | bins = length(signal);
|
|
75 | 87 | f = fs/bins * (0:(bins-1)/2)';
|
76 | 88 | % Get amplitude and phase spectra and use only the first half of the
|
77 | 89 | %>spectrum [0, fs/2[
|
78 |
| - amplitude = abs(compspec(1:length(f))); |
79 |
| - phase = angle(compspec(1:length(f))); |
| 90 | + amplitude = abs(compspec(1:length(f),:)); |
| 91 | + phase = angle(compspec(1:length(f),:)); |
80 | 92 | % Scale the amplitude (factor two for mirrored frequencies
|
81 | 93 | %>divide by number of bins)
|
82 |
| - amplitude = [amplitude(1); 2*amplitude(2:end)] / bins; |
| 94 | + amplitude = [amplitude(1,:); 2*amplitude(2:end,:)] / bins; |
83 | 95 |
|
84 | 96 | else % For even signal length
|
85 | 97 | % Calculate corresponding frequency axis
|
86 | 98 | f = fs/bins * (0:bins / 2)';
|
87 | 99 | % Get amplitude and phase spectra and use only the first half of the
|
88 | 100 | %>spectrum [0, fs/2]
|
89 |
| - amplitude = abs(compspec(1:length(f))); |
90 |
| - phase = angle(compspec(1:length(f))); |
| 101 | + amplitude = abs(compspec(1:length(f),:)); |
| 102 | + phase = angle(compspec(1:length(f),:)); |
91 | 103 | % Scale the amplitude (factor two for mirrored frequencies
|
92 | 104 | %>divide by number of bins)
|
93 |
| - amplitude = [amplitude(1); 2*amplitude(2:end-1); amplitude(end)] / bins; |
| 105 | + amplitude = [amplitude(1,:); 2*amplitude(2:end-1,:); amplitude(end,:)] / bins; |
94 | 106 | end
|
95 | 107 |
|
96 |
| -% Return values |
97 |
| -if nargout>0, varargout{1}=amplitude; end |
98 |
| -if nargout>1, varargout{2}=phase; end |
99 |
| -if nargout>2, varargout{3}=f; end |
100 |
| - |
101 |
| - |
102 | 108 | %% ===== Plotting ========================================================
|
103 | 109 | if nargout==0 || useplot
|
104 | 110 | figure; title('Spectrum');
|
105 | 111 | subplot(2,1,1)
|
106 | 112 | semilogx(f,20 * log10(abs(amplitude))); xlim([1, fs/2]);
|
107 | 113 | grid on; xlabel('frequency / Hz'); ylabel('amplitude / dB')
|
108 | 114 | subplot(2,1,2)
|
109 |
| - semilogx(f,unwrap(phase)); xlim([1, fs/2]); |
| 115 | + semilogx(f,unwrap(phase,[],1)); xlim([1, fs/2]); |
110 | 116 | grid on; xlabel('frequency / Hz'); ylabel('phase / rad')
|
111 | 117 | end
|
| 118 | + |
| 119 | +%% ===== Output ========================================================== |
| 120 | +% Return values |
| 121 | +if nargout>0 |
| 122 | + % undo reshape and permute |
| 123 | + amplitude = reshape(amplitude, [length(f), s(2:end)]); |
| 124 | + amplitude = permute(amplitude, [Ndims-dim+2:Ndims, 1:Ndims-dim+1]); |
| 125 | + varargout{1}=amplitude; |
| 126 | +end |
| 127 | +if nargout>1 |
| 128 | + % undo reshape and permute |
| 129 | + phase = reshape(phase, [length(f), s(2:end)]); |
| 130 | + phase = permute(phase, [Ndims-dim+2:Ndims, 1:Ndims-dim+1]); |
| 131 | + varargout{2}=phase; |
| 132 | +end |
| 133 | +if nargout>2, varargout{3}=f; end |
0 commit comments