diff options
-rw-r--r-- | decoders/ir_irmp/irmp_library.py | 40 | ||||
-rw-r--r-- | decoders/ir_irmp/pd.py | 23 |
2 files changed, 52 insertions, 11 deletions
diff --git a/decoders/ir_irmp/irmp_library.py b/decoders/ir_irmp/irmp_library.py index d542a1d..5ec6522 100644 --- a/decoders/ir_irmp/irmp_library.py +++ b/decoders/ir_irmp/irmp_library.py @@ -29,6 +29,8 @@ class IrmpLibrary: Library instance for an infrared protocol detector. ''' + __usable_instance = None + class ResultData(ctypes.Structure): _fields_ = [ ( 'protocol', ctypes.c_uint32, ), @@ -54,14 +56,13 @@ class IrmpLibrary: return 'libirmp.dylib' return 'irmp.dll' - def __init__(self): + def _library_setup_api(self): ''' - Create a library instance. + Lookup the C library's API routines. Declare their prototypes. ''' - # Load the library. Lookup routines, declare their prototypes. - filename = self._library_filename() - self._lib = ctypes.cdll.LoadLibrary(filename) + if not self._lib: + return False self._lib.irmp_get_sample_rate.restype = ctypes.c_uint32 self._lib.irmp_get_sample_rate.argtypes = [] @@ -85,20 +86,46 @@ class IrmpLibrary: # Create a result buffer that's local to the library instance. self._data = self.ResultData() + return True + + def __init__(self): + ''' + Create a library instance. + ''' + + # Only create a working instance for the first invocation. + # Degrade all other instances, make them fail "late" during + # execution, so that users will see the errors. + self._lib = None + self._data = None + if IrmpLibrary.__usable_instance is None: + filename = self._library_filename() + self._lib = ctypes.cdll.LoadLibrary(filename) + self._library_setup_api() + IrmpLibrary.__usable_instance = self + def get_sample_rate(self): + if not self._lib: + return None return self._lib.irmp_get_sample_rate() def reset_state(self): + if not self._lib: + return None self._lib.irmp_reset_state() def add_one_sample(self, level): + if not self._lib: + raise Exception("IRMP library limited to a single instance.") if not self._lib.irmp_add_one_sample(int(level)): return False self._lib.irmp_get_result_data(ctypes.byref(self._data)) return True def get_result_data(self): - data = { + if not self._data: + return None + return { 'proto_nr': self._data.protocol, 'proto_name': self._data.protocol_name.decode('UTF-8', 'ignore'), 'address': self._data.address, @@ -108,4 +135,3 @@ class IrmpLibrary: 'start': self._data.start_sample, 'end': self._data.end_sample, } - return data diff --git a/decoders/ir_irmp/pd.py b/decoders/ir_irmp/pd.py index cb69fd0..979c1e0 100644 --- a/decoders/ir_irmp/pd.py +++ b/decoders/ir_irmp/pd.py @@ -24,6 +24,9 @@ import sigrokdecode as srd class SamplerateError(Exception): pass +class LibraryError(Exception): + pass + class Decoder(srd.Decoder): api_version = 3 id = 'ir_irmp' @@ -90,12 +93,11 @@ class Decoder(srd.Decoder): self.put(ss, es, self.out_ann, [0, txts]) def __init__(self): - self.irmp = irmp_library.IrmpLibrary() - self.lib_rate = self.irmp.get_sample_rate() + self.irmp = None self.reset() def reset(self): - self.irmp.reset_state() + self.want_reset = True def start(self): self.out_ann = self.register(srd.OUTPUT_ANN) @@ -105,11 +107,24 @@ class Decoder(srd.Decoder): self.samplerate = value def decode(self): + if not self.irmp: + try: + self.irmp = irmp_library.IrmpLibrary() + except Exception as e: + txt = e.args[0] + raise LibraryError(txt) + if self.irmp: + self.lib_rate = self.irmp.get_sample_rate() + if not self.irmp or not self.lib_rate: + raise LibraryError('Cannot access IRMP library. One instance limit exceeded?') if not self.samplerate: raise SamplerateError('Cannot decode without samplerate.') if self.samplerate % self.lib_rate: - raise SamplerateError('capture samplerate must be multiple of library samplerate ({})'.format(self.lib_rate)) + raise SamplerateError('Capture samplerate must be multiple of library samplerate ({})'.format(self.lib_rate)) self.rate_factor = int(self.samplerate / self.lib_rate) + if self.want_reset: + self.irmp.reset_state() + self.want_reset = False self.active = 0 if self.options['polarity'] == 'active-low' else 1 ir, = self.wait() |