]> git.parisson.com Git - timeside.git/commitdiff
Change AnalyzerResult 'data' to 'dataObject' and add functions to access directly...
authorThomas Fillon <thomas@parisson.com>
Wed, 9 Oct 2013 13:29:41 +0000 (15:29 +0200)
committerThomas Fillon <thomas@parisson.com>
Wed, 9 Oct 2013 13:31:24 +0000 (15:31 +0200)
12 files changed:
tests/test_AnalyzerResult.py
tests/test_analyzer_dc.py
tests/test_analyzer_level.py
timeside/analyzer/aubio_melenergy.py
timeside/analyzer/aubio_mfcc.py
timeside/analyzer/aubio_pitch.py
timeside/analyzer/aubio_specdesc.py
timeside/analyzer/aubio_temporal.py
timeside/analyzer/core.py
timeside/analyzer/dc.py
timeside/analyzer/level.py
timeside/analyzer/yaafe.py

index d1dd63e8fad0d66602779395ec5436b8d6110dcb..53952bc54bed9cb8ac5a091177d57858072f8331 100755 (executable)
@@ -26,55 +26,55 @@ class TestAnalyzerResult(TestCase):
 
     def testOnFloat(self):
         "float result"
-        self.result.data.value = 1.2
+        self.result.dataObject.value = 1.2
 
     def testOnInt(self):
         "integer result"
-        self.result.data.value = 1
+        self.result.dataObject.value = 1
 
     def testOnList(self):
         "list result"
-        self.result.data.value = [1., 2.]
+        self.result.dataObject.value = [1., 2.]
 
     def testOnString(self):
         "string result"
-        self.result.data.value = "hello"
+        self.result.dataObject.value = "hello"
 
     def testOnListOfString(self):
         "list of strings result"
-        self.result.data.value = ["hello", "hola"]
+        self.result.dataObject.value = ["hello", "hola"]
 
     def testOnListOfList(self):
         "list of lists result"
-        self.result.data.value = [[0, 1], [0, 1, 2]]
+        self.result.dataObject.value = [[0, 1], [0, 1, 2]]
 
     def testOnNumpyVectorOfFloat(self):
         "numpy vector of float"
-        self.result.data.value = ones(2, dtype='float') * pi
+        self.result.dataObject.value = ones(2, dtype='float') * pi
 
     def testOnNumpy2DArrayOfFloat64(self):
         "numpy 2d array of float64"
-        self.result.data.value = ones([2, 3], dtype='float64') * pi
+        self.result.dataObject.value = ones([2, 3], dtype='float64') * pi
 
     def testOnNumpy3DArrayOfInt32(self):
         "numpy 3d array of int32"
-        self.result.data.value = ones([2, 3, 2], dtype='int32')
+        self.result.dataObject.value = ones([2, 3, 2], dtype='int32')
 
     def testOnNumpyArrayOfStrings(self):
         "numpy array of strings"
-        self.result.data.value = array(['hello', 'hola'])
+        self.result.dataObject.value = array(['hello', 'hola'])
 
     def testOnEmptyList(self):
         "empty list"
-        self.result.data.value = []
+        self.result.dataObject.value = []
 
     def testOnNone(self):
         "None"
-        self.result.data.value = None
+        self.result.dataObject.value = None
 
     def testOnUnicode(self):
         "None"
-        self.result.data.value = None
+        self.result.dataObject.value = None
 
     def tearDown(self):
         pass
@@ -113,7 +113,7 @@ def create_good_method_func(numpy_data_type):
     def method(self):
         "numpy %s" % str(numpy_data_type)[7:-1]
         import numpy
-        self.result.data.value = numpy_data_type(pi)
+        self.result.dataObject.value = numpy_data_type(pi)
     return method
 
 
@@ -125,7 +125,7 @@ def create_bad_method_func(numpy_data_type):
             data = getattr(numpy, numpy_data_type)(pi)
         except ValueError:
             data = getattr(numpy, numpy_data_type)()
-        self.assertRaises(TypeError, self.result.data.__setattr__, 'value', data)
+        self.assertRaises(TypeError, self.result.dataObject.__setattr__, 'value', data)
     return method
 
 for numpy_data_type in good_numpy_data_types:
index ae2ec2729f777e6a7d693e0f7f990f852affa0f3..3fd683dc967b5b241fa3cd43ad43e9f347339846 100755 (executable)
@@ -25,7 +25,7 @@ class TestAnalyzerDC(TestCase):
         (decoder | self.analyzer).run()
         results = self.analyzer.results()
         for key in self.expected.keys():
