Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

78 строки
1.5KB

  1. package fftutil
  2. import "math"
  3. func Hann(n int) []float64 {
  4. w := make([]float64, n)
  5. if n <= 1 {
  6. if n == 1 {
  7. w[0] = 1
  8. }
  9. return w
  10. }
  11. for i := 0; i < n; i++ {
  12. w[i] = 0.5 * (1 - math.Cos(2*math.Pi*float64(i)/float64(n-1)))
  13. }
  14. return w
  15. }
  16. func Spectrum(iq []complex64, window []float64) []float64 {
  17. plan := NewCmplxPlan(len(iq))
  18. return SpectrumWithPlan(iq, window, plan)
  19. }
  20. func SpectrumWithPlan(iq []complex64, window []float64, plan *CmplxPlan) []float64 {
  21. n := len(iq)
  22. if n == 0 {
  23. return nil
  24. }
  25. in := make([]complex128, n)
  26. for i := 0; i < n; i++ {
  27. v := iq[i]
  28. w := 1.0
  29. if len(window) == n {
  30. w = window[i]
  31. }
  32. in[i] = complex(float64(real(v))*w, float64(imag(v))*w)
  33. }
  34. out := make([]complex128, n)
  35. if plan != nil && plan.N() == n {
  36. plan.FFT(out, in)
  37. } else {
  38. NewCmplxPlan(n).FFT(out, in)
  39. }
  40. power := make([]float64, n)
  41. eps := 1e-12
  42. invN := 1.0 / float64(n)
  43. for i := 0; i < n; i++ {
  44. idx := (i + n/2) % n
  45. mag := cmplxAbs(out[idx]) * invN
  46. p := 20 * math.Log10(mag+eps)
  47. power[i] = p
  48. }
  49. return power
  50. }
  51. func SpectrumFromFFT(out []complex64) []float64 {
  52. n := len(out)
  53. if n == 0 {
  54. return nil
  55. }
  56. power := make([]float64, n)
  57. eps := 1e-12
  58. invN := 1.0 / float64(n)
  59. for i := 0; i < n; i++ {
  60. idx := (i + n/2) % n
  61. v := out[idx]
  62. mag := math.Hypot(float64(real(v)), float64(imag(v))) * invN
  63. p := 20 * math.Log10(mag+eps)
  64. power[i] = p
  65. }
  66. return power
  67. }
  68. func cmplxAbs(v complex128) float64 {
  69. return math.Hypot(real(v), imag(v))
  70. }