2017-07-12 2 views
0

Ich spiele FM Radio und versuche die Frequenz meines RTL-SDR für meinen Raspberry Pi 3 zu ändern, während ich streame (dh ohne das Programm herunterfahren und neu starten zu müssen))Stream FM Radio auf Raspberry Pi, Frequenzwechsel ohne Neustart

Es spielt derzeit den Sender und ich kann den Sender/Frequenz langsam erhöhen. Wenn ich es jedoch zu schnell inkrementiere, hört das SDR auf zu spielen.

Ich verwende:

  • Himbeere 3 Pi, in Python zu schreiben 2.7.9
  • NooElec R820T SDR & DVB-T USB-Dongle
  • Drehgeber zur Eingabe gewünschten Frequenz
  • pi-encoder Bibliothek
  • rtl_fm zu empfangen und sox zu spielen
Mein Code

ist derzeit:

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

Ist Python subprocess tolerant zu diesem Zweck?

Gibt es einen anderen Weg (Befehl, Methode, Bibliothek), der einen reibungsloseren und schnelleren Wechsel des Senders/der Frequenz ermöglichen würde, der die Wiedergabe nicht beeinträchtigt oder das Abspielen des SDR verhindert?

Antwort

0

Möglicherweise müssen Sie einen Weg finden, auf process.kill() zu warten und die Pipes zu schließen (es geschieht asynchron), bevor Sie mit Ihrem updateStation-Aufruf einen neuen Prozess starten. Versuchen Sie eine kleine Verzögerung in Ihrer main while() - Schleife nach einem Kill auszuführen, um zu verhindern, dass Prozessbefehle schneller gesendet werden, als das Betriebssystem zuverlässig verarbeiten kann.

+0

Ich habe die "updateStation" -Funktion zehn Mal mit einem Ruhezustand zwischen jedem Anruf getestet. Ich war in der Lage, bis zu 0,6 Sekunden Schlaf stabil zu bleiben. Darunter war es schuppig. – spearna

+0

Ich denke, deine Empfehlung ist die Art, wie ich gehen werde. Ich werde einen Catch implementieren, um zu verhindern, dass Race Condition s/w kill und ein neuer Call. Ich füge auch einen Haken hinzu, um eine schnelle Änderung der Station zu handhaben, um zu vermeiden, den Befehl rtl_fm aufzurufen, bis ich die gewünschte Station erreicht habe. – spearna