-            self.assertEquals(results[key].data.value, self.expected[key])
+            self.assertEquals(results[key].dataObject.value, self.expected[key])
 
 if __name__ == '__main__':
     unittest.main(testRunner=TestRunner())
index b298880c0c9daeacb45ceda317ad95a03f2ec0f7..5ae9b7367a6a1e7565f010b9dbee49afd4ae1c31 100755 (executable)
@@ -33,7 +33,7 @@ class TestAnalyzerLevel(TestCase):
         (decoder | self.analyzer).run()
         results = self.analyzer.results()
         for key in self.expected.keys():
-            self.assertEquals(results[key].data.value, self.expected[key])
+            self.assertEquals(results[key].dataObject.value, self.expected[key])
         #print results
         #print results.to_yaml()
         #print results.to_json()
index 68945e73b946bb08ccfad418afc6226182911571..6c8d162484fc33484227b74aa620ff769187927e 100644 (file)
@@ -76,7 +76,7 @@ class AubioMelEnergy(Analyzer):
         melenergy.idMetadata.unit=''
 
         # Set Data
-        melenergy.data.value = self.melenergy_results
+        melenergy.dataObject.value = self.melenergy_results
 
         self._results.add(melenergy)
 
index 987d8b5d942d0ac18842f33ff92f665f6012bfab..ca2df21422a0aa4f0cedfaf7e87d9ebe3baecdc7 100644 (file)
@@ -76,5 +76,5 @@ class AubioMfcc(Analyzer):
         mfcc.idMetadata.unit = ""
         mfcc.parameters = parameters
 
-        mfcc.data.value = self.mfcc_results
+        mfcc.dataObject.value = self.mfcc_results
         self._results.add(mfcc)
index face938ba03eb500df7e69693291433e8d3ea572..fb3413870fe89eb8a117ef623384645fe7920c36 100644 (file)
@@ -76,7 +76,7 @@ class AubioPitch(Analyzer):
         # parameters : None # TODO check with Piem "default" and "freq" in setup
 
         # Set Data
-        pitch.data.value = numpy.array(self.pitches)
+        pitch.dataObject.value = numpy.array(self.pitches)
 
         self._results.add(pitch)
 
index c7594eb8ddab20149896def73e3c4d62da06ce08..865d2d880f15370759a6a9b2bff7d88a01a77177 100644 (file)
@@ -81,7 +81,7 @@ class AubioSpecdesc(Analyzer):
             res_specdesc.idMetadata.unit = unit
 
 
-            res_specdesc.data.value = self.specdesc_results[method]
+            res_specdesc.dataObject.value = self.specdesc_results[method]
 
             self._results.add(res_specdesc)
 
index 24ca77ed72bf22d7018d7148a2e4efb6aebf9458..9f109ad5b33bd6950602d959cb8954fceb896d96 100644 (file)
@@ -84,8 +84,8 @@ class AubioTemporal(Analyzer):
         # Set Data , dataMode='label', timeMode='event'
         # Event = list of (time, labelId)
 
-        onsets.data.label = numpy.ones(len(self.onsets))
-        onsets.data.time = self.onsets
+        onsets.dataObject.label = numpy.ones(len(self.onsets))
+        onsets.dataObject.time = self.onsets
 
         onsets.labelMetadata.label = {1: 'Onset'}
 
@@ -104,10 +104,10 @@ class AubioTemporal(Analyzer):
         # Event = list of (time, value)
         # TODO : add time
         if len(self.onsets) > 1:
-            onsetrate.data.value = 60. / numpy.diff(self.onsets)
-            onsetrate.data.time = self.onsets[:-1]
+            onsetrate.dataObject.value = 60. / numpy.diff(self.onsets)
+            onsetrate.dataObject.time = self.onsets[:-1]
         else:
-            onsetrate.data.value = []
+            onsetrate.dataObject.value = []
 
         self._results.add(onsetrate)
 
@@ -125,11 +125,11 @@ class AubioTemporal(Analyzer):
         if len(self.beats) > 1:
             duration = numpy.diff(self.beats)
             duration = numpy.append(duration,duration[-1])
-            beats.data.time = self.beats
-            beats.data.duration = duration
-            beats.data.label = numpy.ones(len(self.beats))
+            beats.dataObject.time = self.beats
+            beats.dataObject.duration = duration
+            beats.dataObject.label = numpy.ones(len(self.beats))
         else:
