No Description

rawdemodulator.go 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2017 Keelan Lightfoot
  2. // Copyright (C) 2007-2008 Board of Regents of the University of Wisconsin
  3. // System (Univ. of Wisconsin-Madison, Trace R&D Center)
  4. // Copyright (C) 2007-2008 Omnitor AB
  5. // Copyright (C) 2007-2008 Voiceriver Inc
  6. //
  7. // This library is free software; you can redistribute it and/or modify it
  8. // under the terms of the GNU Lesser General Public License as published by
  9. // the Free Software Foundation; either version 2.1 of the License, or (at
  10. // your option) any later version.
  11. package gortty
  12. import (
  13. "context"
  14. "math"
  15. )
  16. // RawDemodulator is fun
  17. type RawDemodulator struct {
  18. input chan int16
  19. output chan DCSignal
  20. dsp *dsp
  21. settings *ModemSettings
  22. sigOut bool
  23. samplerate int
  24. div int
  25. }
  26. // NewRawDemodulator is fun
  27. func NewRawDemodulator(ctx context.Context, s *ModemSettings, input chan int16, output chan DCSignal) *RawDemodulator {
  28. d := new(RawDemodulator)
  29. d.input = input
  30. d.output = output
  31. d.settings = s
  32. // the bandpass filter is picky about the sample rate, and the output is perfectly
  33. // balanced when the sample rate is 3x the center frequency, so lets divide the sample
  34. // rate down to as close to that as we can get.
  35. centerFrequency := math.Abs(float64(d.settings.OneFreq)+float64(d.settings.ZeroFreq)) / 2 * 3
  36. d.div = int(math.Floor(float64(d.settings.SampleRate) / float64(centerFrequency)))
  37. if d.div == 0 {
  38. d.div = 1
  39. }
  40. d.samplerate = d.settings.SampleRate / d.div
  41. d.dsp = newDsp(d.settings.OneFreq, d.settings.ZeroFreq, d.samplerate)
  42. go d.run(ctx)
  43. return d
  44. }
  45. func (d *RawDemodulator) run(ctx context.Context) {
  46. count := 0
  47. for {
  48. select {
  49. case <-ctx.Done():
  50. return
  51. case sam := <-d.input:
  52. // sample rate reduction
  53. count++
  54. if count%d.div > 0 {
  55. continue
  56. }
  57. d.dsp.demod(float64(sam))
  58. var signal int8
  59. var quality int8
  60. if math.Abs(d.dsp.demLpf) > d.dsp.demTotal*d.dsp.minThresh && d.dsp.demTotal*d.dsp.minThresh != 0 {
  61. quality = 1
  62. } else {
  63. quality = 0
  64. }
  65. if d.dsp.demLpf-d.dsp.minThresh*d.dsp.demTotal > 0 {
  66. signal = 1 * quality
  67. } else {
  68. signal = -1 * quality
  69. }
  70. d.output <- DCSignal{
  71. Signal: signal,
  72. Quality: quality,
  73. }
  74. }
  75. }
  76. }