Starting and stopping of local audio playback working through REST API
This commit is contained in:
parent
59ca70b20b
commit
0b559a8f85
90
radio.py
90
radio.py
@ -3,6 +3,9 @@ import SoapySDR as soapy
|
||||
import prefixed
|
||||
from formats import *
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import struct
|
||||
|
||||
|
||||
class Radio:
|
||||
@ -11,9 +14,6 @@ class Radio:
|
||||
|
||||
def __init__(self, device_info):
|
||||
self.device_info = device_info
|
||||
self.stream = None
|
||||
self.buffer = None
|
||||
self.port = None
|
||||
self.run = False
|
||||
self.thread = None
|
||||
|
||||
@ -21,7 +21,6 @@ class Radio:
|
||||
if self.device is None:
|
||||
raise RuntimeError("Failed to connect to radio device")
|
||||
|
||||
|
||||
def configure(self, frequency):
|
||||
frequency = int(prefixed.Float(frequency))
|
||||
sample_rate = 384000
|
||||
@ -41,31 +40,14 @@ class Radio:
|
||||
'gain-mode': 'auto' if self.device.getGainMode(soapy.SOAPY_SDR_RX, 0) else 'manual',
|
||||
}
|
||||
|
||||
|
||||
def start_stream(self):
|
||||
if self.thread:
|
||||
raise RuntimeError('Stream thread is already running')
|
||||
|
||||
self.buffer = np.array([0] * Radio.SAMPLES * 2, TYPES[Radio.FORMAT])
|
||||
self.stream = self.device.setupStream(soapy.SOAPY_SDR_RX, FORMATS[Radio.FORMAT])
|
||||
self.device.activateStream(self.stream)
|
||||
|
||||
self.run = True
|
||||
self.thread = Thread(target=self._stream_thread, daemon=True, args=())
|
||||
self.thread.start()
|
||||
|
||||
|
||||
def _stream_thread(self):
|
||||
while self.run:
|
||||
result = self.device.readStream(self.stream, [self.buffer], Radio.SAMPLES)
|
||||
|
||||
if result.ret < 1:
|
||||
print('Stream read failed, exiting.', file=sys.stderr)
|
||||
self.keep_going = False
|
||||
|
||||
self._cleanup_stream()
|
||||
|
||||
|
||||
def end_stream(self):
|
||||
if self.thread is None:
|
||||
raise RuntimeError('No stream thread to terminate')
|
||||
@ -74,8 +56,72 @@ class Radio:
|
||||
self.thread.join()
|
||||
self.thread = None
|
||||
|
||||
def _stream_thread(self):
|
||||
self._init_stream()
|
||||
|
||||
while self.run:
|
||||
result = self.device.readStream(self.stream, [self.buffer], Radio.SAMPLES)
|
||||
|
||||
if result.ret < 1:
|
||||
print('Stream read failed, exiting.', file=sys.stderr)
|
||||
self.keep_going = False
|
||||
|
||||
read_size = int(result.ret * 2)
|
||||
self.demod.stdin.write(
|
||||
struct.pack(PACKINGS[Radio.FORMAT] % read_size,
|
||||
*self.buffer[:read_size])
|
||||
)
|
||||
|
||||
self._cleanup_stream()
|
||||
|
||||
def _init_stream(self):
|
||||
self.playback = subprocess.Popen(
|
||||
['/usr/bin/sox', '-t', 'raw', '-r', '32000', '-b', '16', '-c', '2', '-L', '-e', 'signed-integer', '-', '-d'],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
|
||||
self.demod = subprocess.Popen(
|
||||
['/usr/bin/python3', 'fm_demod.py', '-f', 'CS16', '-s', '384k', '-d', '32k'],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=self.playback.stdin,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
|
||||
self.buffer = np.array([0] * Radio.SAMPLES * 2, TYPES[Radio.FORMAT])
|
||||
self.stream = self.device.setupStream(soapy.SOAPY_SDR_RX, FORMATS[Radio.FORMAT])
|
||||
self.device.activateStream(self.stream)
|
||||
|
||||
def _cleanup_stream(self):
|
||||
#shutdown the stream
|
||||
# Cleanup the streaming objects in the reverse order to the _init method.
|
||||
self.device.deactivateStream(self.stream)
|
||||
self.device.closeStream(self.stream)
|
||||
self.buffer = None
|
||||
|
||||
self.demod.kill()
|
||||
self.playback.kill()
|
||||
|
||||
|
||||
"""
|
||||
Quick and dirty test of the Radio class.
|
||||
"""
|
||||
if __name__ == '__main__':
|
||||
import time
|
||||
|
||||
sdr = Radio({'driver': 'sdrplay'})
|
||||
|
||||
print('Configuring...')
|
||||
sdr.configure('105.5M')
|
||||
print('Configured.')
|
||||
|
||||
print('Starting stream...')
|
||||
sdr.start_stream()
|
||||
print('Stream started.')
|
||||
|
||||
# Let the stream play for a while
|
||||
time.sleep(5)
|
||||
|
||||
print('Ending stream...')
|
||||
sdr.end_stream()
|
||||
print('Stream ended.')
|
||||
Loading…
Reference in New Issue
Block a user