Esempio n. 1
0
def main():
    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10
    print '  sample rate: %0.6f MHz' % (sdr.rs / 1e6)
    print '  center frequency %0.6f MHz' % (sdr.fc / 1e6)
    print '  gain: %d dB' % sdr.gain

    print 'Reading samples...'
    samples = sdr.read_samples(256 * 1024)
    print '  signal mean:', sum(samples) / len(samples)

    print 'Testing callback...'
    sdr.read_samples_async(test_callback, 256 * 1024)

    try:
        import pylab as mpl

        print 'Testing spectrum plotting...'
        mpl.figure()
        mpl.psd(samples, NFFT=1024, Fc=sdr.fc / 1e6, Fs=sdr.rs / 1e6)

        mpl.show()
    except:
        # matplotlib not installed/working
        pass

    print 'Done\n'
    sdr.close()
Esempio n. 2
0
def main():
    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10
    print '  sample rate: %0.6f MHz' % (sdr.rs/1e6)
    print '  center frequency %0.6f MHz' % (sdr.fc/1e6)
    print '  gain: %d dB' % sdr.gain

    print 'Reading samples...'
    samples = sdr.read_samples(256*1024)
    print '  signal mean:', sum(samples)/len(samples)

    print 'Testing callback...'
    sdr.read_samples_async(test_callback, 256*1024)

    try:
        import pylab as mpl

        print 'Testing spectrum plotting...'
        mpl.figure()
        mpl.psd(samples, NFFT=1024, Fc=sdr.fc/1e6, Fs=sdr.rs/1e6)

        mpl.show()
    except:
        # matplotlib not installed/working
        pass

    print 'Done\n'
    sdr.close()
Esempio n. 3
0
class SDRThread(QThread):
    signal = pyqtSignal(object)

    def __init__(self,
                 sample_rate=2.4e6,
                 center_freq=100.0e6,
                 freq_correction=60,
                 gain=33.8,
                 chunks=1024):
        QThread.__init__(self)

        # configure device
        try:
            self.sdr = RtlSdr()
        except LibUSBError:
            print("No Hardware Detected")
            self.isRunning = False

        else:
            self.sdr.sample_rate = sample_rate  # Hz
            self.sdr.center_freq = center_freq  # Hz
            self.sdr.freq_correction = freq_correction  # PPM
            self.sdr.gain = gain  # dB
            self.isRunning = True

        self.CHUNK = chunks

    def __del__(self):
        if self.isRunning:
            self.wait()

    def stop_thread(self):
        self.isRunning = False
        self.sdr.cancel_read_async()
        self.sdr.close()

    def sdr_tune(self, cf):
        self.sdr.center_freq = cf  # Hz

    def sdr_gain(self, gain=33.8):
        self.sdr.gain = gain

    def run(self):
        if self.isRunning:
            self.sdr.read_samples_async(self.sdr_async_callback, self.CHUNK,
                                        None)

    def sdr_async_callback(self, iq, ctx):
        power, _ = mlab.psd(iq,
                            NFFT=self.CHUNK,
                            Fs=self.sdr.sample_rate,
                            scale_by_freq=False)
        self.signal.emit(np.sqrt(power))
Esempio n. 4
0
 def run(self):
   
   # Read 128ms of data at a time (must be a multiple of a power of two)
   blkSize = SAMPLE_RATE_KHZ()*128;
   blockLoc = np.zeros(1,dtype=np.uint64);
   
   sdr = RtlSdr();
   # configure device
   sdr.sample_rate = SAMPLE_RATE_KHZ()*1e3  # Hz
   sdr.center_freq = 1575420000     # Hz
   sdr.gain = 29;
   sdrQueue.put((sdr,blockLoc,blkSize/SAMPLE_RATE_KHZ(),1));
   sdr.read_samples_async(sdrCallback, blkSize, context=sdrQueue);
Esempio n. 5
0
    def run(self):

        # Read 128ms of data at a time (must be a multiple of a power of two)
        blkSize = SAMPLE_RATE_KHZ() * 128
        blockLoc = np.zeros(1, dtype=np.uint64)

        sdr = RtlSdr()
        # configure device
        sdr.sample_rate = SAMPLE_RATE_KHZ() * 1e3  # Hz
        sdr.center_freq = 1575420000  # Hz
        sdr.gain = 29
        sdrQueue.put((sdr, blockLoc, blkSize / SAMPLE_RATE_KHZ(), 1))
        sdr.read_samples_async(sdrCallback, blkSize, context=sdrQueue)
Esempio n. 6
0
def main():
    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print '   sample rate: %0.6f MHz' % (sdr.rs / 1e6)
    print '   center ferquency %0.6f MHz' % (sdr.fc / 1e6)
    print '   gain: %d dB' % sdr.gain

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)
Esempio n. 7
0
def main():
    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print '   sample rate: %0.6f MHz' % (sdr.rs/1e6)
    print '   center ferquency %0.6f MHz' % (sdr.fc/1e6)
    print '   gain: %d dB' % sdr.gain

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)
Esempio n. 8
0
def main():
    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 2.4e6
    sdr.fc = 70e6
    sdr.gain = 4
    print '  sample rate: %0.6f MHz' % (sdr.rs / 1e6)
    print '  center frequency %0.6f MHz' % (sdr.fc / 1e6)
    print '  gain: %d dB' % sdr.gain

    print 'Reading samples...'
    samples = sdr.read_samples(1024)
    print '  signal mean:', sum(samples) / len(samples)

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)

    sdr.close()
Esempio n. 9
0
def main():
    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 2.4e6
    sdr.fc = 70e6
    sdr.gain = 4
    print '  sample rate: %0.6f MHz' % (sdr.rs/1e6)
    print '  center frequency %0.6f MHz' % (sdr.fc/1e6)
    print '  gain: %d dB' % sdr.gain

    print 'Reading samples...'
    samples = sdr.read_samples(1024)
    print '  signal mean:', sum(samples)/len(samples)

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)

    sdr.close()
Esempio n. 10
0
def main():

    @limit_time(0.01)
    @limit_calls(20)
    def read_callback(buffer, rtlsdr_obj):
        print('In callback')
        print('   signal mean:', sum(buffer)/len(buffer))

    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print('Configuring SDR...')
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print('   sample rate: %0.6f MHz' % (sdr.rs/1e6))
    print('   center ferquency %0.6f MHz' % (sdr.fc/1e6))
    print('   gain: %d dB' % sdr.gain)

    print('Testing callback...')
    sdr.read_samples_async(read_callback)
Esempio n. 11
0
class FMRadio:

    sample_buffer = Queue.Queue(maxsize=100)
    base_spectrum = np.ones(5780)

    def __init__(self,freq,N_samples):

        self.sample_rate = 1e6
        self.decim_r1 = 1e6/2e5 # for wideband fm
        self.decim_r2 = 2e5/44100 # for baseband recovery
        self.center_freq = freq+250e3
        self.gain = 36

        self.N_samples = N_samples
        self.is_sampling = False

        self.sdr =  RtlSdr()
        self.sdr.direct_sampling = 1
        self.sdr.sample_rate = self.sample_rate
        self.sdr.center_freq = self.center_freq
        self.sdr.gain = self.gain

        self.pa = pyaudio.PyAudio()
        self.stream = self.pa.open( format = pyaudio.paFloat32,
                                    channels = 1,
                                    rate = 44100,
                                    output = True)

        adj = 0
        hamming = 10*signal.hamming(self.N_samples*.10 + adj)
        lpf = np.append( np.zeros(self.N_samples*.45),hamming)
        self.lpf = np.roll(np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*.45))),int(-.25*self.N_samples))

    def __del__(self):
        print "sdr closed"
        self.sdr.close()
        print "pyaudio terminated"
        self.pa.terminate()

    def getSamples(self):
        #N_samples = self.N_samples # 1/24.4 seconds   ~46336 #approximately a 2048/44100 amount's time
        return self.sdr.read_samples(self.N_samples)

    def getSamplesAsync(self):
        #Asynchronous call. Meant to be put in a loop w/ a calback fn
        #print 'gonna sample'
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)

    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
              #  print 'gottum'
            except:
                print "wtf idk no samples?"
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)

            self.play(audio_out)

        print 'gonna try to finish off the to-do list'
        sample_buffer.join()


    def demodulate(self,samples):
        # DEMODULATION CODE
        #samples = #self.sample_buffer.get()
        # LIMITER goes here

        # low pass & down sampling via fft


        spectrum = np.fft.fft(samples)*self.lpf

        toplot = False
        if(toplot):
            fig = plt.figure()
            plt.plot(np.abs(spectrum))
            plt.show()

# Decimate in two rounds. One to 200k, another to 44.1k
        # DECIMATE HERE. Note that we're looking at 1MHz bandwidth.
        n_s = spectrum.size

        channel_spectrum = spectrum[int(n_s*.75-.5*n_s/self.decim_r1):int(.75*n_s+.5*n_s/self.decim_r1)] #np.append(spectrum[0:int(n_s/self.decim_r1*.5)],spectrum[n_s-int(n_s/self.decim_r1*.5):n_s])

        #radio_spectrum -= np.mean(radio_spectrum) #attempt to remove dc bias
        #print channel_spectrum.size
        toplot = False
        if(toplot):
            fig = plt.figure()
            plt.plot(np.abs(np.fft.ifftshift(channel_spectrum)))
            plt.show()


        lp_samples = np.fft.ifft(np.fft.ifftshift(channel_spectrum))

        #lp_samples = self.lowpass_filter(lp_samples,4)
        power = np.abs(self.rms(lp_samples))
        lp_samples /= power
        #print np.abs(self.rms(lp_samples))

    # polar discriminator
        dphase = np.zeros(lp_samples.size)

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase = ( A * np.conj(B) )

