123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- // Copyright (C) 2017 Keelan Lightfoot
- // Copyright (C) 2007-2008 Board of Regents of the University of Wisconsin
- // System (Univ. of Wisconsin-Madison, Trace R&D Center)
- // Copyright (C) 2007-2008 Omnitor AB
- // Copyright (C) 2007-2008 Voiceriver Inc
- //
- // This library is free software; you can redistribute it and/or modify it
- // under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation; either version 2.1 of the License, or (at
- // your option) any later version.
-
- package gortty
-
- import (
- "context"
- "math"
- )
-
- type DCSignal struct {
- Signal int8
- Quality int8
- }
-
- // RawModulator is fun
- type RawModulator struct {
- input chan DCSignal
- output chan int16
-
- settings *ModemSettings
-
- phaseQ16 uint16 // phase acc 0..2math.Pi -> 0..65536
- amplitude int16 // peak RawModulator amplitude for one tone
- wOneQ16 uint16 // scaled one freq 0..2math.Pi -> 0..65536
- wZeroQ16 uint16 // scaled zero freq 0..2math.Pi -> 0..65536
- sinLutQ15 []int16 // sine lookup table
- callback Callback
- }
-
- // NewRawModulator is fun
- func NewRawModulator(ctx context.Context, s *ModemSettings, input chan DCSignal, output chan int16) *RawModulator {
-
- m := new(RawModulator)
-
- m.input = input
- m.output = output
-
- m.settings = s
-
- m.amplitude = 16384
-
- wOne, wZero := calculateW(m.settings.OneFreq, m.settings.ZeroFreq, m.settings.SampleRate)
-
- m.wOneQ16 = uint16((65536 / (2.0 * math.Pi)) * wOne)
- m.wZeroQ16 = uint16((65536 / (2.0 * math.Pi)) * wZero)
-
- m.sinLutQ15 = make([]int16, 16384)
- for i := 0; i < 16384; i++ {
- m.sinLutQ15[i] = int16(32767 * math.Sin(2.0*math.Pi*float64(i)/float64(16384)))
- }
- go m.run(ctx)
- return m
- }
-
- // SetCallback is fun
- func (m *RawModulator) SetCallback(callback Callback) {
- m.callback = callback
- }
-
- func (m *RawModulator) SetAmplitude(amplitude int16) {
- m.amplitude = amplitude
- }
-
- func (m *RawModulator) run(ctx context.Context) {
-
- var lut uint16
- for {
- select {
- case <-ctx.Done():
- return
- case s := <-m.input:
- if s.Signal > 0 {
- lut = m.wOneQ16
- } else {
- lut = m.wZeroQ16
- }
- m.phaseQ16 += lut
- if s.Quality > 0 {
- m.output <- multq15(m.amplitude, m.sinLutQ15[m.phaseQ16>>2])
- } else {
- m.output <- 0
- }
- }
-
- }
-
- }
|