summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decoders/ir_irmp/irmp_library.py40
-rw-r--r--decoders/ir_irmp/pd.py23
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()