#dpm = np.mean(np.abs(dphase))
        # normalize
        #       dphase /= dpm
        #dphase.resize(dphase.size+1)
        dphase[dphase.size-1] = dphase[dphase.size-2]

        rebuilt = signal.medfilt(np.angle(dphase)/np.pi,21) #  np.cos(dphase)

        #phase = np.sin(rebuilt)
        #phase = self.lowpass_filter(phase,8)

        #rebuilt= self.lowpass_filter(rebuilt,8)

        toplot = False
        if toplot:
            fig = plt.figure()
            ax = fig.add_subplot(111)
            ax.plot(rebuilt)

            plt.show()


        spectrum = np.fft.fft(rebuilt) #* self.lpf2

        n_z = spectrum.size
        #base_spectrum = np.append(spectrum[0:1024],spectrum[n_z-1024:n_z])
        self.base_spectrum = np.append(spectrum[0:int(n_z/self.decim_r2*.5)],spectrum[n_z-int(n_z/self.decim_r2*.5):n_s])

        output = np.fft.ifft(self.base_spectrum)

        output = self.lowpass_filter(np.real(output),8) # just the tip (kills the 19k pilot)

#         toplot = False
#         if(toplot):
#             fig = plt.figure()
#             plt.plot(np.real(output))
#             plt.show()

        return np.real(output)

    def updateimg(self,base_spectrum):
        spectralimg = np.zeros((base_spectrum.size/20,base_spectrum.size/10))
        for i in np.r_[0:base_spectrum.size/10]:
            spectralimg[np.abs(np.fft.fftshift(base_spectrum)[i*10]/10),i] = 1
        cv2.imshow('spectrum',spectralimg)

    def demodulate2(self,samples):
        # DEMODULATION CODE

        # LIMITER goes here

        # low pass & down sampling
        lp_samples = signal.decimate(self.lowpass_filter(samples,16),int(self.decim_r1))


    # polar discriminator

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase = ( A * np.conj(B) )

        dphase.resize(dphase.size+1)
        dphase[dphase.size-1] = dphase[dphase.size-2]

        rebuilt = signal.medfilt(np.angle(dphase)/np.pi,15) #  np.cos(dphase)

        output = signal.decimate(rebuilt,int(self.decim_r2))

        return np.real(output)

# utility functions #

    def lowpass_filter(self,x,width):
        #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi
        wndw = np.kaiser(width,6)
        #wndw /= np.sum(wndw)
        new_array = signal.fftconvolve(x, wndw)

        return new_array[int(width/2):x.size+int(width/2)]

    # calculate mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # calculate rms for power #
    def rms(self,samples):
        meansq = np.mean(np.square(samples))
        return np.sqrt(meansq)

    def play(self,samples):
        self.stream.write( samples.astype(np.float32).tostring() )



    def start(self):
        streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        streamer.start()
        self.count = 0
        while(1):
            if not self.is_sampling:
                self.getSamplesAsync() # sampler loop
Esempio n. 12
0
  
  return (num,den);


fmDemod = FMDemod();
fileRead = FileReader();
audioPlay = AudioPlay();

dataQueue = Queue.Queue([1]);
audioQueue = Queue.Queue([1]);

sdr = RtlSdr();

# configure device
sdr.sample_rate = 250e3;  # Hz
numSampsRead = 1024*600;
freq = raw_input('Choose a station frequency: ');

try:
  freq = float(freq);
  sdr.center_freq = freq;
  sdr.gain = 'auto';
  #fileRead.start();
  fmDemod.start();
  audioPlay.start();
  sdr.read_samples_async(sdrCallback, numSampsRead);    
    
except ValueError:
  print("Invalid number");
    
Esempio n. 13
0
                        bitstr += "0"
                    else:
                        bitstr += "1"
                        if (bitCount < 6):
                            scancode += (1 << bitCount)
                    bitCount += 1
                    bitValue = 0
                    if (bitCount > 10):
                        bitCount = 0
                        state = 0  # fin demod
        except:
            exit(0)


if __name__ == "__main__":
    q = Queue()
    p = Process(target=AsyncWelchProcess, args=(q, ))
    p.start()

    def on_sample(buf, queue):
        queue.put(list(buf))

    from rtlsdr import RtlSdr

    sdr = RtlSdr()
    # configure device
    sdr.sample_rate = SAMPLE_RATE  # sample rate
    sdr.center_freq = FREQ
    sdr.gain = 'auto'
    sdr.read_samples_async(on_sample, 2048, context=q)
Esempio n. 14
0
    process(samples, rtl_sdr_obj)


parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument('--ppm', type=int, default=0, help='ppm error correction')

parser.add_argument('--gain', type=int, default=20, help='RF gain level')

parser.add_argument('--freq',
                    type=int,
                    default=92900000,
                    help='frequency to listen to, in Hertz')

parser.add_argument('--verbose', action='store_true', help='mute audio output')

args = parser.parse_args()

sdr = RtlSdr()

sdr.rs = 1024000

sdr.fc = args.freq

sdr.gain = args.gain

sdr.err_ppm = args.ppm

sdr.read_samples_async(read_callback, int(sdr.get_sample_rate()) // 16)
Esempio n. 15
0
class RtlReader(object):
    def __init__(self, **kwargs):
        super(RtlReader, self).__init__()
        self.signal_buffer = []
        self.sdr = RtlSdr()
        self.sdr.sample_rate = modes_sample_rate
        self.sdr.center_freq = modes_frequency
        self.sdr.gain = "auto"
        # sdr.freq_correction = 75

        self.debug = kwargs.get("debug", False)
        self.raw_pipe_in = None
        self.stop_flag = False

    def _process_buffer(self):
        messages = []

        # signal_array = np.array(self.signal_buffer)
        # pulses_array = np.where(np.array(self.signal_buffer) < th_amp, 0, 1)
        # pulses = "".join(str(x) for x in pulses_array)
        buffer_length = len(self.signal_buffer)

        i = 0
        while i < buffer_length:
            if self.signal_buffer[i] < th_amp:
                i += 1
                continue

            # if pulses[i : i + pbits * 2] == preamble:
            if self._check_preamble(self.signal_buffer[i : i + pbits * 2]):
                frame_start = i + pbits * 2
                frame_end = i + pbits * 2 + (fbits + 1) * 2
                frame_length = (fbits + 1) * 2
                frame_pulses = self.signal_buffer[frame_start:frame_end]

                msgbin = ""
                for j in range(0, frame_length, 2):
                    p2 = frame_pulses[j : j + 2]
                    if len(p2) < 2:
                        break

                    if p2[0] < th_amp and p2[1] < th_amp:
                        break
                    elif p2[0] >= p2[1]:
                        c = "1"
                    elif p2[0] < p2[1]:
                        c = "0"
                    else:
                        msgbin = ""
                        break
                    msgbin += c

                # advance i with a jump
                i = frame_start + j

                if len(msgbin) > 0:
                    msghex = pms.bin2hex(msgbin)
                    if self._check_msg(msghex):
                        messages.append([msghex, time.time()])
                    if self.debug:
                        self._debug_msg(msghex)

            elif i > buffer_length - 500:
                # save some for next process
                break
            else:
                i += 1

        # keep reminder of buffer for next iteration
        self.signal_buffer = self.signal_buffer[i:]
        return messages

    def _check_preamble(self, pulses):
        if len(pulses) != 16:
            return False

        for i in range(16):
            if abs(pulses[i] - preamble[i]) > th_amp_diff:
                return False

        return True

    def _check_msg(self, msg):
        df = pms.df(msg)
        msglen = len(msg)
        if df == 17 and msglen == 28:
            if pms.crc(msg) == 0:
                return True
        elif df in [20, 21] and msglen == 28:
            return True
        elif df in [4, 5, 11] and msglen == 14:
            return True

    def _debug_msg(self, msg):
        df = pms.df(msg)
        msglen = len(msg)
        if df == 17 and msglen == 28:
            print(msg, pms.icao(msg), pms.crc(msg))
        elif df in [20, 21] and msglen == 28:
            print(msg, pms.icao(msg))
        elif df in [4, 5, 11] and msglen == 14:
            print(msg, pms.icao(msg))
        else:
            # print("[*]", msg)
            pass

    def _read_callback(self, data, rtlsdr_obj):
        # scaling signal (imporatant)
        amp = np.absolute(data)
        amp_norm = np.interp(amp, (amp.min(), amp.max()), (0, 1))
        self.signal_buffer.extend(amp_norm.tolist())

        if len(self.signal_buffer) >= buffer_size:
            messages = self._process_buffer()
            self.handle_messages(messages)

    def handle_messages(self, messages):
        """re-implement this method to handle the messages"""
        for msg, t in messages:
            # print("%15.9f %s" % (t, msg))
            pass

    def stop(self, *args, **kwargs):
        self.sdr.cancel_read_async()

    def run(self, raw_pipe_in=None, stop_flag=None):
        self.raw_pipe_in = raw_pipe_in
        self.stop_flag = stop_flag
        self.sdr.read_samples_async(self._read_callback, read_size)
Esempio n. 16
0
class FMRadio(QtGui.QMainWindow,Ui_MainWindow):
    sample_buffer = Queue.Queue(maxsize=10)
    base_spectrum = np.ones(5780)

    plotOverall = True
    plotChannel = False
    plotPlaying = False
    plotWaveform = False
    useStereo = False
    stereoWidth = 10
    useMedianFilt = True
    useLPFilt = False
    demodFiltSize = 11
    useAudioFilter = True
    audioFilterSize = 16
    toDraw = True
    demodMain = True
    demodSub1 = False
    demodSub2 = False
    toDrawWaterfalls = True
    toDrawPlots = False

    prevCutoff = 0

    toPlot = (np.cumsum(np.ones(5780)),np.cumsum(np.ones(5780)))

    def __init__(self,freq,N_samples):

        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.createQtConnections()


        self.sample_rate = 2.4e5 ###1e6
        #self.decim_r1 = 1e6/2e5 # for wideband fm
        self.decim_r2 = 2.4e5/48000 # for baseband recovery
        self.center_freq = freq #+250e3
        self.gain = 38

        self.N_samples = N_samples
        self.is_sampling = False

        self.spectrogram = np.zeros((328,200))
        self.chspectrogram = np.zeros((328,200))
        self.plspectrogram = np.zeros((164,200))

        self.sdr =  RtlSdr()
        #self.sdr.direct_sampling = 1
        self.sdr.sample_rate = self.sample_rate
        self.sdr.center_freq = self.center_freq
        self.sdr.gain = self.gain

        self.pa = pyaudio.PyAudio()
        self.stream = self.pa.open( format = pyaudio.paFloat32,
                                    channels = 2,
                                    rate = 48000,
                                    output = True)

        adj = 0
        hamming = np.kaiser(self.N_samples/4 + adj,1)
        lpf = np.append( np.zeros(self.N_samples*3/8),hamming)
        self.lpf = np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*3/8))) #,int(-.25*self.N_samples))

        hamming = 10*signal.hamming(self.N_samples/16)
        lpf = np.append(np.zeros(self.N_samples*15/32),hamming)
        self.lpf_s1 = (np.append(lpf,np.zeros(int(self.N_samples*15/32))))
        #self.lpf_s1 = np.roll(temp,int(.5*self.N_samples*67/120))
        #self.lpf_s1 += np.roll(temp,int(-.5*self.N_samples*67/120))
        self.lpf_s1 = np.fft.fftshift(self.lpf_s1)
        #self.lpf_s1 += np.fft.fftshift(self.lpf_s1)

