def activateFm(self, tau): print("[DEMOD] Setting up FM demodulator...") self.abortAudio() self.stereo = True self.demod = WBFM(tau, self.sfs, self.afs, self.dsp_buff) self.p = pyaudio.PyAudio() self.que.queue.clear() self.stream = self.p.open( format=pyaudio.paFloat32, channels=2, frames_per_buffer=self.dsp_out, rate=self.afs, output=True, stream_callback=self.fm)
def setDevice(self, device): device = toDevice(device) print("[DEMOD] Activating {} device.".format(device["label"])) self.sdr = SoapySDR.Device(device) self.sdr.setGainMode(SOAPY_SDR_RX, 0, True) self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) supported_fs = self.sdr.getSampleRateRange(SOAPY_SDR_RX, 0) avfs = [ [240e3, 256e3, 1.024e6, 2.5e6, 3.0e6], [960e3, 480e3, 240e3, 256e3, 768e3, 1.024e6, 2.5e6, 3.0e6], ] self.sfs = int(768e3) self.mfs = int(240e3) self.afs = int(48e3) for fs in reversed(supported_fs): for pfs in avfs[self.pmode]: if pfs >= fs.minimum() and pfs <= fs.maximum(): self.sfs = int(pfs) break print("[DEMOD] Sampling Rate: {}".format(self.sfs)) self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * 8 self.dec_out = int(np.ceil(self.dsp_buff / (self.sfs / self.mfs))) self.dsp_out = int(np.ceil(self.dec_out / (self.mfs / self.afs))) print(self.sdr_buff / self.sfs) self.dec = Decimator(self.sfs, self.mfs, self.dec_out, cuda=self.cuda) self.wbfm = WBFM(self.tau, self.mfs, self.afs, self.dec_out, cuda=self.cuda, numba=self.numba) self.sdr.setSampleRate(SOAPY_SDR_RX, 0, self.sfs) self.device = str(device)
def setDevice(self, device, buffer_mult=8): self.sfs = int(768e3) self.mfs = int(240e3) self.afs = int(48e3) self.sfs = self.soapy.init(device, [ [240e3, 256e3, 1.024e6, 2.5e6, 3.0e6], [960e3, 480e3, 240e3, 256e3, 768e3, 1.024e6, 2.5e6, 3.0e6], ]) print("[DEMOD] Sampling Rate: {}".format(self.sfs)) self.sdr_buff = 2048 self.dsp_buff = self.sdr_buff * buffer_mult self.dec_out = int(np.ceil(self.dsp_buff / (self.sfs / self.mfs))) self.dsp_out = int(np.ceil(self.dec_out / (self.mfs / self.afs))) self.dec = Decimator(self.sfs, self.mfs, cuda=self.cuda) self.wbfm = WBFM(self.tau, self.mfs, self.afs, cuda=self.cuda)
def __init__(self, sfs, afs, mult, cuda): super(AnalogTest, self).__init__() self.sfs = int(sfs) self.afs = int(afs) self.tau = 75e-6 self.mult = int(mult) self.cuda = cuda self.number = 500 self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * self.mult self.wbfm = WBFM(self.tau, self.sfs, self.afs, cuda) self.mfm = MFM(self.tau, self.sfs, self.afs, cuda) if self.cuda: import cusignal as sig self.buff = sig.get_shared_mem(self.dsp_buff, dtype=np.complex64) else: self.buff = np.zeros([self.dsp_buff], dtype=np.complex64)
class Demodulator(QThread): def __init__(self, freq, cuda=False, numba=False): QThread.__init__(self) # Global Settings self.device = dict() self.numba = numba self.cuda = cuda self.running = False self.pmode = 1 self.safed = True self.mode = 0 self.vol = 1.0 self.freq = freq # FM Settings self.tau = 75e-6 self.stereo = True # Demodulation FIFO self.que = queue.Queue() self.sd = importlib.import_module("sounddevice") def setDevice(self, device): device = toDevice(device) print("[DEMOD] Activating {} device.".format(device["label"])) self.sdr = SoapySDR.Device(device) self.sdr.setGainMode(SOAPY_SDR_RX, 0, True) self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) supported_fs = self.sdr.getSampleRateRange(SOAPY_SDR_RX, 0) avfs = [ [240e3, 256e3, 1.024e6, 2.5e6, 3.0e6], [960e3, 480e3, 240e3, 256e3, 768e3, 1.024e6, 2.5e6, 3.0e6], ] self.sfs = int(768e3) self.mfs = int(240e3) self.afs = int(48e3) for fs in reversed(supported_fs): for pfs in avfs[self.pmode]: if pfs >= fs.minimum() and pfs <= fs.maximum(): self.sfs = int(pfs) break print("[DEMOD] Sampling Rate: {}".format(self.sfs)) self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * 8 self.dec_out = int(np.ceil(self.dsp_buff / (self.sfs / self.mfs))) self.dsp_out = int(np.ceil(self.dec_out / (self.mfs / self.afs))) print(self.sdr_buff / self.sfs) self.dec = Decimator(self.sfs, self.mfs, self.dec_out, cuda=self.cuda) self.wbfm = WBFM(self.tau, self.mfs, self.afs, self.dec_out, cuda=self.cuda, numba=self.numba) self.sdr.setSampleRate(SOAPY_SDR_RX, 0, self.sfs) self.device = str(device) def setFreq(self, freq): self.freq = freq self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) def stop(self): print("[DEMOD] Stopping.") self.running = False while not self.safed: time.sleep(0.05) def run(self): print("[DEMOD] Starting.") self.running = True self.safed = False plan = [(i * self.sdr_buff) for i in range(self.dsp_buff // self.sdr_buff)] buff = np.zeros([self.dsp_buff], dtype=np.complex64) rx = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32) self.sdr.activateStream(rx) with self.sd.OutputStream(blocksize=self.dsp_out, callback=self.router, samplerate=self.afs, channels=2): while self.running: for i in plan: self.sdr.readStream(rx, [buff[i:]], self.sdr_buff) self.que.put_nowait(buff.astype(np.complex64)) with self.que.mutex: self.que.queue.clear() self.sdr.deactivateStream(rx) self.sdr.closeStream(rx) self.safed = True def router(self, outdata, f, t, s): if self.que.qsize() < 1: time.sleep(0.1) try: inp = self.que.get(timeout=0.5) except queue.Empty: raise self.sd.CallbackAbort finally: if not self.running: raise self.sd.CallbackAbort if self.mode == 0: L, R = self.wbfm.run(self.dec.run(inp)) if self.wbfm.freq >= 19010 and self.wbfm.freq <= 18990: R = L outdata[:] = (np.dstack((L, R)) * self.vol) if self.mode == 1: LR = np.zeros((self.dsp_out * 2), dtype=np.float32) outdata[:] = LR.reshape(self.dsp_out, 2)
def setFM(self, tau): self.stereo = True self.demod = WBFM(tau, self.sfs, self.afs, self.dsp_buff, self.cuda, self.numba)
class Demodulator(QThread): def __init__(self, freq, cuda=False, numba=False): QThread.__init__(self) self.numba = numba self.cuda = cuda self.device = dict() self.running = False self.safed = True self.mode = 0 self.vol = 1.0 self.freq = freq self.sfs = int(256e3) self.afs = int(32e3) self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * 4 self.dsp_out = int(self.dsp_buff / (self.sfs / self.afs)) def setDevice(self, device): device = toDevice(device) print("[DEMOD] Activating {} device.".format(device["label"])) self.sdr = SoapySDR.Device(device) self.sdr.setGainMode(SOAPY_SDR_RX, 0, True) self.sdr.setSampleRate(SOAPY_SDR_RX, 0, self.sfs) self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) self.device = str(device) def setFM(self, tau): self.stereo = True self.demod = WBFM(tau, self.sfs, self.afs, self.dsp_buff, self.cuda, self.numba) def setAM(self): pass def setFreq(self, freq): self.freq = freq self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) def stop(self): print("[DEMOD] Stopping.") self.running = False while not self.safed: pass def run(self): print("[DEMOD] Starting.") self.running = True self.safed = False buff = np.zeros([self.dsp_buff], dtype=np.complex64) rx = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32) self.sdr.activateStream(rx) self.que = queue.Queue() with sd.RawOutputStream(blocksize=self.dsp_out, callback=self.router, samplerate=self.afs, channels=2): while self.running: for i in range(self.dsp_buff // self.sdr_buff): self.sdr.readStream(rx, [buff[(i * self.sdr_buff):]], self.sdr_buff, timeoutUs=int(1e9)) self.que.put(buff.astype(np.complex64)) self.sdr.deactivateStream(rx) self.sdr.closeStream(rx) self.safed = True def router(self, outdata, frames, time, status): if self.mode == 0: outdata[:] = self.fm().tobytes() elif self.mode == 1: outdata[:] = self.am().tobytes() def fm(self): L, R = self.demod.run(self.que.get()) if self.demod.freq >= 19015 and self.demod.freq <= 18985: return (np.dstack((L, L)) * self.vol).astype(np.float32) else: return (np.dstack((L, R)) * self.vol).astype(np.float32) def am(self): self.que.get() LR = np.zeros((self.dsp_out * 2), dtype=np.float32) return LR.reshape(self.dsp_out, 2)
"ofs": ofs, "chs": 2, "codec": opuslib.APPLICATION_AUDIO }, ] # ZeroMQ Declaration url = '*' port = 8080 sio = socketio.AsyncServer(async_mode='aiohttp', cors_allowed_origins='*') app = web.Application() sio.attach(app) # Radio-Core Declaration tuner = Tuner(stations, sfs, cuda=cuda) demod = [WBFM(tau, r['bw'], r['afs'], r['bw'], cuda=cuda) for r in stations] queue = asyncio.Queue() sdr_buff = 1200 # OPUS Declaration opus = [opuslib.Encoder(r['afs'], r['chs'], r['codec']) for r in stations] # Radio Declaration args = dict(driver="lime") sdr = SoapySDR.Device(args) sdr.setGainMode(SOAPY_SDR_RX, 0, True) sdr.setSampleRate(SOAPY_SDR_RX, 0, tuner.bw) sdr.setFrequency(SOAPY_SDR_RX, 0, tuner.mdf) # Buffer Declaration if cuda:
class Demodulator(QThread): def __init__(self, freq): QThread.__init__(self) self.device = dict() self.running = False self.vol = 1.0 self.freq = freq self.sfs = int(256e3) self.afs = int(32e3) self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * 3 self.dsp_out = int(self.dsp_buff / (self.sfs / self.afs)) self.p = pyaudio.PyAudio() self.que = queue.Queue() def activateDevice(self, device): device = toDevice(device) print("[DEMOD] Activating {} device.".format(device["label"])) try: self.sdr.unmake() except: pass self.sdr = SoapySDR.Device(device) self.sdr.setGainMode(SOAPY_SDR_RX, 0, True) self.sdr.setSampleRate(SOAPY_SDR_RX, 0, self.sfs) self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) self.device = str(device) def setFreq(self, freq): self.freq = freq self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) def stop(self): print("[DEMOD] Stopping Demodulator") self.running = False def run(self): print("[DEMOD] Starting Demodulator") self.rx = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32) self.sdr.activateStream(self.rx) self.running = True buff = np.zeros([self.dsp_buff], dtype=np.complex64) while self.running: for i in range(self.dsp_buff // self.sdr_buff): self.sdr.readStream(self.rx, [buff[(i * self.sdr_buff):]], self.sdr_buff, timeoutUs=int(1e9)) self.que.put(buff.astype(np.complex64)) self.stream.stop_stream() self.stream.close() self.sdr.deactivateStream(self.rx) self.sdr.closeStream(self.rx) print("[DEMOD] Device stream has stopped.") def activateFm(self, tau): print("[DEMOD] Setting up FM demodulator...") self.stereo = True self.demod = WBFM(tau, self.sfs, self.afs, self.dsp_buff) try: self.stream.stop_stream() self.stream.close() except: pass self.stream = self.p.open(format=pyaudio.paFloat32, channels=2, frames_per_buffer=self.dsp_out, rate=self.afs, output=True, stream_callback=self.fm) self.que.queue.clear() def fm(self, in_data, frame_count, time_info, status): L, R = self.demod.run(self.que.get()) I = np.zeros((self.dsp_out * 2), dtype=np.float32) if self.demod.freq < 19015 and self.demod.freq > 18985: I[0::2] = L I[1::2] = R else: I[0::2] = L I[1::2] = L I *= self.vol return (I.reshape(self.dsp_out, 2), pyaudio.paContinue) def activateAm(self): print("[DEMOD] Setting up AM demodulator...") try: self.stream.stop_stream() self.stream.close() except: pass def am(self, in_data, frame_count, time_info, status): pass
class Demodulator(QThread): def __init__(self, soapy, cuda=False): QThread.__init__(self) # Global Settings self.soapy = soapy self.cuda = cuda self.running = False self.pmode = 1 self.safed = True self.mode = 0 self.vol = 1.0 # FM Settings self.tau = 75e-6 self.stereo = True # Demodulation FIFO self.que = queue.Queue() self.sd = importlib.import_module("sounddevice") def setDevice(self, device, buffer_mult=8): self.sfs = int(768e3) self.mfs = int(240e3) self.afs = int(48e3) self.sfs = self.soapy.init(device, [ [240e3, 256e3, 1.024e6, 2.5e6, 3.0e6], [960e3, 480e3, 240e3, 256e3, 768e3, 1.024e6, 2.5e6, 3.0e6], ]) print("[DEMOD] Sampling Rate: {}".format(self.sfs)) self.sdr_buff = 2048 self.dsp_buff = self.sdr_buff * buffer_mult self.dec_out = int(np.ceil(self.dsp_buff / (self.sfs / self.mfs))) self.dsp_out = int(np.ceil(self.dec_out / (self.mfs / self.afs))) self.dec = Decimator(self.sfs, self.mfs, cuda=self.cuda) self.wbfm = WBFM(self.tau, self.mfs, self.afs, cuda=self.cuda) def stop(self): print("[DEMOD] Stopping.") self.running = False while not self.safed: time.sleep(0.05) def run(self): print("[DEMOD] Starting.") self.running = True self.safed = False buff = np.zeros([self.dsp_buff], dtype=np.complex64) self.soapy.start() with self.sd.OutputStream(blocksize=self.dsp_out, callback=self.router, samplerate=self.afs, channels=2): while self.running: count = 0 while count < self.dsp_buff: count += self.soapy.read([buff[count:]], self.sdr_buff) self.que.put(buff.astype(np.complex64)) with self.que.mutex: self.que.queue.clear() self.soapy.stop() self.safed = True def router(self, outdata, f, t, s): if self.que.qsize() < 1: time.sleep(0.1) try: inp = self.que.get(timeout=0.5) except queue.Empty: raise self.sd.CallbackAbort finally: if not self.running: raise self.sd.CallbackAbort if self.mode == 0: L, R = self.wbfm.run(self.dec.run(inp)) if self.wbfm.freq >= 19010 and self.wbfm.freq <= 18990: R = L outdata[:] = (np.dstack((L, R)) * self.vol) if self.mode == 1: LR = np.zeros((self.dsp_out * 2), dtype=np.float32) outdata[:] = LR.reshape(self.dsp_out, 2)
class Demodulator(QThread): def __init__(self, freq): QThread.__init__(self) self.device = dict() self.running = False self.vol = 1.0 self.freq = freq self.sfs = int(256e3) self.afs = int(32e3) self.sdr_buff = 1024 self.dsp_buff = self.sdr_buff * 4 self.dsp_out = int(self.dsp_buff/(self.sfs/self.afs)) self.que = queue.Queue() def activateDevice(self, device): device = toDevice(device) print("[DEMOD] Activating {} device.".format(device["label"])) self.sdr = SoapySDR.Device(device) self.sdr.setGainMode(SOAPY_SDR_RX, 0, True) self.sdr.setSampleRate(SOAPY_SDR_RX, 0, self.sfs) self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) self.device = str(device) def setFreq(self, freq): self.freq = freq self.sdr.setFrequency(SOAPY_SDR_RX, 0, self.freq) def stop(self): print("[DEMOD] Stopping Demodulator") self.running = False def run(self): print("[DEMOD] Starting Demodulator") self.rx = self.sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32) self.sdr.activateStream(self.rx) self.running = True buff = np.zeros([self.dsp_buff], dtype=np.complex64) while self.running: for i in range(self.dsp_buff//self.sdr_buff): self.sdr.readStream( self.rx, [buff[(i*self.sdr_buff):]], self.sdr_buff, timeoutUs=int(1e9)) self.que.put(buff.astype(np.complex64)) self.abortAudio() self.sdr.deactivateStream(self.rx) self.sdr.closeStream(self.rx) print("[DEMOD] Device stream has stopped.") def abortAudio(self): if not self.running: return print("[DEMOD] Aborting audio.") try: self.stream.stop_stream() self.stream.close() self.p.terminate() except Exception as e: print("[DEMOD] Error aborting audio:", e) def activateFm(self, tau): print("[DEMOD] Setting up FM demodulator...") self.abortAudio() self.stereo = True self.demod = WBFM(tau, self.sfs, self.afs, self.dsp_buff) self.p = pyaudio.PyAudio() self.que.queue.clear() self.stream = self.p.open( format=pyaudio.paFloat32, channels=2, frames_per_buffer=self.dsp_out, rate=self.afs, output=True, stream_callback=self.fm) def fm(self, in_data, frame_count, time_info, status): # Receive and Demodulate Samples L, R = self.demod.run(self.que.get()) # Ensure Conversion to F32 L = L.astype(np.float32) R = R.astype(np.float32) # Create PyAudio Stereo Matrix LR = np.zeros((self.dsp_out*2), dtype=np.float32) if self.demod.freq >= 19015 and self.demod.freq <= 18985: LR[0::2] = L LR[1::2] = L else: LR[0::2] = L LR[1::2] = R # Further Sanitize the Output LR *= self.vol LR = LR.reshape(self.dsp_out, 2) return (LR, pyaudio.paContinue) def activateAm(self): print("[DEMOD] Setting up AM demodulator...") self.abortAudio() def am(self, in_data, frame_count, time_info, status): pass