├── README ├── sweep.py ├── example.py └── rtlsdr ├── __init__.py └── _librtlsdr.py /README: -------------------------------------------------------------------------------- 1 | **** WARNING: These bindings are several years out of date. The librtlsdr library has almost certainly chained it's API enough to make them broken out of the box. 2 | 3 | 4 | Some simple ctypes python bindings for librtlsdr 5 | 6 | First, get and install librtlsdr from http://sdr.osmocom.org/trac/wiki/rtl-sdr 7 | 8 | This does nothing but wrap librtlsdr 9 | 10 | librtlsdr.so should be in your library path. It's a good idea if you 11 | make sure that the rtlsdr binary that comes with it works before you 12 | try this. 13 | 14 | I haven't tested this with windows. Theoretically it should work with 15 | librtlsdr compiled as a DLL 16 | 17 | -- David Basden 18 | -------------------------------------------------------------------------------- /sweep.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | from rtlsdr import RtlSDR 4 | import sys 5 | 6 | if __name__ == "__main__": 7 | 8 | if len(sys.argv) < 2: 9 | print >> sys.stderr, sys.argv[0], "" 10 | sys.exit(1) 11 | 12 | if RtlSDR.get_device_count() < 1: 13 | raise IOError("No known devices found") 14 | 15 | s = RtlSDR(0, 105700000, 1024000) 16 | 17 | outf = open(sys.argv[1], "w") 18 | #s.reset_buffer() # Must do before first read 19 | 20 | try: 21 | for n in range(500,10000,5): 22 | n = n *.1 23 | print >> sys.stderr, n,"MHz", 24 | s.frequency = int(n * 10**6) 25 | s.reset_buffer() 26 | for c in xrange(3): 27 | outf.write(s.read()) 28 | except KeyboardInterrupt: 29 | pass 30 | finally: 31 | outf.close() 32 | s.close() 33 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | from rtlsdr import RtlSDR 4 | import sys 5 | 6 | if __name__ == "__main__": 7 | 8 | if len(sys.argv) < 2: 9 | print >> sys.stderr, sys.argv[0], "" 10 | sys.exit(1) 11 | 12 | if RtlSDR.get_device_count() < 1: 13 | raise IOError("No known devices found") 14 | 15 | s = RtlSDR(0, 105700000, 1024000) 16 | 17 | # This is actually a property that changes the frequency 18 | s.frequency = 54000000 19 | s.frequency = 927000000 20 | s.frequency = 435012000 21 | s.frequency = 145125000 22 | s.frequency = 130100000 23 | s.frequency = 105700000 24 | 25 | s.reset_buffer() # Must do before first read 26 | buf = s.read() 27 | outf = open(sys.argv[1], "w") 28 | 29 | try: 30 | while True: 31 | outf.write(s.read()) 32 | except KeyboardInterrupt: 33 | pass 34 | finally: 35 | outf.close() 36 | s.close() 37 | -------------------------------------------------------------------------------- /rtlsdr/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import _librtlsdr as sdr 4 | import ctypes 5 | from ctypes import pointer 6 | import sys 7 | 8 | class RtlSDR(object): 9 | READ_SIZE = 16 * 16384 10 | 11 | def __init__(self, device_index=0, center_frequency=105400000, sample_rate=1024000, tuner_gain=0): 12 | '''initialise the rtlsdr device and tune to initial frequency 13 | ''' 14 | self.dev = sdr.rtlsdr_dev_t() 15 | self.devp = pointer(self.dev) 16 | self.devidx = device_index 17 | 18 | if sdr.rtlsdr_open(self.devp, device_index) < 0: 19 | raise IOError("Couldn't open sdr device index %d" % (device_index,) ) 20 | print >> sys.stderr, "Using", sdr.rtlsdr_get_device_name(0) 21 | self.__closed = False 22 | 23 | self.set_sample_rate(sample_rate) 24 | self.set_center_freq(center_frequency) 25 | self.set_tuner_gain(tuner_gain) 26 | self._buf = ctypes.create_string_buffer(self.READ_SIZE) 27 | 28 | def set_sample_rate(self, sample_rate): 29 | if sdr.rtlsdr_set_sample_rate(self.devp, sample_rate) != 0: 30 | self.close() 31 | raise IOError("Couldn't set sample rate") 32 | self._sample_rate = sample_rate 33 | def get_sample_rate(self): 34 | return self._sample_rate 35 | sample_rate = property(get_sample_rate, set_sample_rate) 36 | 37 | def set_tuner_gain(self, gain): 38 | if sdr.rtlsdr_set_tuner_gain(self.devp, gain) < 0: 39 | raise IOError("Couldn't set tuner gain") 40 | self._tuner_gain = gain 41 | def get_tuner_gain(self): 42 | return self._tuner_gain 43 | tuner_gain = property(get_tuner_gain, set_tuner_gain) 44 | 45 | 46 | def set_center_freq(self, center_freq): 47 | if sdr.rtlsdr_set_center_freq(self.devp, center_freq) != 0: 48 | self.close() 49 | raise IOError("Couldn't set center frequency") 50 | self._center_freq = center_freq 51 | def get_center_freq(self): 52 | return self._center_freq 53 | center_freq = property(get_center_freq, set_center_freq) 54 | frequency = property(get_center_freq, set_center_freq) 55 | 56 | def reset_buffer(self): 57 | '''reset hardware buffers 58 | MUST be called before first read 59 | ''' 60 | if sdr.rtlsdr_reset_buffer(self.devp) < 0: 61 | raise IOError("Couldn't reset hardware buffers") 62 | 63 | def read(self): 64 | '''read data into our buffer 65 | You'll be returned a ctypes string buffer. 66 | THIS IS PRETTY DANGEROUS. Treat it as you would 67 | C memory. You can pretty easily crash python 68 | messing with it 69 | 70 | The buffer is re-used, so get stuff out before you 71 | call read() again 72 | ''' 73 | readp = pointer(ctypes.c_int32()) 74 | r = sdr.rtlsdr_read_sync(self.devp,self._buf, self.READ_SIZE, readp) 75 | if r < 0: raise IOError("Error reading from device") 76 | if readp < self.READ_SIZE: raise IOError("Short read!") 77 | 78 | return self._buf.raw 79 | 80 | def close(self): 81 | if not self.__closed: 82 | sdr.rtlsdr_close(self.devp) 83 | self.__closed = True 84 | 85 | @staticmethod 86 | def get_device_count(): 87 | return sdr.rtlsdr_get_device_count() 88 | 89 | if __name__ == "__main__": 90 | if RtlSDR.get_device_count() < 1: 91 | raise IOError("No known devices found") 92 | 93 | s = RtlSDR(0, 105700000, 1024000) 94 | s.frequency = 54000000 95 | s.frequency = 927000000 96 | s.frequency = 435012000 97 | s.frequency = 145125000 98 | s.frequency = 130100000 99 | s.frequency = 105700000 100 | s.reset_buffer() 101 | f = open("pytest.bin", "w") 102 | buf = s.read() 103 | f.write(buf) 104 | f.close() 105 | s.close() 106 | -------------------------------------------------------------------------------- /rtlsdr/_librtlsdr.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | 3 | _libraries = {} 4 | _libraries['librtlsdr.so'] = CDLL('librtlsdr.so') 5 | STRING = c_char_p 6 | 7 | 8 | int8_t = c_int8 9 | int16_t = c_int16 10 | int32_t = c_int32 11 | int64_t = c_int64 12 | uint8_t = c_uint8 13 | uint16_t = c_uint16 14 | uint32_t = c_uint32 15 | uint64_t = c_uint64 16 | int_least8_t = c_byte 17 | int_least16_t = c_short 18 | int_least32_t = c_int 19 | int_least64_t = c_long 20 | uint_least8_t = c_ubyte 21 | uint_least16_t = c_ushort 22 | uint_least32_t = c_uint 23 | uint_least64_t = c_ulong 24 | int_fast8_t = c_byte 25 | int_fast16_t = c_long 26 | int_fast32_t = c_long 27 | int_fast64_t = c_long 28 | uint_fast8_t = c_ubyte 29 | uint_fast16_t = c_ulong 30 | uint_fast32_t = c_ulong 31 | uint_fast64_t = c_ulong 32 | intptr_t = c_long 33 | uintptr_t = c_ulong 34 | intmax_t = c_long 35 | uintmax_t = c_ulong 36 | class rtlsdr_dev(Structure): 37 | pass 38 | rtlsdr_dev_t = rtlsdr_dev 39 | rtlsdr_dev._fields_ = [ 40 | ] 41 | rtlsdr_get_device_count = _libraries['librtlsdr.so'].rtlsdr_get_device_count 42 | rtlsdr_get_device_count.restype = uint32_t 43 | rtlsdr_get_device_count.argtypes = [] 44 | rtlsdr_get_device_name = _libraries['librtlsdr.so'].rtlsdr_get_device_name 45 | rtlsdr_get_device_name.restype = STRING 46 | rtlsdr_get_device_name.argtypes = [uint32_t] 47 | rtlsdr_open = _libraries['librtlsdr.so'].rtlsdr_open 48 | rtlsdr_open.restype = c_int 49 | rtlsdr_open.argtypes = [POINTER(POINTER(rtlsdr_dev_t)), uint32_t] 50 | rtlsdr_close = _libraries['librtlsdr.so'].rtlsdr_close 51 | rtlsdr_close.restype = c_int 52 | rtlsdr_close.argtypes = [POINTER(rtlsdr_dev_t)] 53 | rtlsdr_set_center_freq = _libraries['librtlsdr.so'].rtlsdr_set_center_freq 54 | rtlsdr_set_center_freq.restype = c_int 55 | rtlsdr_set_center_freq.argtypes = [POINTER(rtlsdr_dev_t), uint32_t] 56 | rtlsdr_get_center_freq = _libraries['librtlsdr.so'].rtlsdr_get_center_freq 57 | rtlsdr_get_center_freq.restype = c_int 58 | rtlsdr_get_center_freq.argtypes = [POINTER(rtlsdr_dev_t)] 59 | rtlsdr_set_freq_correction = _libraries['librtlsdr.so'].rtlsdr_set_freq_correction 60 | rtlsdr_set_freq_correction.restype = c_int 61 | rtlsdr_set_freq_correction.argtypes = [POINTER(rtlsdr_dev_t), c_int] 62 | rtlsdr_get_freq_correction = _libraries['librtlsdr.so'].rtlsdr_get_freq_correction 63 | rtlsdr_get_freq_correction.restype = c_int 64 | rtlsdr_get_freq_correction.argtypes = [POINTER(rtlsdr_dev_t)] 65 | rtlsdr_set_tuner_gain = _libraries['librtlsdr.so'].rtlsdr_set_tuner_gain 66 | rtlsdr_set_tuner_gain.restype = c_int 67 | rtlsdr_set_tuner_gain.argtypes = [POINTER(rtlsdr_dev_t), c_int] 68 | rtlsdr_get_tuner_gain = _libraries['librtlsdr.so'].rtlsdr_get_tuner_gain 69 | rtlsdr_get_tuner_gain.restype = c_int 70 | rtlsdr_get_tuner_gain.argtypes = [POINTER(rtlsdr_dev_t)] 71 | rtlsdr_set_sample_rate = _libraries['librtlsdr.so'].rtlsdr_set_sample_rate 72 | rtlsdr_set_sample_rate.restype = c_int 73 | rtlsdr_set_sample_rate.argtypes = [POINTER(rtlsdr_dev_t), uint32_t] 74 | rtlsdr_get_sample_rate = _libraries['librtlsdr.so'].rtlsdr_get_sample_rate 75 | rtlsdr_get_sample_rate.restype = c_int 76 | rtlsdr_get_sample_rate.argtypes = [POINTER(rtlsdr_dev_t)] 77 | rtlsdr_reset_buffer = _libraries['librtlsdr.so'].rtlsdr_reset_buffer 78 | rtlsdr_reset_buffer.restype = c_int 79 | rtlsdr_reset_buffer.argtypes = [POINTER(rtlsdr_dev_t)] 80 | rtlsdr_read_sync = _libraries['librtlsdr.so'].rtlsdr_read_sync 81 | rtlsdr_read_sync.restype = c_int 82 | rtlsdr_read_sync.argtypes = [POINTER(rtlsdr_dev_t), c_void_p, c_int, POINTER(c_int)] 83 | rtlsdr_async_read_cb_t = CFUNCTYPE(None, STRING, uint32_t, c_void_p) 84 | rtlsdr_wait_async = _libraries['librtlsdr.so'].rtlsdr_wait_async 85 | rtlsdr_wait_async.restype = c_int 86 | rtlsdr_wait_async.argtypes = [POINTER(rtlsdr_dev_t), rtlsdr_async_read_cb_t, c_void_p] 87 | rtlsdr_cancel_async = _libraries['librtlsdr.so'].rtlsdr_cancel_async 88 | rtlsdr_cancel_async.restype = c_int 89 | rtlsdr_cancel_async.argtypes = [POINTER(rtlsdr_dev_t)] 90 | __all__ = ['rtlsdr_read_sync', 'rtlsdr_set_center_freq', 91 | 'rtlsdr_get_freq_correction', 'int32_t', 'uint_least64_t', 92 | 'uintptr_t', 'uintmax_t', 'int_fast32_t', 'int16_t', 93 | 'int64_t', 'int_fast16_t', 'rtlsdr_set_sample_rate', 94 | 'rtlsdr_set_tuner_gain', 'int_fast64_t', 95 | 'rtlsdr_async_read_cb_t', 'uint8_t', 'int_least8_t', 96 | 'rtlsdr_get_device_count', 'rtlsdr_open', 'uint_least16_t', 97 | 'rtlsdr_reset_buffer', 'uint_least32_t', 'int_least64_t', 98 | 'int_least16_t', 'int_fast8_t', 'uint_least8_t', 99 | 'rtlsdr_set_freq_correction', 'intptr_t', 'int_least32_t', 100 | 'int8_t', 'rtlsdr_wait_async', 'rtlsdr_dev', 101 | 'rtlsdr_dev_t', 'rtlsdr_get_tuner_gain', 102 | 'rtlsdr_get_sample_rate', 'rtlsdr_cancel_async', 103 | 'uint_fast32_t', 'uint_fast64_t', 'intmax_t', 104 | 'rtlsdr_close', 'rtlsdr_get_device_name', 'uint_fast16_t', 105 | 'rtlsdr_get_center_freq', 'uint32_t', 'uint64_t', 106 | 'uint16_t', 'uint_fast8_t'] 107 | --------------------------------------------------------------------------------