#         fig = plt.figure()
#         ax = fig.add_subplot(111)
#         ax.plot(range(self.lpf_s1.size),self.lpf_s1)
#         fig.show()

        hamming = 10*signal.hamming(self.N_samples/32)
        lpf = np.append(np.zeros(self.N_samples*31/64),hamming)
        self.lpf_s2 = (np.append(lpf,np.zeros(int(self.N_samples*31/64))))
        #self.lpf_s2 = np.roll(temp,int(.5*self.N_samples*92/120))
        #self.lpf_s2 += np.roll(temp,int(-.5*self.N_samples*92/120))
        self.lpf_s2 = np.fft.fftshift(self.lpf_s2)

    def createQtConnections(self):
        QtCore.QObject.connect(self.ui.freqSelect, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.setFreq)
        QtCore.QObject.connect(self.ui.checkBox, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.setUseStereo)
        QtCore.QObject.connect(self.ui.mainchannel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodMain)
        QtCore.QObject.connect(self.ui.subband1, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub1)
        QtCore.QObject.connect(self.ui.subband2, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub2)
        QtCore.QObject.connect(self.ui.stereoWidthSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setStereoWidth)
        QtCore.QObject.connect(self.ui.spectrum_overall, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumOverall)
        QtCore.QObject.connect(self.ui.spectrum_channel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumChannel)
        QtCore.QObject.connect(self.ui.spectrum_playing, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumPlaying)
        QtCore.QObject.connect(self.ui.spectrum_waveform, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumWaveform)
        QtCore.QObject.connect(self.ui.demodFiltMedian, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltMedian)
        QtCore.QObject.connect(self.ui.demodFiltLP, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltLP)
        QtCore.QObject.connect(self.ui.demodFilterSize, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setDemodFiltSize)
        QtCore.QObject.connect(self.ui.audioFilterActive, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setAudioFiltUse)
        QtCore.QObject.connect(self.ui.audioFilterSizeSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setAudioFiltSize)
        QtCore.QObject.connect(self.ui.exitButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.terminate)
        QtCore.QObject.connect(self.ui.drawPlot, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawSpec)
        QtCore.QObject.connect(self.ui.waterfallButton, QtCore.SIGNAL(_fromUtf8('toggled(bool)')), self.setDrawWaterfalls)
      #  QtCore.QObject.connect(self.ui.plotButton, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawPlot)

        self.bindPlot()


    def bindPlot(self):
        self.dpi = 100
        self.fig = Figure((4.31,2.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.ui.plotFrame)

        self.initplot()

        #self.anim = animation.FuncAnimation(self.fig,self.replot,interval=2000,blit=False)
        #self.canvas.mpl_connect('click_event',self.on_click_plot)


#         self.curve = QwtPlotCurve("Frequencies")
#         self.curve.setData(self.toPlot[0],self.toPlot[1]) #np.r_[-5e5:5e5:1e6/self.toPlot.size],np.abs(self.toPlot))
#         self.curve.attach(self.ui.spectrumPlot)
#         self.ui.spectrumPlot.replot()
#         #threading.Timer(1,self.replot).start()

    def initplot(self):
        self.axes = self.fig.add_subplot(111, aspect=200/431)
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        #self.axes.invert_yaxis()

    def replot(self):
       self.axes.clear()
       #self.axes.set_s
       self.axes.plot(self.toPlot[0],self.toPlot[1])
       self.axes.set_aspect('auto',anchor='C')
       self.canvas.draw()

    def setDrawSpec(self,s):
        self.toDraw = s

    def drawSpectrum(self):
        self.axes.clear()
        self.axes.imshow(self.spectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawChspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.chspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawPlspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.plspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def setDrawPlots(self,s):
        self.toDrawPlots = s
        self.toDrawWaterfalls = not s

    def setDrawWaterfalls(self,s):
        self.toDrawWaterfalls = s
        self.toDrawPlots = not s

    def setFreq(self,freq):
        freq /= 10.0
        text = "%.1f MHz" % freq
        self.ui.curFreq.setText(text)
        self.center_freq = freq*1e6 #+ 250e3
        setf_t = threading.Thread(target=self.setF_th, args=[self.center_freq,])
        setf_t.start()
        setf_t.join()

    def setF_th(self,f):
        while(self.is_sampling == True):
            pass
        self.sdr.center_freq = f

    def setUseStereo(self,u):
        self.useStereo = u
    def setStereoWidth(self,w):
        self.stereoWidth = np.sqrt(10*w)

    def setDemodMain(self,s):
        self.demodMain = s
        self.demodSub1 = not s
        self.demodSub2 = not s
        #self.useStereo = True
    def setDemodSub1(self,s):
        self.demodMain = not s
        self.demodSub1 = s
        self.demodSub2 = not s
        #self.useStereo = False
    def setDemodSub2(self,s):
        self.demodMain = not s
        self.demodSub1 = not s
        self.demodSub2 = s
        #self.useStereo = False

    def setSpectrumOverall(self,s):
        #self.initplot()
        self.plotOverall = s
        self.plotChannel = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumChannel(self,s):
        #self.initplot()
        self.plotChannel = s
        self.plotOverall = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumPlaying(self,s):
        #self.initplot()
        self.plotPlaying = s
        self.plotChannel = not s
        self.plotOverall= not s
        self.plotWaveform = not s
    def setSpectrumWaveform(self,s):
        self.plotWaveform = s
        self.plotPlaying = not s
        self.plotChannel = not s
        self.plotOverall= not s

    def setDemodFiltMedian(self,s):
        self.useMedianFilt = s
        self.useLPFilt = not s
    def setDemodFiltLP(self,s):
        self.useLPFilt = s
        self.useMedianFilt = not s
    def setDemodFiltSize(self,s):
        if(s % 2 == 0):
            s+=1
        self.demodFiltSize = s

    def setAudioFiltUse(self,s):
        self.useAudioFilter = s
    def setAudioFiltSize(self,s):
        self.audioFilterSize = s

    def terminate(self):
        self.__del__()

    def __del__(self):
        #QtGui.QMainWindow.__del__()
        #Ui_MainWindow.__del__()
        #self.streamer.stop()
        #self.sampler_t.stop()
        print "sdr closed"
        self.sdr.close()
        print "pyaudio terminated"
        self.pa.terminate()
        sys.exit()

    def getSamples(self):
        #N_samples = self.N_samples # 1/24.4 seconds   ~46336 #approximately a 2048/44100 amount's time
        return self.sdr.read_samples(self.N_samples)

    def getSamplesAsync(self):
        #Asynchronous call. Meant to be put in a loop w/ a calback fn
        #print 'gonna sample'
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)

    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
              #  print 'gottum'
            except:
                print "wtf idk no samples?"
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)

            self.play(audio_out)

        print 'gonna try to finish off the to-do list'
        sample_buffer.join()


    def demodulate(self,samples):
        # DEMODULATION CODE
        #samples = #self.sample_buffer.get()
        # LIMITER goes here

        # low pass & down sampling via fft


        spectrum = np.fft.fftshift(np.fft.fft(samples))

        self.spectrogram = np.roll(self.spectrogram, 1,axis=1)
        self.spectrogram[:,0] = np.log(np.abs(spectrum[::100]))


        if(self.toDraw and self.plotOverall and self.count % 10 == 9):