-            beats.data.label = []
+            beats.dataObject.label = []
 
         beats.labelMetadata.label = {1: 'Beat'}
 
@@ -149,11 +149,11 @@ class AubioTemporal(Analyzer):
             periods = 60. / numpy.diff(self.beats)
             periods = numpy.append(periods, periods[-1])
 
-            bpm.data.time = self.beats
-            bpm.data.duration = duration
-            bpm.data.value = periods
+            bpm.dataObject.time = self.beats
+            bpm.dataObject.duration = duration
+            bpm.dataObject.value = periods
 
         else:
-            bpm.data.value = []
+            bpm.dataObject.value = []
 
         self._results.add(bpm)
index 2fc94975f3fc1f83dc06340fc064955a98b6284d..1d559149f3c2cbe21b63348f1c22dbe827fe80d7 100644 (file)
@@ -233,6 +233,7 @@ class AudioMetadata(MetadataObject):
     _default_value = OrderedDict([('uri', ''),
                                   ('start', 0),
                                   ('duration', None),
+                                  ('IS_SEGMENT', None),
                                   ('channels', None),
                                   ('channelsManagement', '')])
 
@@ -289,14 +290,15 @@ class FrameMetadata(MetadataObject):
                                   ('stepsize', None)])
 
 
-class AnalyzerData(MetadataObject):
+class DataObject(MetadataObject):
 
     '''
     Metadata object to handle Frame related Metadata
 
         Attributes
         ----------
-        data : numpy array
+        value : numpy array
+        label : numpy array of int
         time : numpy array of float
         duration : numpy array of float
 
@@ -338,7 +340,7 @@ class AnalyzerData(MetadataObject):
             elif name == 'dataType':
                 return
 
-        super(AnalyzerData, self).__setattr__(name, value)
+        super(DataObject, self).__setattr__(name, value)
 
     def __eq__(self, other):
         try:
@@ -429,7 +431,7 @@ class AnalyzerResult(MetadataObject):
     A new MetadataObject with the following attributes :
         - dataMode
         - timeMode
-        - data : :class:`AnalyzerData`
+        - data : :class:`DataObject`
         - idMetadata : :class:`IdMetadata`
         - audioMetadata : :class:`AudioMetadata`
         - frameMetadata : :class:`FrameMetadata`
@@ -442,7 +444,7 @@ class AnalyzerResult(MetadataObject):
     _default_value = OrderedDict([('dataMode', None),
                                   ('timeMode', None),
                                   ('idMetadata', None),
-                                  ('data', None),
+                                  ('dataObject', None),
                                   ('audioMetadata', None),
                                   ('frameMetadata', None),
                                   ('labelMetadata', None),
@@ -460,7 +462,7 @@ class AnalyzerResult(MetadataObject):
 
     def __setattr__(self, name, value):
         setFuncDict = {'idMetadata': IdMetadata,
-                       'data': AnalyzerData,
+                       'dataObject': DataObject,
                        'audioMetadata': AudioMetadata,
                        'frameMetadata': FrameMetadata,
                        'labelMetadata': LabelMetadata,
@@ -482,13 +484,13 @@ class AnalyzerResult(MetadataObject):
                 raise TypeError('Wrong argument')
         elif name == 'dataMode':
             if self[name] is not None:
-                raise AttributeError("The value of attribute ''timeMode'' \\\
+                raise AttributeError("The value of attribute ''dataMode'' \\\
                 can not change after setup")
             if value == 'value':
                 del self.labelMetadata
-                del self.data.label
+                del self.dataObject.label
             elif value == 'label':
-                del self.data.value
+                del self.dataObject.value
             elif value is None:
                 pass
             else:
@@ -500,12 +502,12 @@ class AnalyzerResult(MetadataObject):
                 can not change after setup")
 
             if value == 'framewise':
-                del self.data.time
-                del self.data.duration
+                del self.dataObject.time
+                del self.dataObject.duration
                 pass
             elif value == 'global':
-                del self.data.time
-                del self.data.duration
+                del self.dataObject.time
+                del self.dataObject.duration
                 del self.frameMetadata
 
                 pass
@@ -513,7 +515,7 @@ class AnalyzerResult(MetadataObject):
                 del self.frameMetadata
             elif value == 'event':
                 del self.frameMetadata
-                del self.data.duration
+                del self.dataObject.duration
 
                 pass
             elif value is None:
@@ -527,7 +529,7 @@ class AnalyzerResult(MetadataObject):
         return dict([(key, self[key].as_dict())
                     for key in self.keys() if hasattr(self[key], 'as_dict')] +
                     [('dataMode', self.dataMode), ('timeMode', self.timeMode)])
-
+                    # TODO : check if it can be simplified now
     def to_xml(self):
         import xml.etree.ElementTree as ET
         root = ET.Element('result')
@@ -561,6 +563,34 @@ class AnalyzerResult(MetadataObject):
 
         return result
 
+    def data(self):
+        return {key: self.dataObject[key] for key in ['value', 'label'] if key in self.dataObject.keys()}
+
+    def time(self):
+        if self.timeMode == 'global':
+            return self.audioMetadata.start
+        elif self.timeMode == 'framewise':
+            return (self.audioMetadata.start +
+                    self.frameMetadata.stepsize * numpy.arange(0,len(self)))
+        else:
+            return self.dataObject.time
+        pass
+
+    def duration(self):
+        if self.timeMode == 'global':
+            return self.audioMetadata.duration
+        elif self.timeMode == 'framewise':
+            return self.frameMetadata.blockwise * numpy.ones(len(self))
+        elif self.timeMode == 'event':
+            return numpy.zeros(len(self))
+        elif self.timeMode == 'segment':
+            return self.dataObject.duration
+
+    def __len__(self):
+        if self.dataMode == 'value':
+            return len(self.dataObject.value)
+        else:
+            return len(self.dataObject.label)
 
 
 #    @property
@@ -589,7 +619,7 @@ class AnalyzerResultContainer(dict):
     >>> (d|a).run() #doctest: +ELLIPSIS
     <timeside.core.ProcessPipe object at 0x...>
     >>> a.new_result() #doctest: +ELLIPSIS
-    AnalyzerResult(dataMode=None, timeMode=None, idMetadata=IdMetadata(id='', name='', unit='', description='', date='...', version='...', author='TimeSide'), data=AnalyzerData(value=None, label=array([], dtype=int64), time=array([], dtype=float64), duration=array([], dtype=float64)), audioMetadata=AudioMetadata(uri='file:///.../tests/samples/sweep.wav', start=1.0, duration=7.0, channels=None, channelsManagement=''), frameMetadata=FrameMetadata(samplerate=None, blocksize=None, stepsize=None), labelMetadata=LabelMetadata(label=None, description=None, labelType='mono'), parameters={})
+    AnalyzerResult(dataMode=None, timeMode=None, idMetadata=IdMetadata(id='', name='', unit='', description='', date='...', version='...', author='TimeSide'), data=DataObject(value=None, label=array([], dtype=int64), time=array([], dtype=float64), duration=array([], dtype=float64)), audioMetadata=AudioMetadata(uri='file:///.../tests/samples/sweep.wav', start=1.0, duration=7.0, channels=None, channelsManagement=''), frameMetadata=FrameMetadata(samplerate=None, blocksize=None, stepsize=None), labelMetadata=LabelMetadata(label=None, description=None, labelType='mono'), parameters={})
     >>> resContainer = coreA.AnalyzerResultContainer()
 
     '''
