get_spectrogram.m 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. function [spec_d, spec_t, spec_f] = get_spectrogram( x, t, win_size, t_resolution )
  2. % Usage: [spec_d, spec_t, spec_f] = get_spectrogram( x, t, win_size, t_resolution )
  3. %
  4. % Calculating amplitude spectrogram from signal x and time-vector t.
  5. %
  6. % -- input form --
  7. % x: Raw EEG signal (1-D vector)
  8. % y: Time vector (in millisecond resolution)
  9. % win_size: Size of sliding moving window (default: 2^10)
  10. % t_resolution: Jump size of sliding moving window (unit: sec, default: 100 msec)
  11. %
  12. % 2019-09-10
  13. %
  14. %% Default condition
  15. if nargin < 5
  16. t_resolution = .1;
  17. end; if nargin < 4
  18. win_size = 2^10;
  19. end
  20. srate = round( 1/nanmean(diff(t)) );
  21. t_fft = [t(1)+(((win_size*.5)+1)/srate), t(end)-(((win_size*.5)+1)/srate)];
  22. t_vec = linspace( t_fft(1), t_fft(end), (diff(t_fft)/t_resolution) +1);
  23. %% Sliding window index bank
  24. idx_collection = single([]);
  25. for tIdx = [1, length(t_vec)]
  26. idx_collection(tIdx,:) = ...
  27. [max(find( t<(t_vec(tIdx)))) - win_size*.5,...
  28. (max(find( t<(t_vec(tIdx)))) + win_size*.5-1) ];
  29. end
  30. idx_collection(:,1) = linspace( idx_collection(1,1), idx_collection(end,1), length(t_vec) );
  31. idx_collection(:,2) = linspace( idx_collection(1,2), idx_collection(end,2), length(t_vec) );
  32. idx_collection = round(idx_collection);
  33. short = find( ~[diff(idx_collection')' == (win_size-1)]);
  34. idx_collection(short,2) = idx_collection(short,2)+1;
  35. try hann = hanning( idx_collection(1,2)-idx_collection(1,1)+1 )';
  36. catch hann = ones([1, win_size]); end
  37. %%
  38. spec_d = [];
  39. spec_t = [];
  40. for tIdx = 1:length(t_vec)
  41. % (1) Indexing
  42. % idx = max(find( t<(t_vec(tIdx)))) - win_size*.5 :...
  43. % max(find( t<(t_vec(tIdx)))) + win_size*.5 -1 ;
  44. % actual_t = t(idx);
  45. % if tIdx==1, han=hanning(length(idx))'; end
  46. idx_list = idx_collection(tIdx,1):idx_collection(tIdx,2);
  47. d = hann .* x(idx_list(1:length(hann))); % to prevent 1-2 point mismatch
  48. [fft_d,spec_f]= fft_half(d, srate);
  49. spec_d( size(spec_d,1)+1 , :) = fft_d;
  50. spec_t( length(spec_t)+1 ) = mean(t(idx_list(1:length(hann))));
  51. end
  52. spec_d = abs(spec_d);
  53. end
  54. %% Subfunctions
  55. function [s,f]=fft_half(x,Fs)
  56. N=(length(x)); k=0:N-1; T=N/Fs; f=k/T;
  57. cutOff = ceil(N/2); f = f(1:cutOff);
  58. nTrials = size(x, 1);
  59. if nTrials == 1
  60. s = fft(x)/N*2; % normalize the data
  61. s = s(1:cutOff); % Single trial FFT
  62. else
  63. s = [];
  64. for trialIdx = 1:nTrials
  65. s_temp = fft(x(trialIdx,:))/N*2;
  66. s_temp = s_temp(1:cutOff); % Single trial FFT
  67. s = [s; s_temp];
  68. end
  69. end
  70. end
  71. function [idx,short] = hb_findIdx( range, fullData )
  72. short=false;
  73. idx = max(find( fullData < range(1)))+1:max(find(fullData<range(2)));
  74. if length(idx)==0, idx = 1:max(find(fullData<range(2))); end
  75. if range(2) > fullData(end), short=1; end
  76. end