#             self.toPlot = (np.linspace(-5e5,5e5,spectrum.size),np.abs(spectrum))
#             self.replot()
            self.drawSpectrum()

        self.count += 1



            #fig = plt.figure()
            #plt.plot(np.abs(spectrum))
            #plt.show()
#
#         spectrum *= self.lpf
# # Decimate in two rounds. One to 200k, another to 44.1k
#         # DECIMATE HERE. Note that we're looking at 1MHz bandwidth.
#         n_s = spectrum.size
#
#         channel_spectrum = spectrum #.25*spectrum[int(n_s*.75-.5*n_s/self.decim_r1):int(.75*n_s+.5*n_s/self.decim_r1)] #np.append(spectrum[0:int(n_s/self.decim_r1*.5)],spectrum[n_s-int(n_s/self.decim_r1*.5):n_s])
#
#         #radio_spectrum -= np.mean(radio_spectrum) #attempt to remove dc bias
#         #print channel_spectrum.size

# #             fig = plt.figure()
# #             plt.plot(np.abs(np.fft.ifftshift(channel_spectrum)))
# #             plt.show()
#             #self.fig.plot(np.fft.ifftshift(channel_spectrum))
#
#
#         lp_samples = np.fft.ifft(np.fft.ifftshift(channel_spectrum))
#
        lp_samples = samples



      #  lp_samples /= power


    # polar discriminator



        dphase = np.zeros(lp_samples.size, dtype='complex')

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase[1:] = ( A * np.conj(B) )

        dphase[0] = lp_samples[0] * np.conj(self.prevCutoff) #dphase[dphase.size-2]
        self.prevCutoff = lp_samples[lp_samples.size-1]

#         if self.useMedianFilt:
#             rebuilt = signal.medfilt(np.angle(dphase)/np.pi,self.demodFiltSize) #  np.cos(dphase)
#         else:
#             rebuilt = self.lowpass(np.angle(dphase),self.demodFiltSize)
        rebuilt = np.angle(dphase) / np.pi
#         toplot = False
#         if toplot:
#             fig = plt.figure()
#             ax = fig.add_subplot(111)
#             ax.plot(rebuilt)

        power = np.abs(self.mad(lp_samples))
        self.ui.signalMeter.setValue(20*(np.log10(power)))

        demodMain = False
        demodSub1 = False
        demodSub2 = False
        if self.demodMain:
            demodMain = True

           # lp_samples = samples
        elif self.demodSub1:
            demodSub1 = True

            #lp_samples = samples * np.exp(-1j*2*np.pi*67650/2.4e5*np.r_[0:samples.size])
        elif self.demodSub2:
            demodSub2 = True
            #lp_samples = samples * np.exp(-1j*2*np.pi*92000/2.4e5*np.r_[0:samples.size])


        spectrum = np.fft.fft(rebuilt)


         #toplot = self.plotChannel
        self.chspectrogram = np.roll(self.chspectrogram, 1,axis=1)
        self.chspectrogram[:,0] = np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:50]))
        if(self.toDraw and self.plotChannel and self.count % 10 == 9):
            self.drawChspectrum()
             #plotspectrum = np.abs(channel_spectrum[::100])
             #self.toPlot = (np.linspace(-np.pi,np.pi,plotspectrum.size),plotspectrum)
             #self.replot()


        isStereo = False
        #demodSub1 = False
        #demodSub2 = False
        n_z = rebuilt.size
        if demodMain:

            #stereo_spectrum = spectrum
            if self.useStereo:
                isStereo = True
                #modulated = rebuilt * np.exp(-2j*np.pi*38000/2.4e5*np.r_[0:rebuilt.size])
                #h = signal.firwin(128,22000,nyq=1.2e5)
                #lp_mod = signal.fftconvolve(modulated,h,mode='same')
                #decim = lp_mod[::self.decim_r2]
                #dphase = np.zeros(decim.size, dtype='complex')
#
#                A = decim[1:decim.size]
#                B = decim[0:decim.size-1]
#
#                dphase[1:] = np.angle( A * np.conj(B) )
                #h = signal.firwin(128,22000,nyq=24000)

                #diff = dphase# [::self.decim_r2]
                mod_spectrum = np.roll(spectrum,int(.5*n_z*38000/120000))
                mod_spectrum += np.roll(spectrum,int(-.5*n_z*38000/120000)) #np.fft.fft(modulated)
                mod_spectrum *= self.lpf #np.fft.ifftshift(np.hamming(stereo_spectrum.size))
                stereo_spectrum = np.append(mod_spectrum[0:np.ceil(n_z/self.decim_r2*.5)],mod_spectrum[n_z-np.ceil(n_z/self.decim_r2*.5):n_z])
                diff = np.fft.ifft(stereo_spectrum)
            #self.base_spectrum = np.append(spectrum[0:int(n_z/self.decim_r2*.5)],spectrum[n_z-int(n_z/self.decim_r2*.5):n_z])
            #output = np.fft.ifft(self.base_spectrum)
            h = signal.firwin(128,16000,nyq=1.2e5)
            output = signal.fftconvolve(rebuilt,h,mode='same')
            output = rebuilt[::self.decim_r2]
#             h = signal.firwin(128,16000,nyq=2.4e4)
#             output = signal.fftconvolve(output,h,mode='same')
        elif demodSub1:

            demod = rebuilt * np.exp(-2j*np.pi*67650/2.4e5*np.r_[0:rebuilt.size])
         #   spectrum = np.fft.fft(demod)*self.lpf_s1
            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]
        #    base_spectrum = np.append(spectrum[0:int(.5*n_z*7500/2.4e5)],spectrum[n_z-int(.5*n_z*7500/2.4e5):n_z])
        #    decim = np.fft.ifft(base_spectrum)

            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.angle( A * np.conj(B) )
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

            #retoutput)

        elif demodSub2:
            demod = rebuilt * np.exp(-2j*np.pi*92000/2.4e5*np.r_[0:rebuilt.size])
          #  spectrum = np.fft.fft(demod)*self.lpf_s2
            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]
          #  base_spectrum = np.append(spectrum[0:int(.5*n_z*7500/2.4e5)],spectrum[n_z-int(.5*n_z*7500/2.4e5):n_z])
          #  decim = np.fft.ifft(base_spectrum)

            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.angle( A * np.conj(B) )
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

            #return np.real(output)

        output -= np.mean(output)

        stereo = np.zeros(output.size*2, dtype='complex')
        if (isStereo):
            #diff = np.fft.ifft(stereo_spectrum)
            w = self.stereoWidth  # adjust to change stereo wideness
         #print w
            left = output + w/10 * diff
            right = output - w/10 * diff

            if(self.useAudioFilter):
                left = self.lowpass(left,self.audioFilterSize)
                right = self.lowpass(right,self.audioFilterSize)

            stereo[0:stereo.size:2] = left
            stereo[1:stereo.size:2] = right
        else:
            if self.useAudioFilter:
                output = self.lowpass(output,self.audioFilterSize) # just the tip (kills the 19k pilot)
            stereo[0:stereo.size:2] = output
            stereo[1:stereo.size:2] = output


        spectrum = np.fft.fft(stereo[::2])
        self.plspectrogram = np.roll(self.plspectrogram, 1,axis=1)
        self.plspectrogram[:,0] = np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:20]))
        if(self.toDraw and self.plotPlaying): # and self.count % 2 == 0):
            if self.toDrawWaterfalls:
                self.drawPlspectrum()
            else:
                sm = np.abs(np.fft.fftshift(spectrum[::20]))
                self.toPlot = (np.linspace(-2.4e4,2.4e4,sm.size),sm)
                self.replot()


        if(self.toDraw and self.plotWaveform):
            sm = np.real(stereo[::20])
            self.toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
            self.replot()


        return np.real(stereo)


#     def updateimg(self,base_spectrum):
#         spectralimg = np.zeros((base_spectrum.size/20,base_spectrum.size/10))
#         for i in np.r_[0:base_spectrum.size/10]:
#             spectralimg[np.abs(np.fft.fftshift(base_spectrum)[i*10]/10),i] = 1
#         cv2.imshow('spectrum',spectralimg)

    def demodulate2(self,samples):
        # DEMODULATION CODE

        # LIMITER goes here

        # low pass & down sampling
        lp_samples = signal.decimate(self.lowpass_filter(samples,16),int(self.decim_r1))


    # polar discriminator

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase = ( A * np.conj(B) )

        dphase.resize(dphase.size+1)
        dphase[dphase.size-1] = dphase[dphase.size-2]

        rebuilt = signal.medfilt(np.angle(dphase)/np.pi,15) #  np.cos(dphase)

        output = signal.decimate(rebuilt,int(self.decim_r2))

        return np.real(.5*output)

# utility functions #

    def lowpass(self,x,width):
        #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi
        #wndw = np.kaiser(width,6)
        wndw = signal.firwin(16,width*990,nyq=24000)
        #wndw /= np.sum(wndw)
        new_array = signal.fftconvolve(x, wndw, mode='same')

        return new_array

    # calculate mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # calculate rms for power #
    def rms(self,samples):
        meansq = np.mean(np.square(samples))
        return np.sqrt(meansq)

    def play(self,samples):
        self.stream.write( samples.astype(np.float32).tostring() )



    def start(self):
        self.streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        self.streamer.start()
        self.count = 0
        self.sampler_t = threading.Thread(target=self.getSamplesAsync) # sampler loop
        self.sampler_t.start()
Esempio n. 17
0
  den  = np.array([1, -2*gain*np.cos(freq), (2*gain-1)]);
  
  return (num,den);


