在 Raspberry Pi 上播放 FM 广播,无需重启即可更改频率
Stream FM Radio on Raspberry Pi, Changing Frequency without Restarting
我正在播放 FM 收音机并尝试更改我的 Raspberry Pi 3 的 RTL-SDR 频率,同时进行流式传输(即,无需关闭程序并重新启动)
它目前正在播放电台,我可以慢慢增加 station/frequency。但是,如果我增加得太快,SDR 就会停止播放。
我正在使用:
- Raspberry Pi3、写在Python2.7.9
- NooElec R820T SDR 和 DVB-T USB 适配器
- 旋转编码器输入所需频率
- pi-encoder图书馆
- rtl_fm 接球和 sox 比赛
我的代码目前是:
import os
import time
import subprocess
from pi_encoder import *
def updateStation(station_addr, kill=0):
print 'creating pipe1a'
pipe1a = subprocess.Popen(['rtl_fm', '-M', 'wbfm', '-f', str(station_addr) + 'M', '-g', '10'], stdout=subprocess.PIPE)
print 'creating pipe1b'
pipe1b = subprocess.Popen(['play', '-r', '32k', '-t', 'raw', '-e', 's', '-b', '16', '-c', '1', '-V1', '-'], stdin=pipe1a.stdout, stdout=subprocess.PIPE)
print 'creating pipe1c'
pipe1c = pipe1b.stdout
pid_a = pipe1a.pid
return pid_a, pipe1a
# Export LD_LIBRARY_PATH; doesn't seem to retain
os.system('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib')
## Rotary encoder GPIO PIN assignments are set in 'pi_encoder' module
## SET INITIAL VALUES
tuner_value = 0
station_addr = 95.1
max_tuner_addr = 109.1
min_tuner_addr = 88.0
## INITIALIZE ROTARY ENCODER WORKER THREAD
tuner_encoder = EncoderWorker(SwitchEncoder(TUNER_CLK_PIN, TUNER_DT_PIN, TUNER_SW_PIN))
tuner_encoder.start()
## MAIN LOOP
try:
print 'Starting main loop'
pid, process = updateStation(station_addr)
while True:
delta_tuner = tuner_encoder.get_delta()
if delta_tuner!=0:
tuner_value = tuner_value + delta_tuner
print "tuner value", tuner_value
station_addr = station_addr + (delta_tuner/10.0)
if station_addr > max_tuner_addr:
station_addr = max_tuner_addr
elif station_addr < min_tuner_addr:
station_addr = min_tuner_addr
print 'station_address: ', station_addr
print 'terminating process:'
process.terminate()
try:
os.kill(pid, 0)
process.kill()
except OSError, e:
print 'Terminated gracefully'
pid, process = updateStation(station_addr)
if tuner_encoder.get_upEvent():
print "tuner up!"
if tuner_encoder.get_downEvent():
print "tuner down!"
finally:
print 'Cleaning up GPIO...'
IO.cleanup()
python 子进程能容忍这种使用吗?
是否有另一种方法(命令、方法、库)可以更流畅、更快速地更改 station/frequency 而不会影响播放或阻止 SDR 播放?
在使用 updateStation 调用启动新进程之前,您可能需要找到一种方法等待 process.kill() 完成并关闭管道(它是异步发生的)。尝试在任何 kill 之后在主 while() 循环中放置一个小的延迟,以防止它发送进程命令的速度快于 OS 可以可靠处理的速度。
我正在播放 FM 收音机并尝试更改我的 Raspberry Pi 3 的 RTL-SDR 频率,同时进行流式传输(即,无需关闭程序并重新启动)
它目前正在播放电台,我可以慢慢增加 station/frequency。但是,如果我增加得太快,SDR 就会停止播放。
我正在使用:
- Raspberry Pi3、写在Python2.7.9
- NooElec R820T SDR 和 DVB-T USB 适配器
- 旋转编码器输入所需频率
- pi-encoder图书馆
- rtl_fm 接球和 sox 比赛
我的代码目前是:
import os
import time
import subprocess
from pi_encoder import *
def updateStation(station_addr, kill=0):
print 'creating pipe1a'
pipe1a = subprocess.Popen(['rtl_fm', '-M', 'wbfm', '-f', str(station_addr) + 'M', '-g', '10'], stdout=subprocess.PIPE)
print 'creating pipe1b'
pipe1b = subprocess.Popen(['play', '-r', '32k', '-t', 'raw', '-e', 's', '-b', '16', '-c', '1', '-V1', '-'], stdin=pipe1a.stdout, stdout=subprocess.PIPE)
print 'creating pipe1c'
pipe1c = pipe1b.stdout
pid_a = pipe1a.pid
return pid_a, pipe1a
# Export LD_LIBRARY_PATH; doesn't seem to retain
os.system('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib')
## Rotary encoder GPIO PIN assignments are set in 'pi_encoder' module
## SET INITIAL VALUES
tuner_value = 0
station_addr = 95.1
max_tuner_addr = 109.1
min_tuner_addr = 88.0
## INITIALIZE ROTARY ENCODER WORKER THREAD
tuner_encoder = EncoderWorker(SwitchEncoder(TUNER_CLK_PIN, TUNER_DT_PIN, TUNER_SW_PIN))
tuner_encoder.start()
## MAIN LOOP
try:
print 'Starting main loop'
pid, process = updateStation(station_addr)
while True:
delta_tuner = tuner_encoder.get_delta()
if delta_tuner!=0:
tuner_value = tuner_value + delta_tuner
print "tuner value", tuner_value
station_addr = station_addr + (delta_tuner/10.0)
if station_addr > max_tuner_addr:
station_addr = max_tuner_addr
elif station_addr < min_tuner_addr:
station_addr = min_tuner_addr
print 'station_address: ', station_addr
print 'terminating process:'
process.terminate()
try:
os.kill(pid, 0)
process.kill()
except OSError, e:
print 'Terminated gracefully'
pid, process = updateStation(station_addr)
if tuner_encoder.get_upEvent():
print "tuner up!"
if tuner_encoder.get_downEvent():
print "tuner down!"
finally:
print 'Cleaning up GPIO...'
IO.cleanup()
python 子进程能容忍这种使用吗?
是否有另一种方法(命令、方法、库)可以更流畅、更快速地更改 station/frequency 而不会影响播放或阻止 SDR 播放?
在使用 updateStation 调用启动新进程之前,您可能需要找到一种方法等待 process.kill() 完成并关闭管道(它是异步发生的)。尝试在任何 kill 之后在主 while() 循环中放置一个小的延迟,以防止它发送进程命令的速度快于 OS 可以可靠处理的速度。