mirror of
https://github.com/jketterl/openwebrx.git
synced 2025-12-06 07:12:09 +01:00
use the new execmodule where appropriate
This commit is contained in:
parent
69d9a5ae79
commit
32fcfad4d5
|
|
@ -1,14 +1,11 @@
|
||||||
from csdr.module import PopenModule
|
from pycsdr.modules import ExecModule
|
||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
|
|
||||||
|
|
||||||
class DrmModule(PopenModule):
|
class DrmModule(ExecModule):
|
||||||
def getInputFormat(self) -> Format:
|
def __init__(self):
|
||||||
return Format.COMPLEX_FLOAT
|
super().__init__(
|
||||||
|
Format.COMPLEX_SHORT,
|
||||||
def getOutputFormat(self) -> Format:
|
Format.SHORT,
|
||||||
return Format.SHORT
|
["dream", "-c", "6", "--sigsrate", "48000", "--audsrate", "48000", "-I", "-", "-O", "-"]
|
||||||
|
)
|
||||||
def getCommand(self):
|
|
||||||
# dream -c 6 --sigsrate 48000 --audsrate 48000 -I - -O -
|
|
||||||
return ["dream", "-c", "6", "--sigsrate", "48000", "--audsrate", "48000", "-I", "-", "-O", "-"]
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from csdr.module import PopenModule
|
from pycsdr.modules import ExecModule
|
||||||
|
|
||||||
|
|
||||||
class FreeDVModule(PopenModule):
|
class FreeDVModule(ExecModule):
|
||||||
def getInputFormat(self) -> Format:
|
def __init__(self):
|
||||||
return Format.SHORT
|
super().__init__(
|
||||||
|
Format.SHORT,
|
||||||
def getOutputFormat(self) -> Format:
|
Format.SHORT,
|
||||||
return Format.SHORT
|
["freedv_rx", "1600", "-", "-"]
|
||||||
|
)
|
||||||
def getCommand(self):
|
|
||||||
return ["freedv_rx", "1600", "-", "-"]
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from csdr.module import PopenModule, ThreadModule
|
from pycsdr.modules import ExecModule
|
||||||
|
from csdr.module import ThreadModule
|
||||||
from owrx.wsjt import WsjtParser, Msk144Profile
|
from owrx.wsjt import WsjtParser, Msk144Profile
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
|
|
@ -7,15 +8,13 @@ import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Msk144Module(PopenModule):
|
class Msk144Module(ExecModule):
|
||||||
def getCommand(self):
|
def __init__(self):
|
||||||
return ["msk144decoder"]
|
super().__init__(
|
||||||
|
Format.SHORT,
|
||||||
def getInputFormat(self) -> Format:
|
Format.CHAR,
|
||||||
return Format.SHORT
|
["msk144decoder"]
|
||||||
|
)
|
||||||
def getOutputFormat(self) -> Format:
|
|
||||||
return Format.CHAR
|
|
||||||
|
|
||||||
|
|
||||||
class ParserAdapter(ThreadModule):
|
class ParserAdapter(ThreadModule):
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@ popd
|
||||||
rm -rf js8py
|
rm -rf js8py
|
||||||
|
|
||||||
git clone https://github.com/jketterl/csdr.git
|
git clone https://github.com/jketterl/csdr.git
|
||||||
# latest develop as of 2023-08-18 (fmdemod replacement)
|
# latest develop as of 2023-08-21 (introduction of execmodule)
|
||||||
cmakebuild csdr 98de79de2187bf9b7d007fc6ae252175578c1459
|
cmakebuild csdr 3a11e7f800d8226e2f5de89432150a724bc7960e
|
||||||
|
|
||||||
git clone https://github.com/jketterl/pycsdr.git
|
git clone https://github.com/jketterl/pycsdr.git
|
||||||
cd pycsdr
|
cd pycsdr
|
||||||
# latest develop as of 2023-08-16 (added lowpass)
|
# latest develop as of 2023-08-21 (introduction of execmodule)
|
||||||
git checkout eec718ae365583ebf5f315ae45967d2f635ff209
|
git checkout ebb46984c9b2a31dcf3810ad1f11e461a839e114
|
||||||
./setup.py install install_headers
|
./setup.py install install_headers
|
||||||
cd ..
|
cd ..
|
||||||
rm -rf pycsdr
|
rm -rf pycsdr
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
from csdr.module import AutoStartModule
|
|
||||||
from pycsdr.types import Format
|
from pycsdr.types import Format
|
||||||
from pycsdr.modules import Writer, TcpSource
|
from pycsdr.modules import Writer, TcpSource, ExecModule, CallbackWriter
|
||||||
from subprocess import Popen, PIPE
|
|
||||||
from owrx.aprs.direwolf import DirewolfConfig, DirewolfConfigSubscriber
|
from owrx.aprs.direwolf import DirewolfConfig, DirewolfConfigSubscriber
|
||||||
from owrx.config.core import CoreConfig
|
from owrx.config.core import CoreConfig
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
@ -13,46 +10,55 @@ import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DirewolfModule(AutoStartModule, DirewolfConfigSubscriber):
|
class LogWriter(CallbackWriter):
|
||||||
|
def __init__(self):
|
||||||
|
self.retained = bytes()
|
||||||
|
super().__init__(Format.CHAR)
|
||||||
|
|
||||||
|
def write(self, data: bytes) -> None:
|
||||||
|
self.retained += data
|
||||||
|
lines = self.retained.split(b"\n")
|
||||||
|
|
||||||
|
# keep the last line
|
||||||
|
# this should either be empty if the last char was \n
|
||||||
|
# or an incomplete line if the read returned early
|
||||||
|
self.retained = lines[-1]
|
||||||
|
|
||||||
|
# log all completed lines
|
||||||
|
for line in lines[0:-1]:
|
||||||
|
logger.info("{}: {}".format("STDOUT", line.strip(b'\n').decode()))
|
||||||
|
|
||||||
|
|
||||||
|
class DirewolfModule(ExecModule, DirewolfConfigSubscriber):
|
||||||
def __init__(self, service: bool = False):
|
def __init__(self, service: bool = False):
|
||||||
self.process = None
|
|
||||||
self.tcpSource = None
|
self.tcpSource = None
|
||||||
|
self.writer = None
|
||||||
self.service = service
|
self.service = service
|
||||||
self.direwolfConfigPath = "{tmp_dir}/openwebrx_direwolf_{myid}.conf".format(
|
self.direwolfConfigPath = "{tmp_dir}/openwebrx_direwolf_{myid}.conf".format(
|
||||||
tmp_dir=CoreConfig().get_temporary_directory(), myid=id(self)
|
tmp_dir=CoreConfig().get_temporary_directory(), myid=id(self)
|
||||||
)
|
)
|
||||||
self.direwolfConfig = None
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def setWriter(self, writer: Writer) -> None:
|
|
||||||
super().setWriter(writer)
|
|
||||||
if self.tcpSource is not None:
|
|
||||||
self.tcpSource.setWriter(writer)
|
|
||||||
|
|
||||||
def getInputFormat(self) -> Format:
|
|
||||||
return Format.SHORT
|
|
||||||
|
|
||||||
def getOutputFormat(self) -> Format:
|
|
||||||
return Format.CHAR
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.direwolfConfig = DirewolfConfig()
|
self.direwolfConfig = DirewolfConfig()
|
||||||
self.direwolfConfig.wire(self)
|
self.direwolfConfig.wire(self)
|
||||||
|
self.__writeConfig()
|
||||||
|
|
||||||
|
super().__init__(Format.SHORT, Format.CHAR, ["direwolf", "-c", self.direwolfConfigPath, "-r", "48000", "-t", "0", "-q", "d", "-q", "h"])
|
||||||
|
# direwolf supplies the data via a socket which we tap into in start()
|
||||||
|
# the output on its STDOUT is informative, but we still want to log it
|
||||||
|
super().setWriter(LogWriter())
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def __writeConfig(self):
|
||||||
file = open(self.direwolfConfigPath, "w")
|
file = open(self.direwolfConfigPath, "w")
|
||||||
file.write(self.direwolfConfig.getConfig(self.service))
|
file.write(self.direwolfConfig.getConfig(self.service))
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
# direwolf -c {direwolf_config} -r {audio_rate} -t 0 -q d -q h 1>&2
|
def setWriter(self, writer: Writer) -> None:
|
||||||
self.process = Popen(
|
self.writer = writer
|
||||||
["direwolf", "-c", self.direwolfConfigPath, "-r", "48000", "-t", "0", "-q", "d", "-q", "h"],
|
if self.tcpSource is not None:
|
||||||
start_new_session=True,
|
self.tcpSource.setWriter(writer)
|
||||||
stdin=PIPE,
|
|
||||||
)
|
|
||||||
|
|
||||||
# resume in case the reader has been stop()ed before
|
|
||||||
self.reader.resume()
|
|
||||||
threading.Thread(target=self.pump(self.reader.read, self.process.stdin.write)).start()
|
|
||||||
|
|
||||||
|
def start(self):
|
||||||
delay = 0.5
|
delay = 0.5
|
||||||
retries = 0
|
retries = 0
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -68,16 +74,16 @@ class DirewolfModule(AutoStartModule, DirewolfConfigSubscriber):
|
||||||
retries += 1
|
retries += 1
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
def stop(self):
|
def restart(self):
|
||||||
if self.process is not None:
|
self.__writeConfig()
|
||||||
self.process.terminate()
|
super().restart()
|
||||||
self.process.wait()
|
self.start()
|
||||||
self.process = None
|
|
||||||
|
def onConfigChanged(self):
|
||||||
|
self.restart()
|
||||||
|
|
||||||
|
def stop(self) -> None:
|
||||||
|
super().stop()
|
||||||
os.unlink(self.direwolfConfigPath)
|
os.unlink(self.direwolfConfigPath)
|
||||||
self.direwolfConfig.unwire(self)
|
self.direwolfConfig.unwire(self)
|
||||||
self.direwolfConfig = None
|
self.direwolfConfig = None
|
||||||
self.reader.stop()
|
|
||||||
|
|
||||||
def onConfigChanged(self):
|
|
||||||
self.stop()
|
|
||||||
self.start()
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue