Added gnuradio flowgraph in case people are curious.
Added the start script which controls the flow of the server application. Still need to add functionality to listen to audio in the client side. They will need to listen to serverip:6003
This commit is contained in:
parent
9b58120dfd
commit
b2dbe95d2f
3 changed files with 1872 additions and 50 deletions
1774
radio_tuner.grc
Normal file
1774
radio_tuner.grc
Normal file
File diff suppressed because it is too large
Load diff
24
start
Executable file
24
start
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
compress=1
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
echo "Shutting Down"
|
||||||
|
rm ./raw_audio_pipe
|
||||||
|
kill $child_pid
|
||||||
|
}
|
||||||
|
|
||||||
|
mkfifo ./raw_audio_pipe
|
||||||
|
|
||||||
|
# Run Radio Server Program in Background
|
||||||
|
./tuner.py &
|
||||||
|
child_pid=$!
|
||||||
|
|
||||||
|
if [ $compress -eq 1 ]
|
||||||
|
then
|
||||||
|
ffmpeg -f f32le -ar 48k -ac 1 -i pipe:0 -f ogg -ab 32k pipe:1 < ./raw_audio_pipe | nc -kl 127.0.0.1 6003
|
||||||
|
|
||||||
|
else
|
||||||
|
tail -f raw_audio_pipe | nc -kl 127.0.0.1 6003
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup
|
124
tuner.py
124
tuner.py
|
@ -3,12 +3,11 @@
|
||||||
##################################################
|
##################################################
|
||||||
# GNU Radio Python Flow Graph
|
# GNU Radio Python Flow Graph
|
||||||
# Title: Top Block
|
# Title: Top Block
|
||||||
# Generated: Sun May 12 22:10:45 2019
|
# Generated: Sat Jun 1 12:54:09 2019
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
|
|
||||||
from gnuradio import analog
|
from gnuradio import analog
|
||||||
from gnuradio import audio
|
|
||||||
from gnuradio import blocks
|
from gnuradio import blocks
|
||||||
from gnuradio import eng_notation
|
from gnuradio import eng_notation
|
||||||
from gnuradio import filter
|
from gnuradio import filter
|
||||||
|
@ -21,6 +20,7 @@ import time
|
||||||
import socket
|
import socket
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class top_block(gr.top_block):
|
class top_block(gr.top_block):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -29,15 +29,17 @@ class top_block(gr.top_block):
|
||||||
##################################################
|
##################################################
|
||||||
# Variables
|
# Variables
|
||||||
##################################################
|
##################################################
|
||||||
self.samp_rate = samp_rate = 1536000
|
self.samp_rate = samp_rate = 2.2e6
|
||||||
self.frequency = frequency = 96900000
|
self.freq = freq = 101.5e6
|
||||||
|
self.audio_rate = audio_rate = 48000
|
||||||
|
self.audio_interp = audio_interp = 4
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Blocks
|
# Blocks
|
||||||
##################################################
|
##################################################
|
||||||
self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' )
|
self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + '' )
|
||||||
self.rtlsdr_source_0.set_sample_rate(samp_rate)
|
self.rtlsdr_source_0.set_sample_rate(samp_rate)
|
||||||
self.rtlsdr_source_0.set_center_freq(frequency, 0)
|
self.rtlsdr_source_0.set_center_freq(freq, 0)
|
||||||
self.rtlsdr_source_0.set_freq_corr(0, 0)
|
self.rtlsdr_source_0.set_freq_corr(0, 0)
|
||||||
self.rtlsdr_source_0.set_dc_offset_mode(2, 0)
|
self.rtlsdr_source_0.set_dc_offset_mode(2, 0)
|
||||||
self.rtlsdr_source_0.set_iq_balance_mode(2, 0)
|
self.rtlsdr_source_0.set_iq_balance_mode(2, 0)
|
||||||
|
@ -48,22 +50,25 @@ class top_block(gr.top_block):
|
||||||
self.rtlsdr_source_0.set_antenna('', 0)
|
self.rtlsdr_source_0.set_antenna('', 0)
|
||||||
self.rtlsdr_source_0.set_bandwidth(0, 0)
|
self.rtlsdr_source_0.set_bandwidth(0, 0)
|
||||||
|
|
||||||
self.low_pass_filter_0 = filter.fir_filter_ccf(4, firdes.low_pass(
|
self.rational_resampler_xxx_0 = filter.rational_resampler_ccc(
|
||||||
1, samp_rate, 500000, 60000, firdes.WIN_KAISER, 6.76))
|
interpolation=audio_rate * audio_interp,
|
||||||
self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_float*1, '127.0.0.1', 7654, 1472, True)
|
decimation=int(samp_rate),
|
||||||
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
|
taps=None,
|
||||||
|
fractional_bw=None,
|
||||||
|
)
|
||||||
|
self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_float*1, 'raw_audio_pipe', False)
|
||||||
|
self.blocks_file_sink_0.set_unbuffered(False)
|
||||||
self.analog_wfm_rcv_0 = analog.wfm_rcv(
|
self.analog_wfm_rcv_0 = analog.wfm_rcv(
|
||||||
quad_rate=384000,
|
quad_rate=audio_rate * audio_interp,
|
||||||
audio_decimation=8,
|
audio_decimation=audio_interp,
|
||||||
)
|
)
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Connections
|
# Connections
|
||||||
##################################################
|
##################################################
|
||||||
self.connect((self.analog_wfm_rcv_0, 0), (self.blocks_udp_sink_0, 0))
|
self.connect((self.analog_wfm_rcv_0, 0), (self.blocks_file_sink_0, 0))
|
||||||
self.connect((self.blocks_throttle_0, 0), (self.low_pass_filter_0, 0))
|
self.connect((self.rational_resampler_xxx_0, 0), (self.analog_wfm_rcv_0, 0))
|
||||||
self.connect((self.low_pass_filter_0, 0), (self.analog_wfm_rcv_0, 0))
|
self.connect((self.rtlsdr_source_0, 0), (self.rational_resampler_xxx_0, 0))
|
||||||
self.connect((self.rtlsdr_source_0, 0), (self.blocks_throttle_0, 0))
|
|
||||||
|
|
||||||
def get_samp_rate(self):
|
def get_samp_rate(self):
|
||||||
return self.samp_rate
|
return self.samp_rate
|
||||||
|
@ -71,20 +76,64 @@ class top_block(gr.top_block):
|
||||||
def set_samp_rate(self, samp_rate):
|
def set_samp_rate(self, samp_rate):
|
||||||
self.samp_rate = samp_rate
|
self.samp_rate = samp_rate
|
||||||
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
|
self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
|
||||||
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 500000, 60000, firdes.WIN_KAISER, 6.76))
|
|
||||||
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
|
|
||||||
|
|
||||||
def get_frequency(self):
|
def get_freq(self):
|
||||||
return self.frequency
|
return self.freq
|
||||||
|
|
||||||
def set_frequency(self, frequency):
|
def set_freq(self, freq):
|
||||||
self.frequency = frequency
|
self.freq = freq
|
||||||
self.rtlsdr_source_0.set_center_freq(self.frequency, 0)
|
self.rtlsdr_source_0.set_center_freq(self.freq, 0)
|
||||||
|
|
||||||
|
def get_audio_rate(self):
|
||||||
|
return self.audio_rate
|
||||||
|
|
||||||
|
def set_audio_rate(self, audio_rate):
|
||||||
|
self.audio_rate = audio_rate
|
||||||
|
|
||||||
|
def get_audio_interp(self):
|
||||||
|
return self.audio_interp
|
||||||
|
|
||||||
|
def set_audio_interp(self, audio_interp):
|
||||||
|
self.audio_interp = audio_interp
|
||||||
|
|
||||||
|
def is_valid_frequency(frequency):
|
||||||
|
return frequency >= 87500000 and frequency <= 108000000
|
||||||
|
|
||||||
|
def parse_commands(conn, tb, commands):
|
||||||
|
quit = False
|
||||||
|
for command in commands:
|
||||||
|
if command == "":
|
||||||
|
continue
|
||||||
|
elif command[0] == '?': # Query Section
|
||||||
|
if command[1:] == "VER":
|
||||||
|
conn.sendall("Version 0.1\n")
|
||||||
|
elif command[1:] == "FREQ":
|
||||||
|
conn.sendall(str(tb.get_freq()) + '\n')
|
||||||
|
else:
|
||||||
|
print("UNKNOWN COMMAND: ", command)
|
||||||
|
elif command[0] == ':': # Setter Section
|
||||||
|
if command[1:5] == "FREQ":
|
||||||
|
print("FREQUENCY SET")
|
||||||
|
frequency = float(command[6:])
|
||||||
|
if is_valid_frequency(frequency):
|
||||||
|
tb.set_freq(frequency)
|
||||||
|
else:
|
||||||
|
print("ERROR: Invalid Frequency ", frequency)
|
||||||
|
elif command[1:] == "QUIT":
|
||||||
|
print("QUITTING")
|
||||||
|
quit = True
|
||||||
|
else:
|
||||||
|
print("UNKNOWN COMMAND: ", command)
|
||||||
|
else:
|
||||||
|
print("UNKNOWN COMMAND", command)
|
||||||
|
# Return state back to application
|
||||||
|
return {'quit': quit}
|
||||||
|
|
||||||
|
|
||||||
def main(top_block_cls=top_block, options=None):
|
def main(top_block_cls=top_block, options=None):
|
||||||
tb = top_block_cls()
|
tb = top_block_cls()
|
||||||
tb.start()
|
tb.start()
|
||||||
|
|
||||||
HOST = '127.0.0.1' # Loopback Address (Localhost)
|
HOST = '127.0.0.1' # Loopback Address (Localhost)
|
||||||
PORT = 65432 # Semi-Random Port that is non-priviledged (> 1023)
|
PORT = 65432 # Semi-Random Port that is non-priviledged (> 1023)
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
@ -103,34 +152,9 @@ def main(top_block_cls=top_block, options=None):
|
||||||
commands = re.split(";", data)
|
commands = re.split(";", data)
|
||||||
if data == "":
|
if data == "":
|
||||||
break
|
break
|
||||||
for command in commands:
|
state = parse_commands(conn, tb, commands)
|
||||||
if command == "":
|
if state['quit']:
|
||||||
continue
|
quit = True
|
||||||
elif command[0] == '?':
|
|
||||||
# Query Section
|
|
||||||
if command[1:] == "VER":
|
|
||||||
conn.sendall("Version 0.1\n")
|
|
||||||
elif command[1:] == "FREQ":
|
|
||||||
conn.sendall(str(tb.get_frequency()) + '\n')
|
|
||||||
else:
|
|
||||||
print("UNKNOWN COMMAND: ", command)
|
|
||||||
elif command[0] == ':':
|
|
||||||
# Setter Section
|
|
||||||
if command[1:5] == "FREQ":
|
|
||||||
print("FREQUENCY SET")
|
|
||||||
frequency = float(command[6:])
|
|
||||||
if frequency >= 87500000 and frequency <= 108000000:
|
|
||||||
tb.set_frequency(frequency)
|
|
||||||
else:
|
|
||||||
print("ERROR: Invalid Frequency ", frequency)
|
|
||||||
elif command[1:] == "QUIT":
|
|
||||||
print("QUITTING")
|
|
||||||
quit = True
|
|
||||||
else:
|
|
||||||
print("UNKNOWN COMMAND: ", command)
|
|
||||||
else:
|
|
||||||
print("UNKNOWN COMMAND", command)
|
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue