fix the secondary fft display
This commit is contained in:
parent
909a969e04
commit
e77b0f4a67
@ -779,13 +779,10 @@ function on_ws_recv(evt) {
|
|||||||
break;
|
break;
|
||||||
case "secondary_config":
|
case "secondary_config":
|
||||||
var s = json['value'];
|
var s = json['value'];
|
||||||
if ('secondary_fft_size' in s)
|
secondary_fft_size = s['secondary_fft_size'] || secondary_fft_size;
|
||||||
window.secondary_fft_size = s['secondary_fft_size'];
|
secondary_bw = s['secondary_bw'] || secondary_bw;
|
||||||
if ('secondary_bw' in s)
|
if_samp_rate = s['if_samp_rate'] || if_samp_rate;
|
||||||
window.secondary_bw = s['secondary_bw'];
|
if (if_samp_rate) secondary_demod_init_canvases();
|
||||||
if ('if_samp_rate' in s)
|
|
||||||
window.if_samp_rate = s['if_samp_rate'];
|
|
||||||
secondary_demod_init_canvases();
|
|
||||||
break;
|
break;
|
||||||
case "receiver_details":
|
case "receiver_details":
|
||||||
$('.webrx-top-container').header().setDetails(json['value']);
|
$('.webrx-top-container').header().setDetails(json['value']);
|
||||||
@ -1391,6 +1388,8 @@ var secondary_demod_current_canvas_actual_line;
|
|||||||
var secondary_demod_current_canvas_context;
|
var secondary_demod_current_canvas_context;
|
||||||
var secondary_demod_current_canvas_index;
|
var secondary_demod_current_canvas_index;
|
||||||
var secondary_demod_canvases;
|
var secondary_demod_canvases;
|
||||||
|
var secondary_bw = 31.25;
|
||||||
|
var if_samp_rate;
|
||||||
|
|
||||||
function secondary_demod_create_canvas() {
|
function secondary_demod_create_canvas() {
|
||||||
var new_canvas = document.createElement("canvas");
|
var new_canvas = document.createElement("canvas");
|
||||||
|
63
owrx/dsp.py
63
owrx/dsp.py
@ -11,6 +11,7 @@ from pycsdr.modules import Buffer, Writer
|
|||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
import pickle
|
import pickle
|
||||||
@ -20,11 +21,23 @@ import logging
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# now that's a name. help, i've reached enterprise level OOP here
|
||||||
|
class ClientDemodulatorSecondaryDspEventClient(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def onSecondaryDspRateChange(self, rate):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def onSecondaryDspBandwidthChange(self, bw):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ClientDemodulatorChain(Chain):
|
class ClientDemodulatorChain(Chain):
|
||||||
def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, hdOutputRate: int, audioCompression: str):
|
def __init__(self, demod: BaseDemodulatorChain, sampleRate: int, outputRate: int, hdOutputRate: int, audioCompression: str, secondaryDspEventReceiver: ClientDemodulatorSecondaryDspEventClient):
|
||||||
self.sampleRate = sampleRate
|
self.sampleRate = sampleRate
|
||||||
self.outputRate = outputRate
|
self.outputRate = outputRate
|
||||||
self.hdOutputRate = hdOutputRate
|
self.hdOutputRate = hdOutputRate
|
||||||
|
self.secondaryDspEventReceiver = secondaryDspEventReceiver
|
||||||
self.selector = Selector(sampleRate, outputRate)
|
self.selector = Selector(sampleRate, outputRate)
|
||||||
self.selector.setBandpass(-4000, 4000)
|
self.selector.setBandpass(-4000, 4000)
|
||||||
self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT)
|
self.selectorBuffer = Buffer(Format.COMPLEX_FLOAT)
|
||||||
@ -142,9 +155,11 @@ class ClientDemodulatorChain(Chain):
|
|||||||
self._syncSquelch()
|
self._syncSquelch()
|
||||||
|
|
||||||
if isinstance(self.secondaryDemodulator, SecondarySelectorChain):
|
if isinstance(self.secondaryDemodulator, SecondarySelectorChain):
|
||||||
self.secondarySelector = SecondarySelector(rate, self.secondaryDemodulator.getBandwidth())
|
bandwidth = self.secondaryDemodulator.getBandwidth()
|
||||||
|
self.secondarySelector = SecondarySelector(rate, bandwidth)
|
||||||
self.secondarySelector.setReader(self.selectorBuffer.getReader())
|
self.secondarySelector.setReader(self.selectorBuffer.getReader())
|
||||||
self.secondarySelector.setFrequencyOffset(self.secondaryFrequencyOffset)
|
self.secondarySelector.setFrequencyOffset(self.secondaryFrequencyOffset)
|
||||||
|
self.secondaryDspEventReceiver.onSecondaryDspBandwidthChange(bandwidth)
|
||||||
else:
|
else:
|
||||||
self.secondarySelector = None
|
self.secondarySelector = None
|
||||||
|
|
||||||
@ -169,6 +184,7 @@ class ClientDemodulatorChain(Chain):
|
|||||||
|
|
||||||
if self.secondaryFftChain is not None:
|
if self.secondaryFftChain is not None:
|
||||||
self.secondaryFftChain.setSampleRate(rate)
|
self.secondaryFftChain.setSampleRate(rate)
|
||||||
|
self.secondaryDspEventReceiver.onSecondaryDspRateChange(rate)
|
||||||
|
|
||||||
def _createSecondaryFftChain(self):
|
def _createSecondaryFftChain(self):
|
||||||
if self.secondaryFftChain is not None:
|
if self.secondaryFftChain is not None:
|
||||||
@ -351,7 +367,7 @@ class ModulationValidator(OrValidator):
|
|||||||
super().__init__(BoolValidator(), RegexValidator(re.compile("^[a-z0-9]+$")))
|
super().__init__(BoolValidator(), RegexValidator(re.compile("^[a-z0-9]+$")))
|
||||||
|
|
||||||
|
|
||||||
class DspManager(SdrSourceEventClient):
|
class DspManager(SdrSourceEventClient, ClientDemodulatorSecondaryDspEventClient):
|
||||||
def __init__(self, handler, sdrSource):
|
def __init__(self, handler, sdrSource):
|
||||||
self.handler = handler
|
self.handler = handler
|
||||||
self.sdrSource = sdrSource
|
self.sdrSource = sdrSource
|
||||||
@ -410,7 +426,8 @@ class DspManager(SdrSourceEventClient):
|
|||||||
self.props["samp_rate"],
|
self.props["samp_rate"],
|
||||||
self.props["output_rate"],
|
self.props["output_rate"],
|
||||||
self.props["hd_output_rate"],
|
self.props["hd_output_rate"],
|
||||||
self.props["audio_compression"]
|
self.props["audio_compression"],
|
||||||
|
self
|
||||||
)
|
)
|
||||||
|
|
||||||
self.readers = {}
|
self.readers = {}
|
||||||
@ -433,7 +450,7 @@ class DspManager(SdrSourceEventClient):
|
|||||||
self.props.wireProperty("fft_compression", self.chain.setSecondaryFftCompression),
|
self.props.wireProperty("fft_compression", self.chain.setSecondaryFftCompression),
|
||||||
self.props.wireProperty("fft_voverlap_factor", self.chain.setSecondaryFftOverlapFactor),
|
self.props.wireProperty("fft_voverlap_factor", self.chain.setSecondaryFftOverlapFactor),
|
||||||
self.props.wireProperty("fft_fps", self.chain.setSecondaryFftFps),
|
self.props.wireProperty("fft_fps", self.chain.setSecondaryFftFps),
|
||||||
self.props.wireProperty("digimodes_fft_size", self.chain.setSecondaryFftSize),
|
self.props.wireProperty("digimodes_fft_size", self.setSecondaryFftSize),
|
||||||
self.props.wireProperty("samp_rate", self.chain.setSampleRate),
|
self.props.wireProperty("samp_rate", self.chain.setSampleRate),
|
||||||
self.props.wireProperty("output_rate", self.chain.setOutputRate),
|
self.props.wireProperty("output_rate", self.chain.setOutputRate),
|
||||||
self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate),
|
self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate),
|
||||||
@ -445,18 +462,7 @@ class DspManager(SdrSourceEventClient):
|
|||||||
self.props.wireProperty("mod", self.setDemodulator),
|
self.props.wireProperty("mod", self.setDemodulator),
|
||||||
self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
|
self.props.wireProperty("dmr_filter", self.chain.setSlotFilter),
|
||||||
self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau),
|
self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau),
|
||||||
]
|
|
||||||
|
|
||||||
def set_secondary_mod(mod):
|
|
||||||
if mod == False:
|
|
||||||
mod = None
|
|
||||||
self.dsp.set_secondary_demodulator(mod)
|
|
||||||
#if mod is not None:
|
|
||||||
#send_secondary_config()
|
|
||||||
|
|
||||||
self.subscriptions += [
|
|
||||||
self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator),
|
self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator),
|
||||||
self.props.wireProperty("digimodes_fft_size", self.chain.setSecondaryFftSize),
|
|
||||||
self.props.wireProperty("secondary_offset_freq", self.chain.setSecondaryFrequencyOffset),
|
self.props.wireProperty("secondary_offset_freq", self.chain.setSecondaryFrequencyOffset),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -486,6 +492,10 @@ class DspManager(SdrSourceEventClient):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
def setSecondaryFftSize(self, size):
|
||||||
|
self.chain.setSecondaryFftSize(size)
|
||||||
|
self.handler.write_secondary_dsp_config({"secondary_fft_size": size})
|
||||||
|
|
||||||
def _getDemodulator(self, demod: Union[str, BaseDemodulatorChain]) -> Optional[BaseDemodulatorChain]:
|
def _getDemodulator(self, demod: Union[str, BaseDemodulatorChain]) -> Optional[BaseDemodulatorChain]:
|
||||||
if isinstance(demod, BaseDemodulatorChain):
|
if isinstance(demod, BaseDemodulatorChain):
|
||||||
return demod
|
return demod
|
||||||
@ -539,20 +549,9 @@ class DspManager(SdrSourceEventClient):
|
|||||||
self.chain.setWriter(buffer)
|
self.chain.setWriter(buffer)
|
||||||
self.wireOutput(self.audioOutput, buffer)
|
self.wireOutput(self.audioOutput, buffer)
|
||||||
|
|
||||||
def sendSecondaryConfig(self):
|
|
||||||
self.handler.write_secondary_dsp_config(
|
|
||||||
{
|
|
||||||
"secondary_fft_size": self.props["digimodes_fft_size"],
|
|
||||||
"if_samp_rate": self.props["output_rate"],
|
|
||||||
# TODO
|
|
||||||
"secondary_bw": 31.25
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def _getSecondaryDemodulator(self, mod) -> Optional[SecondaryDemodulator]:
|
def _getSecondaryDemodulator(self, mod) -> Optional[SecondaryDemodulator]:
|
||||||
if isinstance(mod, SecondaryDemodulator):
|
if isinstance(mod, SecondaryDemodulator):
|
||||||
return mod
|
return mod
|
||||||
# TODO add remaining modes
|
|
||||||
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
|
if mod in ["ft8", "wspr", "jt65", "jt9", "ft4", "fst4", "fst4w", "q65"]:
|
||||||
from csdr.chain.digimodes import AudioChopperDemodulator
|
from csdr.chain.digimodes import AudioChopperDemodulator
|
||||||
from owrx.wsjt import WsjtParser
|
from owrx.wsjt import WsjtParser
|
||||||
@ -579,7 +578,6 @@ class DspManager(SdrSourceEventClient):
|
|||||||
if not demodulator:
|
if not demodulator:
|
||||||
self.chain.setSecondaryDemodulator(None)
|
self.chain.setSecondaryDemodulator(None)
|
||||||
else:
|
else:
|
||||||
self.sendSecondaryConfig()
|
|
||||||
self.chain.setSecondaryDemodulator(demodulator)
|
self.chain.setSecondaryDemodulator(demodulator)
|
||||||
|
|
||||||
def setAudioCompression(self, comp):
|
def setAudioCompression(self, comp):
|
||||||
@ -589,8 +587,7 @@ class DspManager(SdrSourceEventClient):
|
|||||||
# wrong output format... need to re-wire
|
# wrong output format... need to re-wire
|
||||||
buffer = Buffer(self.chain.getOutputFormat())
|
buffer = Buffer(self.chain.getOutputFormat())
|
||||||
self.chain.setWriter(buffer)
|
self.chain.setWriter(buffer)
|
||||||
# TODO check if this is hd audio
|
self.wireOutput(self.audioOutput, buffer)
|
||||||
self.wireOutput("audio", buffer)
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self.sdrSource.isAvailable():
|
if self.sdrSource.isAvailable():
|
||||||
@ -677,3 +674,9 @@ class DspManager(SdrSourceEventClient):
|
|||||||
|
|
||||||
def onShutdown(self):
|
def onShutdown(self):
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
|
def onSecondaryDspBandwidthChange(self, bw):
|
||||||
|
self.handler.write_secondary_dsp_config({"secondary_bw": bw})
|
||||||
|
|
||||||
|
def onSecondaryDspRateChange(self, rate):
|
||||||
|
self.handler.write_secondary_dsp_config({"if_samp_rate": rate})
|
||||||
|
Loading…
Reference in New Issue
Block a user