설명 없음

rawmodulator.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. type DCSignal struct {
  17. Signal int8
  18. Quality int8
  19. }
  20. // RawModulator is fun
  21. type RawModulator struct {
  22. input chan DCSignal
  23. output chan int16
  24. settings *ModemSettings
  25. phaseQ16 uint16 // phase acc 0..2math.Pi -> 0..65536
  26. amplitude int16 // peak RawModulator amplitude for one tone
  27. wOneQ16 uint16 // scaled one freq 0..2math.Pi -> 0..65536
  28. wZeroQ16 uint16 // scaled zero freq 0..2math.Pi -> 0..65536
  29. sinLutQ15 []int16 // sine lookup table
  30. callback Callback
  31. }
  32. // NewRawModulator is fun
  33. func NewRawModulator(ctx context.Context, s *ModemSettings, input chan DCSignal, output chan int16) *RawModulator {
  34. m := new(RawModulator)
  35. m.input = input
  36. m.output = output
  37. m.settings = s
  38. m.amplitude = 16384
  39. wOne, wZero := calculateW(m.settings.OneFreq, m.settings.ZeroFreq, m.settings.SampleRate)
  40. m.wOneQ16 = uint16((65536 / (2.0 * math.Pi)) * wOne)
  41. m.wZeroQ16 = uint16((65536 / (2.0 * math.Pi)) * wZero)
  42. m.sinLutQ15 = make([]int16, 16384)
  43. for i := 0; i < 16384; i++ {
  44. m.sinLutQ15[i] = int16(32767 * math.Sin(2.0*math.Pi*float64(i)/float64(16384)))
  45. }
  46. go m.run(ctx)
  47. return m
  48. }
  49. // SetCallback is fun
  50. func (m *RawModulator) SetCallback(callback Callback) {
  51. m.callback = callback
  52. }
  53. func (m *RawModulator) SetAmplitude(amplitude int16) {
  54. m.amplitude = amplitude
  55. }
  56. func (m *RawModulator) run(ctx context.Context) {
  57. var lut uint16
  58. for {
  59. select {
  60. case <-ctx.Done():
  61. return
  62. case s := <-m.input:
  63. if s.Signal > 0 {
  64. lut = m.wOneQ16
  65. } else {
  66. lut = m.wZeroQ16
  67. }
  68. m.phaseQ16 += lut
  69. if s.Quality > 0 {
  70. m.output <- multq15(m.amplitude, m.sinLutQ15[m.phaseQ16>>2])
  71. } else {
  72. m.output <- 0
  73. }
  74. }
  75. }
  76. }