fmDemod = FMDemod();
fileRead = FileReader();
audioPlay = AudioPlay();

dataQueue = Queue.Queue([1]);
audioQueue = Queue.Queue([1]);

sdr = RtlSdr();

# configure device
sdr.sample_rate = 250e3;  # Hz
numSampsRead = 1024*600;
freq = raw_input('Choose a station frequency: ');

try:
  freq = float(freq);
  sdr.center_freq = freq;
  sdr.gain = 'auto';
  #fileRead.start();
  fmDemod.start();
  audioPlay.start();
  sdr.read_samples_async(sdrCallback, numSampsRead);    
    
except ValueError:
  print("Invalid number");
Esempio n. 18
0
            queue = mp.Queue(queue_max_size)

            print("Creating multiprocessing process")
            p = mp.Process(target=process_samples, args=(queue, ))
            p.start()

            # This code helps the decoder determine frequency offsets, etc.
            decoder.first_samples(samples, doppler=doppler)

            context_dict = {
                'sdr': sdr,
                'observer': obs,
                'sat': sat,
                'sat_name': sat_name,
            }
            sdr.read_samples_async(rtlsdr_callback, num_samples_per_recording,
                                   context_dict)
            print("Ending async RTLSDR processing")
            queue.close()
            queue.join_thread()
            p.join()

            if should_finish:
                break

        else:
            # If no satellite is overhead, find the next one that will be
            sat_detected = False
            for minute in range(0, 60 * 12):

                obs.date = ephem.now() + minute * ephem.minute
                for sat_name in active_orbcomm_satellites:
Esempio n. 19
0
sdr.center_freq = center_freq   
sdr.gain = 10

## get samples
samples = []

def callback(ss, obj):
    samples.append(ss)
    #obj.cancel_read_async()

print('Ready to record!')
raw_input("Press Enter to record...")
    
print('recording...')
N_samples = sample_rate*0.5 # approximately seconds
sdr.read_samples_async(limit_time(record_len)(callback), N_samples)   # get samples

print('recorded!')

sdr_samples = np.hstack(samples)

print('demodulating...')
ss = smart_demod(sdr_samples, sample_rate, freq_offset)
#del sdr_samples'

print('finding packets...')
packets = findPackets(ss)[0]

print('error correcting packets...')
decodes = map(lambda p: util.correct(decodePacket(p)), packets)
def stream_radio():
    sdr = RtlSdr()
    sdr.sample_rate = 2.4e6
    sdr.center_freq = 90e6
    sdr.gain = 4
    sdr.read_samples_async(async_callback)
class Receiver:
    def __init__(self, sampleRate, carrierFreq, symbolLength, frameSize):
        self.sampleRate = sampleRate
        self.carrierFreq = carrierFreq
        self.symbolLength = symbolLength
        self.frameSizeInBits = frameSize * 8 / 2
        self.headerStart = [
            0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
            1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
            1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0
        ]
        self.headerEnd = [
            1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0,
            0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0,
            0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1,
            1, 0, 0, 1, 0, 0, 0, 0, 1, 1
        ]

        self.rtl = RtlSdr()
        self.rtl.sample_rate = self.sampleRate
        self.rtl.center_freq = self.carrierFreq

        self.demodulator = Demodulator(self.carrierFreq, self.symbolLength,
                                       self.sampleRate)
        self.modulator = Modulator(self.carrierFreq, self.symbolLength,
                                   self.sampleRate)
        self.frameSync = FrameSynchronization(
            self.modulator.modulate(self.headerStart),
            self.modulator.modulate(self.headerEnd), self.symbolLength,
            self.sampleRate)
        self.timeRecover = TimingRecovery(self.symbolLength)

        self.rtlSamples = Queue()
        self.frames = Queue()
        self.previousData = Queue(1)
        self.previousData.put([0])
        self.data = Queue()

        self.threads = []
        self.threads.append(threading.Thread(target=self.receive))
        self.threads.append(threading.Thread(target=self.findFrame))
        self.threads.append(threading.Thread(target=self.processData))
        self.threads.append(threading.Thread(target=self.playSound))

        for th in self.threads:
            th.start()

    def receive(self):
        def rtl_callback(samples, rtlsdr_obj):
            self.rtlSamples.put(samples)

        self.rtl.read_samples_async(rtl_callback, self.sampleRate / 10)

    def findFrame(self):
        currentData = self.rtlSamples.get()
        prevData = self.previousData.get()
        data = np.append(prevData, currentData)

        dataPosition = self.frameSync.synchronizeStartHeader(data)
        dataEndPosition = self.frameSync.synchronizeStopHeader(
            data[dataPosition:])

        if abs(dataEndPosition -
               self.frameSizeInBits) <= self.frameSizeInBits / 10:
            print("Frame found. Size = " + str(dataEndPosition))

            self.previousData.put(data[dataPosition + dataEndPosition:])
            self.frames.put(data[dataPosition:dataPosition + dataEndPosition])
        else:
            self.previousData.put(currentData)

    def processData(self):
        data = self.frames.get()

        data = self.frameSync.correctFreqAndPhase(data)
        data = self.timeRecover.synchronizeTiming(data)
        data = self.demodulator.demodulate(data)

        self.data.put(data)

    def playSound(self):
        dataToPlay = self.data.get()
        #TODO: write func
        return
Esempio n. 22
0
class FMRadio(QtGui.QMainWindow,Ui_MainWindow):
    sample_buffer = Queue.Queue(maxsize=10)
    base_spectrum = np.ones(5780)

    plotOverall = True
    plotChannel = False
    plotPlaying = False
    plotWaveform = False
    useStereo = False
    stereoWidth = 10
    useMedianFilt = True
    useLPFilt = True
    demodFiltSize = 100000
    useAudioFilter = True
    audioFilterSize = 16
    toDraw = True
    demodMain = True
    demodSub1 = False
    demodSub2 = False
    toDrawWaterfalls = True
    toDrawPlots = False

    prevCutoff = 0
    prevSpec1 = np.zeros(128)
    prevSpec2 = np.zeros(128)
    prevSpec3 = np.zeros(128)
    prevConvo1 = np.zeros(128)
    prevConvo2 = np.zeros(128,dtype='complex')

    limiterMax = np.zeros(32)

    toPlot = (np.cumsum(np.ones(5780)),np.cumsum(np.ones(5780)))

    def __init__(self,freq,N_samples):
        self.spectrogram = np.zeros((512,400))
        self.chspectrogram = np.zeros((512,400))
        self.plspectrogram = np.zeros((256,400))
        self.cur_spectrogram = self.spectrogram


        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.createQtConnections()
        ftxt = "%.1f MHz" % (freq/1e6)
        self.ui.curFreq.setText(ftxt)

        self.sample_rate = 2.4e5 # tried 1.024e6 - not so great
        self.decim_r1 = 1 # 1.024e6/2.4e5 # for wideband fm down from sample_rate
        self.decim_r2 = 2.4e5/48000 # for baseband recovery
        self.center_freq = freq #+250e3
        self.gain = 16

        self.N_samples = N_samples
        self.is_sampling = False



        self.sdr =  RtlSdr()
        #self.sdr.direct_sampling = 1
        self.sdr.sample_rate = self.sample_rate
        self.sdr.center_freq = self.center_freq
        self.sdr.gain = self.gain

        self.pa = pyaudio.PyAudio()
        self.stream = self.pa.open( format = pyaudio.paFloat32,
                                    channels = 2,
                                    rate = 48000,
                                    output = True)

        self.PLL = PhaseLockedLoop(self.N_samples,19000,self.sample_rate)

        self.initOpenCV()

        self.noisefilt = np.ones(6554)
        b,a = signal.butter(1, 2122/48000*2*np.pi, btype='low')
        self.demph_zf = signal.lfilter_zi(b, a)

        adj = 0
        hamming = np.kaiser(self.N_samples/4 + adj,1)
        lpf = np.append( np.zeros(self.N_samples*3/8),hamming)
        self.lpf = np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*3/8))) #,int(-.25*self.N_samples))

        hamming = 10*signal.hamming(self.N_samples/16)
        lpf = np.append(np.zeros(self.N_samples*15/32),hamming)
        self.lpf_s1 = (np.append(lpf,np.zeros(int(self.N_samples*15/32))))
        #self.lpf_s1 = np.roll(temp,int(.5*self.N_samples*67/120))
        #self.lpf_s1 += np.roll(temp,int(-.5*self.N_samples*67/120))
        self.lpf_s1 = np.fft.fftshift(self.lpf_s1)
        #self.lpf_s1 += np.fft.fftshift(self.lpf_s1)

