]> sigrok.org Git - libsigrokdecode.git/commitdiff
irmp: rework the Python language binding for the shared library
authorGerhard Sittig <redacted>
Sat, 22 Feb 2020 09:16:16 +0000 (10:16 +0100)
committerGerhard Sittig <redacted>
Sat, 18 Jul 2020 13:33:23 +0000 (15:33 +0200)
Rename the Python language binding's source file and identifiers to
eliminate camel case (most of it, stick with camel case in Python class
names as is the convention). Adjust whitespace and arrange tables such
that their indentation will last during maintenance.

Re-add the license text which was missing in the original submission's
copy of another decoder. Add copyright information for this submission.

Don't "import *" from ctypes(3), use explicit references instead. Avoid
double underscores as single leading underscore is already bad enough.
Adjust the Python side to the C library's renamed API routines.

Create a result data structure layout that only has a single level of
nesting, which better represents the C library's interface. Only flags
"get unfolded" in the Python binding, to eliminate magic numbers.

Prepare to support more platforms than Linux (detected) and Windows (the
default when nothing else got detected).

decoders/ir_irmp/IrmpPythonWrap.py [deleted file]
decoders/ir_irmp/irmp_library.py [new file with mode: 0644]

diff --git a/decoders/ir_irmp/IrmpPythonWrap.py b/decoders/ir_irmp/IrmpPythonWrap.py
deleted file mode 100644 (file)
index ee250c4..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-from ctypes import *
-import platform
-
-      
-
-class IrmpWrap:
-    class IrmpData(Structure):
-         _fields_ = [  ("protocol"      , c_uint32 ),
-                       ("protocolName"  , c_char_p ),
-                       ("address"       , c_uint32 ),
-                       ("command"       , c_uint32 ),
-                       ("flags"         , c_uint32 ),
-                       ("startSample"   , c_uint32 ),
-                       ("endSample"     , c_uint32 ),
-         ]
-    
-    def __init__(self):
-        libname = "irmp.dll"
-        # get the right filename
-
-        if platform.uname()[0] == "Linux":
-            name = "irmp.so"    
-    
-        self.__irmpDll = cdll.LoadLibrary("irmp.dll")
-        self.__irmpDll.IRMP_GetSampleRate.restype = c_int32
-        self.__irmpDll.IRMP_GetSampleRate.argtypes = []
-        
-        
-        self.__irmpDll.IRMP_GetProtocolName.restype = c_char_p
-        self.__irmpDll.IRMP_GetProtocolName.argtypes = [c_uint32]
-        
-        self.__irmpDll.IRMP_Reset.restype = None
-        self.__irmpDll.IRMP_Reset.argtypes = []
-        
-        self.__irmpDll.IRMP_AddSample.restype = c_uint32
-        self.__irmpDll.IRMP_AddSample.argtypes = [c_uint8]
-        
-        self.__irmpDll.IRMP_GetData.restype = c_uint32
-        self.__irmpDll.IRMP_GetData.argtypes = [POINTER(IrmpWrap.IrmpData)]
-        
-        self.__irmpDll.IRMP_Detect.restype = IrmpWrap.IrmpData
-        self.__irmpDll.IRMP_Detect.argtypes = [ c_char_p, c_uint32]
-        
-        self.__data = IrmpWrap.IrmpData()
-        self.__startSample = c_uint32(0)
-        self.__endSample   = c_uint32(0)
-
-        return
-
-    def GetProtocollName(self, pn):
-        return self.__irmpDll.IRMP_GetProtocollName(pn)
-    
-    def GetSampleRate(self):
-        return self.__irmpDll.IRMP_GetSampleRate()
-    
-    def Reset(self):
-        self.__irmpDll.IRMP_Reset()
-        
-    def AddSample(self, level):
-        
-        if self.__irmpDll.IRMP_AddSample(c_uint8( 1 if (level!=0) else 0)):
-            self.__irmpDll.IRMP_GetData( byref(self.__data))
-            return True
-        else:
-            return False
-        
-    def GetData(self):
-        return { 'data'  : { 
-                             'protocol'     : self.__data.protocol,
-                             'protocolName' : self.__data.protocolName.decode('UTF-8'),
-                             'address'       : self.__data.address,
-                             'command'       : self.__data.command,
-                             'repeat'        : (self.__data.flags != 0)
-                           }, 
-                 'start' : self.__data.startSample,
-                 'end'   : self.__data.endSample
-               }
-
diff --git a/decoders/ir_irmp/irmp_library.py b/decoders/ir_irmp/irmp_library.py
new file mode 100644 (file)
index 0000000..3bd9048
--- /dev/null
@@ -0,0 +1,108 @@
+##
+## This file is part of the libsigrokdecode project.
+##
+## Copyright (C) 2019 Rene Staffen
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+##
+
+'''
+Python binding for the IRMP library.
+'''
+
+import ctypes
+import platform
+
+class IrmpLibrary:
+    '''
+    Library instance for an infrared protocol detector.
+    '''
+
+    class ResultData(ctypes.Structure):
+        _fields_ = [
+            ( 'protocol', ctypes.c_uint32, ),
+            ( 'protocol_name', ctypes.c_char_p, ),
+            ( 'address', ctypes.c_uint32, ),
+            ( 'command', ctypes.c_uint32, ),
+            ( 'flags', ctypes.c_uint32, ),
+            ( 'start_sample', ctypes.c_uint32, ),
+            ( 'end_sample', ctypes.c_uint32, ),
+        ]
+
+    FLAG_REPETITION = 1 << 0
+
+    def _library_filename(self):
+        '''
+        Determine the library filename depending on the platform.
+        '''
+
+        if platform.uname()[0] == 'Linux':
+            return 'libirmp.so'
+        # TODO Add support for more platforms.
+        return 'irmp.dll'
+
+    def __init__(self):
+        '''
+        Create a library instance.
+        '''
+
+        # Load the library. Lookup routines, declare their prototypes.
+        filename = self._library_filename()
+        self._lib = ctypes.cdll.LoadLibrary(filename)
+
+        self._lib.irmp_get_sample_rate.restype = ctypes.c_uint32
+        self._lib.irmp_get_sample_rate.argtypes = []
+
+        self._lib.irmp_reset_state.restype = None
+        self._lib.irmp_reset_state.argtypes = []
+
+        self._lib.irmp_add_one_sample.restype = ctypes.c_int
+        self._lib.irmp_add_one_sample.argtypes = [ ctypes.c_int, ]
+
+        if False:
+            self._lib.irmp_detect_buffer.restype = self.ResultData
+            self._lib.irmp_detect_buffer.argtypes = [ ctypes.POINTER(ctypes.c_uint8), ctypes.c_size_t, ]
+
+        self._lib.irmp_get_result_data.restype = ctypes.c_int
+        self._lib.irmp_get_result_data.argtypes = [ ctypes.POINTER(self.ResultData), ]
+
+        self._lib.irmp_get_protocol_name.restype = ctypes.c_char_p
+        self._lib.irmp_get_protocol_name.argtypes = [ ctypes.c_uint32, ]
+
+        # Create a result buffer that's local to the library instance.
+        self._data = self.ResultData()
+
+    def get_sample_rate(self):
+        return self._lib.irmp_get_sample_rate()
+
+    def reset_state(self):
+        self._lib.irmp_reset_state()
+
+    def add_one_sample(self, level):
+        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 = {
+            'proto_nr': self._data.protocol,
+            'proto_name': self._data.protocol_name.decode('UTF-8', 'ignore'),
+            'address': self._data.address,
+            'command': self._data.command,
+            'repeat': bool(self._data.flags & self.FLAG_REPETITION),
+            'start': self._data.start_sample,
+            'end': self._data.end_sample,
+        }
+        return data