Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

93 рядки
1.9KB

  1. package main
  2. import (
  3. "sort"
  4. "strconv"
  5. "time"
  6. "sdr-visual-suite/internal/config"
  7. "sdr-visual-suite/internal/dsp"
  8. )
  9. func mustParseDuration(raw string, fallback time.Duration) time.Duration {
  10. if raw == "" {
  11. return fallback
  12. }
  13. if d, err := time.ParseDuration(raw); err == nil {
  14. return d
  15. }
  16. return fallback
  17. }
  18. func buildDecoderMap(cfg config.Config) map[string]string {
  19. out := map[string]string{}
  20. if cfg.Decoder.FT8Cmd != "" {
  21. out["FT8"] = cfg.Decoder.FT8Cmd
  22. }
  23. if cfg.Decoder.WSPRCmd != "" {
  24. out["WSPR"] = cfg.Decoder.WSPRCmd
  25. }
  26. if cfg.Decoder.DMRCmd != "" {
  27. out["DMR"] = cfg.Decoder.DMRCmd
  28. }
  29. if cfg.Decoder.DStarCmd != "" {
  30. out["D-STAR"] = cfg.Decoder.DStarCmd
  31. }
  32. if cfg.Decoder.FSKCmd != "" {
  33. out["FSK"] = cfg.Decoder.FSKCmd
  34. }
  35. if cfg.Decoder.PSKCmd != "" {
  36. out["PSK"] = cfg.Decoder.PSKCmd
  37. }
  38. return out
  39. }
  40. func decoderKeys(cfg config.Config) []string {
  41. m := buildDecoderMap(cfg)
  42. keys := make([]string, 0, len(m))
  43. for k := range m {
  44. keys = append(keys, k)
  45. }
  46. sort.Strings(keys)
  47. return keys
  48. }
  49. func extractSignalIQ(iq []complex64, sampleRate int, centerHz float64, sigHz float64, bwHz float64) []complex64 {
  50. if len(iq) == 0 || sampleRate <= 0 {
  51. return nil
  52. }
  53. offset := sigHz - centerHz
  54. shifted := dsp.FreqShift(iq, sampleRate, offset)
  55. cutoff := bwHz / 2
  56. if cutoff < 200 {
  57. cutoff = 200
  58. }
  59. if cutoff > float64(sampleRate)/2-1 {
  60. cutoff = float64(sampleRate)/2 - 1
  61. }
  62. taps := dsp.LowpassFIR(cutoff, sampleRate, 101)
  63. filtered := dsp.ApplyFIR(shifted, taps)
  64. decim := sampleRate / 200000
  65. if decim < 1 {
  66. decim = 1
  67. }
  68. return dsp.Decimate(filtered, decim)
  69. }
  70. func parseSince(raw string) (time.Time, error) {
  71. if raw == "" {
  72. return time.Time{}, nil
  73. }
  74. if ms, err := strconv.ParseInt(raw, 10, 64); err == nil {
  75. if ms > 1e12 {
  76. return time.UnixMilli(ms), nil
  77. }
  78. return time.Unix(ms, 0), nil
  79. }
  80. if t, err := time.Parse(time.RFC3339Nano, raw); err == nil {
  81. return t, nil
  82. }
  83. return time.Parse(time.RFC3339, raw)
  84. }