#         fig = plt.figure()
#         ax = fig.add_subplot(111)
#         ax.plot(range(self.lpf_s1.size),self.lpf_s1)
#         fig.show()

        hamming = 10*signal.hamming(self.N_samples/32)
        lpf = np.append(np.zeros(self.N_samples*31/64),hamming)
        self.lpf_s2 = (np.append(lpf,np.zeros(int(self.N_samples*31/64))))
        #self.lpf_s2 = np.roll(temp,int(.5*self.N_samples*92/120))
        #self.lpf_s2 += np.roll(temp,int(-.5*self.N_samples*92/120))
        self.lpf_s2 = np.fft.fftshift(self.lpf_s2)

    # Not currently used
    def getSamples(self):
        return self.sdr.read_samples(self.N_samples);

    def getSamplesAsync(self):
        #Asynchronous call. Initiates a continuous loop with the callback fn
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)
    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        # Initiates a loop to process all the incoming blocks of samples from the Queue
        # This should be run in its own thread, or the program will become unresponsive
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
            except:
                #print "wtf idk no samples?"  # even though this can't happen... (although I'm not sure why not)
                #print 'gonna try to finish off the to-do list'
                #self.sample_buffer.join()
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)
            self.play(audio_out)

    def gen_spectrogram(self,x,m,prevSpec):
        itsreal = np.isreal(x[0])

        m = int(m)
        lx = x.size
        nt = (lx) // m
        #NT = (lx +m -1)//m
        #padsize = NT*m -lx
        cutsize = lx -nt*m
        padsize = int(cutsize + m/2)


        if not prevSpec.size == padsize:
            prevSpec = np.zeros(padsize)

        xp = np.append(x[cutsize:],prevSpec)
        prevSpec = x[:(padsize)]

        xh = np.zeros((m,nt*2), dtype='complex')
        for n in range(int(nt*2)):
            block = xp[m*n//2:m*(n+2)//2]

            xh[:,n] = block*np.hanning(block.size)


        #if self.prevSpec.size == padsize:
        #    xb = np.append(self.prevSpec[:prevSpec.size-m/2],x)
        #    xc = np.append(self.prevSpec,x[:lx-m/2])
        #    self.prevSpec = x[lx-m/2:]
        #else:

        #    xb = np.append(x,np.zeros(-lx+nt*m))
        #    xc = np.append(x[m/2:],np.zeros(nt*m - lx + m/2))


        #xr = np.reshape(xb, (m,nt), order='F') * np.outer(np.hanning(m),np.ones(nt))
        #xs = np.reshape(xc, (m,nt), order='F') * np.outer(np.hanning(m),np.ones(nt))

        #xm = np.zeros((m,2*nt),dtype='complex')
        #xm[:,::2] = xr
        #xm[:,1::2] = xs

        if itsreal:
            spec = np.fft.fft(xh,m,axis=0)
            spec = spec[:m//2,:]
        else:
            spec = np.fft.fftshift(np.fft.fft(xh,m,axis=0))
        #mx = np.max(spec)

        pwr = np.log(np.abs(spec) + 1e-6)

        return (np.real(pwr),prevSpec)

    def initOpenCV(self):
        cv2.namedWindow("Spectrogram")

    def demodulate(self,samples):
        # DEMODULATION CODE - And the core function
        # samples must be passed in by the caller
        self.count += 1

        #spectral_window = signal.hanning

        #spectrum = np.fft.fftshift(np.fft.fft(samples*spectral_window(samples.size)))

        self.spectrogram = np.roll(self.spectrogram, 16,axis=1)
        stft,self.prevSpec1 = self.gen_spectrogram(samples,samples.size//8,self.prevSpec1)
        self.spectrogram[:,:16] = stft[::8,:]     # np.log(np.abs(spectrum[::100]))

        if(self.plotOverall): # and self.count % 10 == 9):
            #self.drawSpectrum()
            self.cur_spectrogram = self.spectrogram
            self.drawCurSpectrum()

#         cutoff = self.demodFiltSize
#         h = signal.firwin(128, cutoff,nyq=self.sample_rate/2)
#         lp = signal.fftconvolve(samples[::self.decim_r1],h,mode='full')
#         lps = lp.size
#         hs = h.size
#         prev = lp[lps-hs:]
#         lp[:hs/2] += self.prevConvo2[hs/2:]
#         lp = np.append(self.prevConvo2[:hs/2],lp)
#         self.prevConvo2 = prev
#         lp_samples = lp[:lps-hs+1]
        lp_samples = samples

        power = np.abs(self.mad(lp_samples))
        self.ui.signalMeter.setValue(20*(np.log10(power)))


    # polar discriminator

        dphase = np.zeros(lp_samples.size, dtype='complex')

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase[1:] = ( A * np.conj(B) )

        dphase[0] = lp_samples[0] * np.conj(self.prevCutoff) #dphase[dphase.size-2]
        self.prevCutoff = lp_samples[lp_samples.size-1]

    # limiting

        dphase /= np.abs(dphase)

#         if self.useMedianFilt:
#             rebuilt = signal.medfilt(np.angle(dphase)/np.pi,self.demodFiltSize) #  np.cos(dphase)
#         else:
#             rebuilt = self.lowpass(np.angle(dphase),self.demodFiltSize)

        rebuilt = np.real(np.angle(dphase) / np.pi)



        demodMain = False
        demodSub1 = False
        demodSub2 = False
        isStereo = False
        if self.demodMain:
            demodMain = True
            if self.useStereo:
                isStereo = True
        elif self.demodSub1:
            demodSub1 = True
        elif self.demodSub2:
            demodSub2 = True

        #spectrum = np.fft.fft(rebuilt* spectral_window(rebuilt.size))
        #print rebuilt.size/8
        self.chspectrogram = np.roll(self.chspectrogram, 16,axis=1)
        stft,self.prevSpec2 = self.gen_spectrogram(rebuilt,rebuilt.size/8,self.prevSpec2)
        self.chspectrogram[:,:16] = stft[::-4,:]                          # np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:50]))
        if(self.plotChannel):# and self.count % 10 == 9):
            self.cur_spectrogram = self.chspectrogram
            self.drawCurSpectrum()
             #plotspectrum = np.abs(channel_spectrum[::100])
             #self.toPlot = (np.linspace(-np.pi,np.pi,plotspectrum.size),plotspectrum)
             #self.replot()


        n_z = rebuilt.size
        if demodMain:

            h = signal.firwin(128,16000,nyq=1.2e5)
            output = signal.fftconvolve(rebuilt,h,mode='full')
            outputa = output    # could be done in place but I'm not concerned with memory

            outputa[:h.size/2] += self.prevConvo1[h.size/2:]   #add the latter half of tail end of the previous convolution
            outputa = np.append(self.prevConvo1[:h.size/2], outputa) # also delayed by half size of h so append the first half

            self.prevConvo1 = output[output.size-h.size:]   # set the tail for next iteration

            output = outputa[:output.size-h.size:self.decim_r2]  # chop off the tail and decimate


            #stereo_spectrum = spectrum
            if isStereo:

                #pilot = rebuilt * np.cos(2*np.pi*19/240*(np.r_[0:rebuilt.size]))
                h = signal.firwin(512,[18000,20000],pass_zero=False,nyq=1.2e5)
                pilot_actual = signal.fftconvolve(rebuilt,h,mode='same')
                self.PLL.adjust(pilot_actual)


                moddif = rebuilt * np.real(np.square(self.PLL.pll)) #np.cos(2*np.pi*38/240*(np.r_[0:ss] - phase_shift))
                h = signal.firwin(128,16000,nyq=1.2e5)
                moddif = signal.fftconvolve(moddif,h,mode='same')

                h = signal.firwin(64,16000,nyq=48000/2)
                diff = signal.fftconvolve(moddif[::self.decim_r2],h,mode='same')
                diff = np.real(diff)
#                 rdbs = rebuilt * np.power(self.PLL.pll,3)
#                 h = signal.hanning(1024)
#                 rdbs = signal.fftconvolve(rdbs,h)
#                 if np.mean(rdbs) > 0:
#                     # bit ONE
#                 else:
#                     # bit ZERO

        elif demodSub1:


            demod = rebuilt * np.exp(-2j*np.pi*67650/2.4e5*np.r_[0:rebuilt.size])

            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]


            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.real(np.angle( A * np.conj(B) ))
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')


        elif demodSub2:
            demod = rebuilt * np.exp(-2j*np.pi*92000/2.4e5*np.r_[0:rebuilt.size])

            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]


            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.real(np.angle( A * np.conj(B) ))
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

        # DC block filter, lol, srsly
        output = np.real(output) - np.mean(np.real(output))

        if np.isnan(output[0]):
            #print "error" # for some reason, output is NaN for the first 2 loops
            return np.zeros(6554)

        # deemphasis - # 2122/samplerate*2 *pi  - butterworth filter
        b,a = signal.butter(1, 2122/48000*2*np.pi, btype='low')
        output, zf = signal.lfilter(b, a, output,zi=self.demph_zf)
        self.demph_zf = zf

        stereo = np.zeros(output.size*2)
        if (isStereo):

            diff = signal.lfilter(b,a,diff)
            w = self.stereoWidth  # adjust to change stereo wideness
            left = output + w/10 * diff
            right = output - w/10 * diff

            if(self.useAudioFilter):
                left = self.lowpass(left,self.audioFilterSize)
                right = self.lowpass(right,self.audioFilterSize)

            stereo[0:stereo.size:2] = left
            stereo[1:stereo.size:2] = right
        else:
            if self.useAudioFilter:
                output = self.lowpass(output,self.audioFilterSize) # just the tip (kills the 19k pilot)
            stereo[0:stereo.size:2] = output
            stereo[1:stereo.size:2] = output

        #normalize to avoid any possible clipping when playing
        stereo /= 2*np.max(stereo)
        #spectrum = np.fft.fft(stereo[::2])
        output = .5*(stereo[::2]+stereo[1::2])

        #spectrum = np.fft.fft(.5*(stereo[::2]+stereo[1::2])*spectral_window(output.size))
        self.plspectrogram = np.roll(self.plspectrogram, 24,axis=1)
        stft,self.prevSpec3 = self.gen_spectrogram(output,512,self.prevSpec3)
        self.plspectrogram[:,:24] = stft[::-1,:]  # np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:20]))
        if(self.plotPlaying): # and self.count % 2 == 0):
            #if self.toDrawWaterfalls:
            self.cur_spectrogram = self.plspectrogram
            self.drawCurSpectrum(invert=True)

                #self.drawPlspectrum()
            #else:

            #    sm = np.abs(np.fft.fftshift(spectrum[::20]))
            #    toPlot = (np.linspace(-2.4e4,2.4e4,sm.size),sm)
            #    self.replot(toPlot)


        #if(self.toDraw and self.plotWaveform):
        #    if self.toDrawWaterfalls:
        #        sm = np.real(output[::20])
        #        toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
        #        self.replot(toPlot)
        #    else:
        #        sm = np.real(self.PLL.pll[::200])
        #        toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
        #        self.replot(toPlot)

        return np.real(stereo)


    # Alternate demodulator. Not used, but extremely simple
    def demodulate2(self,samples):
        # DEMODULATION CODE

        # LIMITER goes here

        # low pass & down sampling
        h = signal.firwin(128,80000,nyq=1.2e5)
        lp_samples = signal.fftconvolve(samples, h)

    # polar discriminator

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase = ( A * np.conj(B) ) / np.pi

        dphase.resize(dphase.size+1)
        dphase[dphase.size-1] = dphase[dphase.size-2]

        h = signal.firwin(128,16000,nyq=1.2e5)
        rebuilt = signal.fftconvolve(dphase,h)

        output = rebuilt[::self.decim_r2]

        output = self.lowpass(output, self.audioFilterSize)

        return np.real(output)

# utility functions #

    def lowpass(self,x,width):
        #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi
        #wndw = np.kaiser(width,6)
        wndw = signal.firwin(16,width*999,nyq=24000)
        #wndw /= np.sum(wndw)
        new_array = signal.fftconvolve(x, wndw, mode='same')

        return new_array

    # calculate mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # calculate rms for power #
    def rms(self,samples):
        meansq = np.mean(np.square(samples))
        return np.sqrt(meansq)

    def play(self,samples):
        self.stream.write( samples.astype(np.float32).tostring() )


    # starting point
    def start(self):
        # Initiates running things
        self.streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        self.streamer.start()
        self.count = 0
        self.sampler_t = threading.Thread(target=self.getSamplesAsync) # sampler loop
        self.sampler_t.start()


    def createQtConnections(self):

        QtCore.QObject.connect(self.ui.freqSelect, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.setFreq)
        QtCore.QObject.connect(self.ui.checkBox, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.setUseStereo)
        QtCore.QObject.connect(self.ui.mainchannel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodMain)
        QtCore.QObject.connect(self.ui.subband1, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub1)
        QtCore.QObject.connect(self.ui.subband2, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub2)
        QtCore.QObject.connect(self.ui.stereoWidthSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setStereoWidth)
        QtCore.QObject.connect(self.ui.spectrum_overall, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumOverall)
        QtCore.QObject.connect(self.ui.spectrum_channel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumChannel)
        QtCore.QObject.connect(self.ui.spectrum_playing, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumPlaying)
        QtCore.QObject.connect(self.ui.spectrum_waveform, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumWaveform)
        QtCore.QObject.connect(self.ui.demodFiltMedian, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltMedian)
        QtCore.QObject.connect(self.ui.demodFiltLP, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltLP)
        QtCore.QObject.connect(self.ui.demodFilterSize, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setDemodFiltSize)
        QtCore.QObject.connect(self.ui.audioFilterActive, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setAudioFiltUse)
        QtCore.QObject.connect(self.ui.audioFilterSizeSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setAudioFiltSize)
        QtCore.QObject.connect(self.ui.exitButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.terminate)
        QtCore.QObject.connect(self.ui.drawPlot, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawSpec)
        QtCore.QObject.connect(self.ui.waterfallButton, QtCore.SIGNAL(_fromUtf8('toggled(bool)')), self.setDrawWaterfalls)
      #  QtCore.QObject.connect(self.ui.plotButton, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawPlot)

        self.bindPlot()


    def bindPlot(self):
        self.dpi = 100
        self.fig = Figure((4.31,2.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.ui.plotFrame)

        self.initplot()


    def initplot(self):
        self.axes = self.fig.add_subplot(111, aspect=200/431)
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.fig.tight_layout()
        #self.axes.invert_yaxis()

        #self.anim = animation.FuncAnimation(self.fig,self.drawCurSpectrum,interval=750)


    def replot(self,toPlot):
        self.axes.clear()
        self.axes.plot(toPlot[0],toPlot[1])
        self.axes.set_aspect('auto',anchor='C')
        self.canvas.draw()

    def setDrawSpec(self,s):
        self.toDraw = s

    def drawCurSpectrum(self,invert=False):
        #self.axes.clear()
        #self.axes.imshow(self.cur_spectrogram, cmap='spectral')
        #self.axes.xaxis.set_major_locator(ticker.NullLocator())
        #self.axes.yaxis.set_major_locator(ticker.NullLocator())
        #self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        #self.canvas.draw()
        mx = np.max(self.cur_spectrogram)
        mn = np.min(self.cur_spectrogram)
        if invert:
            self.cur_spectrogram = -cv2.convertScaleAbs(self.cur_spectrogram,alpha=255 / (mx))
        else:
            self.cur_spectrogram = cv2.convertScaleAbs(self.cur_spectrogram,alpha=255 / (mn))
        self.cur_spectrogram = cv2.GaussianBlur(self.cur_spectrogram,(5,5),.6)
        cmapped =cv2.applyColorMap(self.cur_spectrogram,cv2.COLORMAP_JET)
        cv2.imshow('Spectrogram',cmapped)
        cv2.waitKey(1);

    def drawSpectrum(self):
        self.axes.clear()
        self.axes.imshow(self.spectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawChspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.chspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawPlspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.plspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def setDrawPlots(self,s):

        self.toDrawPlots = s
        self.toDrawWaterfalls = not s

    def setDrawWaterfalls(self,s):

        self.toDrawWaterfalls = s
        self.toDrawPlots = not s

    def setFreq(self,freq):
        if freq % 2 == 0:
            freq += 1
        freq /= 10.0
        text = "%.1f MHz" % freq
        self.ui.curFreq.setText(text)
        self.center_freq = freq*1e6 #+ 250e3
        setf_t = threading.Thread(target=self.setF_th, args=[self.center_freq,])
        setf_t.start()
        setf_t.join()



    # This function is what is used to adjust the tuner on the RTL
    # Currently, it causes the program to crash if used after an unspecified period of inactivity
    #     commented lines are attempts that didn't work
    def setF_th(self,f):
        while(self.is_sampling == True):
            pass
        #self.sdr.cancel_read_async()
        time.sleep(.1)
        self.sdr.center_freq = f
        #self.getSamplesAsync()

    def setUseStereo(self,u):
        self.useStereo = u
    def setStereoWidth(self,w):
        self.stereoWidth = w/5

    def setDemodMain(self,s):
        self.demodMain = s
        self.demodSub1 = not s
        self.demodSub2 = not s
        #self.useStereo = True
    def setDemodSub1(self,s):
        self.demodMain = not s
        self.demodSub1 = s
        self.demodSub2 = not s
        #self.useStereo = False
    def setDemodSub2(self,s):
        self.demodMain = not s
        self.demodSub1 = not s
        self.demodSub2 = s
        #self.useStereo = False

    def setSpectrumOverall(self,s):
        #self.initplot()
        #self.cur_spectrogram = self.spectrogram
        self.plotOverall = s
        self.plotChannel = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumChannel(self,s):
        #self.initplot()
        self.plotChannel = s
        self.plotOverall = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumPlaying(self,s):
        #self.initplot()
        self.plotPlaying = s
        self.plotChannel = not s
        self.plotOverall= not s
        self.plotWaveform = not s
    def setSpectrumWaveform(self,s):
        self.plotWaveform = s
        self.plotPlaying = not s
        self.plotChannel = not s
        self.plotOverall= not s

    def setDemodFiltMedian(self,s):
        self.useMedianFilt = s
        self.useLPFilt = not s
    def setDemodFiltLP(self,s):
        self.useLPFilt = s
        self.useMedianFilt = not s
    def setDemodFiltSize(self,s):
        #if(s % 2 == 0):
        #    s+=1
        self.demodFiltSize = s

    def setAudioFiltUse(self,s):
        self.useAudioFilter = s
    def setAudioFiltSize(self,s):
        self.audioFilterSize = s

    def terminate(self):
        self.__del__()

    # Destructor - also used to exit the program when user clicks "Quit"
    def __del__(self):

        # Program will continue running in the background unless the RTL is told to stop sampling
        self.sdr.cancel_read_async()
        print "sdr closed"
        self.sdr.close()
        print "pyaudio terminated"
        self.pa.terminate()
        cv2.destroyAllWindows()
Esempio n. 23
0
def run_total_power_int(num_samp, gain, rate, fc, t_int):
    '''
    Implement a total-power radiometer. Raw, uncalibrated power values.

    Inputs:
    num_samp:   Number of elements to sample from the SDR IQ timeseries per call
    gain:       Requested SDR gain (dB)
    rate:       SDR sample rate, intrinsically tied to bandwidth in SDRs (Hz)
    fc:         Bandpass center frequency (Hz)
    t_int:      Total integration time (s)

    Returns:
    p_tot:   Time-averaged power in the signal from the sdr, in 
             uncalibrated units
    '''
    import rtlsdr.helpers as helpers

    # Start the RtlSdr instance
    print('Initializing rtl-sdr with pyrtlsdr:')
    sdr = RtlSdr()

    try:
        sdr.rs = rate
        sdr.fc = fc
        sdr.gain = gain
        print('  sample rate: {} MHz'.format(sdr.rs / 1e6))
        print('  center frequency {} MHz'.format(sdr.fc / 1e6))
        print('  gain: {} dB'.format(sdr.gain))
        print('  num samples per call: {}'.format(num_samp))
        print('  requested integration time: {}s'.format(t_int))
        # For Nyquist sampling of the passband dv over an integration time
        # tau, we must collect N = 2 * dv * tau real samples.
        # https://www.cv.nrao.edu/~sransom/web/A1.html#S3
        # Because the SDR collects complex samples at a rate rs = dv, we can
        # Nyquist sample a signal of band-limited noise dv with only rs * tau
        # complex samples.
        # The phase content of IQ samples allows the bandlimited signal to be
        # Nyquist sampled at a data rate of rs = dv complex samples per second
        # rather than the 2* dv required of real samples.
        N = int(sdr.rs * t_int)
        print('  => num samples to collect: {}'.format(N))
        print('  => est. num of calls: {}'.format(int(N / num_samp)))

        global p_tot
        global cnt
        p_tot = 0.0
        cnt = 0

        # Set the baseline time
        start_time = time.time()
        print('Integration began at {}'.format(
            time.strftime('%a, %d %b %Y %H:%M:%S',
                          time.localtime(start_time))))

        # Time integration loop
        @helpers.limit_calls(N / num_samp)
        def p_tot_callback(iq, context):
            # The below is a total power measurement equivalent to summing
            # P = V^2 / R = (sqrt(I^2 + Q^2))^2 = (I^2 + Q^2)
            global p_tot
            p_tot += np.sum(np.real(iq * np.conj(iq)))
            global cnt
            cnt += 1

        sdr.read_samples_async(p_tot_callback, num_samples=num_samp)

        end_time = time.time()
        print('Integration ended at {} after {} seconds.'.format(
            time.strftime('%a, %d %b %Y %H:%M:%S'), end_time - start_time))
        print('{} calls were made to SDR.'.format(cnt))
        print('{} samples were measured at {} MHz'.format(
            cnt * num_samp, fc / 1e6))
        print('for an effective integration time of {:.2f}s'.format(
            (num_samp * cnt) / rate))

        # Compute the average power value based on the number of measurements
        # we actually did
        p_avg = p_tot / (num_samp * cnt)

        # nice and tidy
        sdr.close()

    except OSError as err:
        print("OS error: {0}".format(err))
        raise (err)
    except:
        print('Unexpected error:', sys.exc_info()[0])
        raise
    finally:
        sdr.close()

    return p_avg
Esempio n. 24
0
class RtlReceiver(Process):
    """Set up and receive data from RTLSDR.
    """
    def __init__(self,
                 sample_rate,
                 center_freq,
                 gain,
                 ppm,
                 sdr_out_A,
                 sdr_out_B,
                 decimate,
                 satellite=False):
        super(RtlReceiver, self).__init__()

        self.sample_rate = sample_rate
        self.center_freq = center_freq
        self.gain = gain
        self.freq_correction = ppm
        self.async_sample_size = 1024 * 24  #default 1024
        self.sdr_out_A = sdr_out_A
        self.sdr_out_B = sdr_out_B
        self.decimate = decimate

        if satellite:
            # Channel 75
            self.freq_shift_A = self.center_freq - 156.775 * 1e6
            # Channel 76
            self.freq_shift_B = self.center_freq - 156.825 * 1e6
        else:
            # Channel 88B
            self.freq_shift_A = self.center_freq - 162.025 * 1e6
            # Channel 87B
            self.freq_shift_B = self.center_freq - 161.975 * 1e6

        print("Frequency shift A: {}MHz".format(self.freq_shift_A / 1e6))
        print("Frequency shift B: {}MHz".format(self.freq_shift_B / 1e6))

        self.fc1_A = np.exp(1.0j * 2.0 * np.pi * self.freq_shift_A /
                            self.sample_rate *
                            np.arange(self.async_sample_size))
        self.fc1_B = np.exp(1.0j * 2.0 * np.pi * self.freq_shift_B /
                            self.sample_rate *
                            np.arange(self.async_sample_size))

    def send_samples(self, samples, rtl):
        #shift frequency, filter, detect phase, and send

        if len(samples) == self.async_sample_size:
            pass
        else:
            pad = np.zeros(self.async_sample_size - len(samples))
            samples = np.append(samples, pad)
            print("Samples padded: {}".format(len(pad)))

        #Frequency shift
        shifted_A = samples * self.fc1_A
        shifted_B = samples * self.fc1_B

        self.sdr_out_A.send(shifted_A)
        self.sdr_out_B.send(shifted_B)

    def run(self):
        #Import here so that a working RtlSdr isn't required to work with recordings
        from rtlsdr import RtlSdr, RtlSdrTcpClient

        self.sdr = RtlSdr()
        #self.sdr = RtlSdrTcpClient(hostname='192.168.0.6', port=1234)

        # configure device
        self.sdr.center_freq = self.center_freq
        self.sdr.sample_rate = self.sample_rate
        self.sdr.gain = self.gain
        if self.freq_correction != 0:
            self.sdr.freq_correction = self.freq_correction

        #try for some extra filtering
        try:
            #self.sdr.bandwidth = (.350 * 1e6)
            pass
        except IOError:
            print("No bandwidth adjustment availible.")

        print("SDR Frequency: {}MHz".format(self.sdr.get_center_freq() / 1e6))
        print("SDR Sample Rate: {}MS/s".format(self.sdr.get_sample_rate() /
                                               1e6))

        self.sdr.read_samples_async(self.send_samples, self.async_sample_size)

        print("Radio closing...")
Esempio n. 25
0
                        bitstr += "0"
                    else:
                        bitstr += "1"
                        if bitCount < 6:
                            scancode += 1 << bitCount
                    bitCount += 1
                    bitValue = 0
                    if bitCount > 10:
                        bitCount = 0
                        state = 0  # fin demod
        except:
            exit(0)


if __name__ == "__main__":
    q = Queue()
    p = Process(target=AsyncWelchProcess, args=(q,))
    p.start()

    def on_sample(buf, queue):
        queue.put(list(buf))

    from rtlsdr import RtlSdr

    sdr = RtlSdr()
    # configure device
    sdr.sample_rate = SAMPLE_RATE  # sample rate
    sdr.center_freq = FREQ
    sdr.gain = "auto"
    sdr.read_samples_async(on_sample, 2048, context=q)
Esempio n. 26
0
            print "Number of loops =", numberofloops
            #s.close();
            global book_index
            global chart
            global sheet1
            chart.add_series({
                'name': '=Sheet1!$B$1',
                'categories': '=Sheet1!$E$2:$E$120',
                'values': '=Sheet1!$B$2:$B$120',
            })
            # Set an Excel chart style. Colors with white outline and shadow.
            chart.set_style(10)

            # Insert the chart into the worksheet (with an offset).
            sheet1.insert_chart('G2', chart, {'x_offset': 25, 'y_offset': 10})
            sys.exit(0)

        signal.signal(signal.SIGINT, signal_handler)

        # - - - - - - - - - - - Calling the sending function - - - - - - -#

        sdr.read_samples_async(process_send)
############################################################################################
    time.sleep(3600)
    for key, mask in mysel.select(timeout=1):
        callback = key.data
        callback(key.fileobj, mask)

print('shutting down')
mysel.close()
Esempio n. 27
0
class RadioReceiver:
    def __init__(self,
                 center_freq=446.1e6,
                 sample_rate=250e3,
                 freq_correction=0,
                 buffer_size=2048,
                 device_index=0):
        self._registeredQueueList = list()
        self._registeredQueueListLock = threading.Lock()
        self._sdr = RtlSdr(device_index)
        self._sdr.sample_rate = sample_rate
        self._sdr.center_freq = center_freq
        if self._sdr.freq_correction != freq_correction:
            self._sdr.freq_correction = freq_correction
        self._thread = threading.Thread(target=self._read_thread,
                                        args=(buffer_size, ))
        self._thread.start()

    @property
    def sample_rate(self):
        return self._sdr.sample_rate

    @sample_rate.setter
    def sample_rate(self, value):
        self._sdr.sample_rate = value

    @property
    def center_freq(self):
        return self._sdr.center_freq

    @center_freq.setter
    def center_freq(self, value):
        self._sdr.center_freq = value

    @property
    def freq_correction(self):
        return self._sdr.sample_rate

    @freq_correction.setter
    def freq_correction(self, value):
        if self._sdr.freq_correction != value:
            self._sdr.freq_correction = value

    def registerQueue(self, q: queue):
        with self._registeredQueueListLock:
            self._registeredQueueList.append(q)

    def unregisterQueue(self, q: queue):
        with self._registeredQueueListLock:
            if q in self._registeredQueueList:
                self._registeredQueueList.remove(q)

    @staticmethod
    def _read_samples_callback(buffer, self):
        with self._registeredQueueListLock:
            for q in self._registeredQueueList:
                if q.full():
                    q.get_nowait()
                q.put_nowait(buffer)

    def _read_thread(self, buffer_size):
        try:
            self._sdr.read_samples_async(RadioReceiver._read_samples_callback,
                                         buffer_size, self)
        except IOError:  #IOError is raised when read_async is canceled
            pass

    def close(self):
        self._sdr.cancel_read_async()
        self._thread.join()
        with self._registeredQueueListLock:
            for q in self._registeredQueueList:
                if q.full():
                    q.get_nowait()
                q.put_nowait(None)