@@ -636,7 +666,7 @@ class AnalyzerResultContainer(dict):
         root = ET.Element('timeside')
 
         for result in self.values():
-            if result:
+            if result is not None:
                 root.append(ET.fromstring(result.to_xml()))
 
         return ET.tostring(root, encoding="utf-8", method="xml")
@@ -745,7 +775,7 @@ class AnalyzerResultContainer(dict):
                 group.attrs['dataMode'] = res['dataMode']
                 group.attrs['timeMode'] = res['timeMode']
                 for key in res.keys():
-                    if key not in ['dataMode', 'timeMode', 'data']:
+                    if key not in ['dataMode', 'timeMode', 'dataObject']:
                         subgroup = group.create_group(key)
 
                         # Write attributes
@@ -755,7 +785,7 @@ class AnalyzerResultContainer(dict):
                                 subgroup.attrs[name] = res[key][name]
 
                 # Write Datasets
-                key = 'data'
+                key = 'dataObject'
                 subgroup = group.create_group(key)
                 for dsetName in res[key].keys():
                     if res[key][dsetName] is not None:
@@ -788,7 +818,7 @@ class AnalyzerResultContainer(dict):
                     for name, value in subgroup.attrs.items():
                             result[subgroup_name][name] = value
 
-                    if subgroup_name == 'data':
+                    if subgroup_name == 'dataObject':
                         for dsetName, dset in subgroup.items():
                             # Load value from the hdf5 dataset and store in data
                             # FIXME : the following conditional statement is to prevent
