简体   繁体   English

在Raspberry Pi上流FM广播,无需重新启动即可更改频率

[英]Stream FM Radio on Raspberry Pi, Changing Frequency without Restarting

I am playing FM radio and trying to change the frequency of my RTL-SDR for my Raspberry Pi 3, while streaming (ie, without having to shut down the program and restart) 我正在播放FM广播,并尝试在流传输时更改Raspberry Pi 3的RTL-SDR频率(即,无需关闭程序并重新启动)

It currently plays the station and I can increment the station/frequency slowly. 当前正在播放电台,我可以缓慢增加电台/频率。 However, if I increment it too fast, the SDR stops playing. 但是,如果我增加得太快,SDR将停止播放。

I'm using: 我正在使用:

  • Raspberry Pi 3, writing in Python 2.7.9 Raspberry Pi 3,用Python 2.7.9编写
  • NooElec R820T SDR & DVB-T USB dongle NooElec R820T SDR和DVB-T USB软件狗
  • Rotary Encoder to input desired frequency 旋转编码器输入所需的频率
  • pi-encoder library pi编码器
  • rtl_fm to receive and sox to play rtl_fm接收和sox播放

My code is currently: 我的代码当前为:

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()

Is python subprocess tolerant to this use? python子进程可以容忍这种用法吗?

Is there another way (command, method, library) that would allow a more smooth and quick change of station/frequency that wouldn't affect play or stop the SDR from playing? 是否有另一种方式(命令,方法,库)可以更平滑,更快速地更改电台/频率,而不影响播放或停止播放SDR?

You may need to find a way wait for process.kill() to finish and the pipes to close (it happens asynchronously), before starting the a new process with your updateStation call. 在使用updateStation调用启动新进程之前,您可能需要找到一种方法来等待process.kill()完成和管道关闭(异步发生)。 Try putting a small delay in your main while() loop after any kill to prevent it from sending process commands faster than the OS can reliably handle. 尝试在执行任何杀死操作后在main while()循环中稍加延迟,以防止其发送进程命令的速度超过操作系统能够可靠处理的速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM