1
- from csdr .chain .demodulator import BaseDemodulatorChain , FixedIfSampleRateChain , HdAudio , DeemphasisTauChain
2
- from pycsdr .modules import AmDemod , DcBlock , FmDemod , Limit , NfmDeemphasis , Agc , Afc , WfmDeemphasis , FractionalDecimator , RealPart
1
+ from csdr .chain .demodulator import BaseDemodulatorChain , FixedIfSampleRateChain , HdAudio , \
2
+ DeemphasisTauChain , MetaProvider , RdsChain
3
+ from pycsdr .modules import AmDemod , DcBlock , FmDemod , Limit , NfmDeemphasis , Agc , Afc , \
4
+ WfmDeemphasis , FractionalDecimator , RealPart , Writer , Buffer
3
5
from pycsdr .types import Format , AgcProfile
6
+ from csdr .chain .redsea import Redsea
7
+ from typing import Optional
8
+ from owrx .feature import FeatureDetector
4
9
5
10
6
11
class Am (BaseDemodulatorChain ):
@@ -38,18 +43,29 @@ def setSampleRate(self, sampleRate: int) -> None:
38
43
self .replace (2 , NfmDeemphasis (sampleRate ))
39
44
40
45
41
- class WFm (BaseDemodulatorChain , FixedIfSampleRateChain , DeemphasisTauChain , HdAudio ):
42
- def __init__ (self , sampleRate : int , tau : float ):
46
+ class WFm (BaseDemodulatorChain , FixedIfSampleRateChain , DeemphasisTauChain , HdAudio , MetaProvider , RdsChain ):
47
+ def __init__ (self , sampleRate : int , tau : float , rdsRbds : bool ):
43
48
self .sampleRate = sampleRate
44
49
self .tau = tau
50
+ self .rdsRbds = rdsRbds
51
+ self .limit = Limit ()
52
+ # this buffer is used to tap into the raw audio stream for redsea RDS decoding
53
+ self .metaTapBuffer = Buffer (Format .FLOAT )
45
54
workers = [
46
55
FmDemod (),
47
- Limit () ,
56
+ self . limit ,
48
57
FractionalDecimator (Format .FLOAT , 200000.0 / self .sampleRate , prefilter = True ),
49
58
WfmDeemphasis (self .sampleRate , self .tau ),
50
59
]
60
+ self .metaChain = None
61
+ self .metaWriter = None
51
62
super ().__init__ (workers )
52
63
64
+ def _connect (self , w1 , w2 , buffer : Optional [Buffer ] = None ) -> None :
65
+ if w1 is self .limit :
66
+ buffer = self .metaTapBuffer
67
+ super ()._connect (w1 , w2 , buffer )
68
+
53
69
def getFixedIfSampleRate (self ):
54
70
return 200000
55
71
@@ -66,6 +82,30 @@ def setSampleRate(self, sampleRate: int) -> None:
66
82
self .replace (2 , FractionalDecimator (Format .FLOAT , 200000.0 / self .sampleRate , prefilter = True ))
67
83
self .replace (3 , WfmDeemphasis (self .sampleRate , self .tau ))
68
84
85
+ def setMetaWriter (self , writer : Writer ) -> None :
86
+ if not FeatureDetector ().is_available ("rds" ):
87
+ return
88
+ if self .metaChain is None :
89
+ self .metaChain = Redsea (self .getFixedIfSampleRate (), self .rdsRbds )
90
+ self .metaChain .setReader (self .metaTapBuffer .getReader ())
91
+ self .metaWriter = writer
92
+ self .metaChain .setWriter (self .metaWriter )
93
+
94
+ def stop (self ):
95
+ super ().stop ()
96
+ if self .metaChain is not None :
97
+ self .metaChain .stop ()
98
+ self .metaChain = None
99
+ self .metaWriter = None
100
+
101
+ def setRdsRbds (self , rdsRbds : bool ) -> None :
102
+ self .rdsRbds = rdsRbds
103
+ if self .metaChain is not None :
104
+ self .metaChain .stop ()
105
+ self .metaChain = Redsea (self .getFixedIfSampleRate (), self .rdsRbds )
106
+ self .metaChain .setReader (self .metaTapBuffer .getReader ())
107
+ self .metaChain .setWriter (self .metaWriter )
108
+
69
109
70
110
class Ssb (BaseDemodulatorChain ):
71
111
def __init__ (self ):
0 commit comments