@@ -874,42 +904,22 @@ class Analyzer(Processor):
         from datetime import datetime
 
         result = AnalyzerResult(dataMode=dataMode, timeMode=timeMode)
+
         # Automatically write known metadata
-        result.idMetadata = IdMetadata(
-            date=datetime.now().replace(microsecond=0).isoformat(' '),
-            version=TimeSideVersion,
-            author='TimeSide')
-        result.audioMetadata = AudioMetadata(uri=self.mediainfo()['uri'],
-                                             start=self.mediainfo()['start'],
-                                             duration=self.mediainfo()['duration'])
-
-        result.data = AnalyzerData()
-
-        if dataMode == 'value':
-            pass
-        elif dataMode == 'label':
-            result.labelMetadata = LabelMetadata()
-        else:
-            # raise ArgError('')
-            pass
+        result.idMetadata.date = datetime.now().replace(
+                                                microsecond=0).isoformat(' ')
+        result.idMetadata.version = TimeSideVersion
+        result.idMetadata.author = 'TimeSide'
+
+        result.audioMetadata.uri = self.mediainfo()['uri']
+        result.audioMetadata.start = self.mediainfo()['start']
+        result.audioMetadata.duration = self.mediainfo()['duration']
+        result.audioMetadata.IS_SEGMENT = self.mediainfo()['IS_SEGMENT']
 
         if timeMode == 'framewise':
-            result.frameMetadata = FrameMetadata(
-                samplerate=self.result_samplerate,
-                blocksize=self.result_blocksize,
-                stepsize=self.result_stepsize)
-        elif timeMode == 'global':
-            # None : handle by data
-            pass
-        elif timeMode == 'segment':
-            # None : handle by data
-            pass
-        elif timeMode == 'event':
-            # None : handle by data, duration = 0
-            pass
-        else:
-            # raise ArgError('')
-            pass
+            result.frameMetadata.samplerate = self.result_samplerate
+            result.frameMetadata.blocksize = self.result_blocksize
+            result.frameMetadata.stepsize = self.result_stepsize
 
         return result
 
index da8fe5eedb5621e134a78c051af743b6bcc49dad..319931d3ac86f10d6bc452606698bbf7730133b0 100644 (file)
@@ -54,5 +54,5 @@ class MeanDCShift(Analyzer):
         dc_result.idMetadata.name = "Mean DC shift"
         dc_result.idMetadata.unit = "%"
         # Set Data
-        dc_result.data.value = numpy.round(numpy.mean(100*self.values),3)
+        dc_result.dataObject.value = numpy.round(numpy.mean(100*self.values),3)
         self._results.add(dc_result)
\ No newline at end of file
index bf406ab89754f2fa9a576dcb99dea9a1760d9d0d..85d9407976826419785f39a31ade23cbd99c9ea4 100644 (file)
@@ -68,7 +68,7 @@ class Level(Analyzer):
         max_level.idMetadata.name = "Max level"
         max_level.idMetadata.unit = "dBFS"
 
-        max_level.data.value = numpy.round(20*numpy.log10(self.max_value), 3)
+        max_level.dataObject.value = numpy.round(20*numpy.log10(self.max_value), 3)
         self._results.add(max_level)
 
         # RMS level
@@ -77,7 +77,7 @@ class Level(Analyzer):
         rms_level.idMetadata.name="RMS level"
         rms_level.idMetadata.unit="dBFS"
 
-        rms_level.data.value = numpy.round(20*numpy.log10(
+        rms_level.dataObject.value = numpy.round(20*numpy.log10(
                                 numpy.sqrt(numpy.mean(self.mean_values))), 3)
         self._results.add(rms_level)
 
index e2fbaf8d00e2c490274b9b7b546d099742c51f5f..a212ef37cb9e02dc924b3433f7b45d7f4fce6f15 100644 (file)
@@ -96,9 +96,9 @@ class Yaafe(Analyzer):
             result.idMetadata.name = name
             result.idMetadata.unit = ''
             # Read Yaafe Results
-            result.data.value = self.yaafe_engine.readOutput(featName)
+            result.dataObject.value = self.yaafe_engine.readOutput(featName)
             # Store results in Container
-            if len(result.data.value):
+            if len(result.dataObject.value):
                 self._results.add(result)