Room Impulsive Response

RooomIR application.

This application was developed using the toolbox’s existent functionalities, and is aimed to give support to acquire and post-process impulsive responses, and calculate room acoustics parameters.

For syntax purposes you should start with:

>>> from pytta import roomir as roomir

The functionalities comprise tools for data acquisition (MeasurementSetup, MeasurementData, and TakeMeasure classes) and post-processing (MeasurementPostProcess class), including some really basic statistical treatment.

The workflow consists of creating a roomir.MeasurementSetup and a roomir.MeasurementData object, then taking a measurement with a roomir.TakeMeasure object (see its documentation for possible take kinds); there will be as many TakeMeasure instantiations as measurement takes. After a measurement is taken it’s saved through the roomir.MeasurementData.save_take() method.

All measured responses and the post-processed impulsive responses are stored as MeasuredThing class objects, while the calculated results as Analysis class objects. All data is stored in the HDF5 file scheme designed for the toolbox. For more information about the specific file scheme for the MeasurementData.hdf5 file check the MeasurementData class documentation.

It is also possible to use the LabJack U3 hardware with the EI 1050 probe to acquire humidity and temperature values during the measurement. Check the TakeMeasure class documentation for more information.

The usage of this app is shown in the files present in the examples folder.

Available classes:

>>> roomir.MeasurementSetup
>>> roomir.MeasurementData
>>> roomir.TakeMeasure
>>> roomir.MeasuredThing
>>> roomir.MeasurementPostProcess

Available functions:

>> MS, D = roomir.med_load(‘med-name’)

For further information, check the docstrings for each class and function mentioned above. This order is also recommended.

Authors:

Matheus Lazarin, matheus.lazarin@eac.ufsm.br

class pytta.roomir.MeasurementSetup(name, samplingRate, device, excitationSignals, freqMin, freqMax, inChannels, inCompensations, outChannels, outCompensations, averages, pause4Avg, noiseFloorTp, calibrationTp)

Holds the measurement setup information. Managed in disc by the roomir.MeasurementData class and loaded back to memory through the roomir.med_load function.

  • name (), (str):

    Measurement identification name. Used on roomir.med_load(‘name’);

  • samplingRate (), (int):

    Device sampling rate;

  • device (), (list | int):

    Audio I/O device identification number from pytta.list_devices(). Can be an integer for input and output with the same device, or a list for different devices. E.g.:

    >>> device = [1,2]  % [input,output]
    
  • excitationSignals (), (dict):

    Dictionary containing SignalObjs with excitation signals. E.g.:

    >>> excitSigs = {'sweep18': pytta.generate.sweep(fftDegree=18),
                     'speech': pytta.read_wave('sabine.wav')}
    
  • freqMin (), (float):

    Analysis band’s lower limit;

  • freqMax (), (float):

    Analysis band’s upper limit

  • inChannels (), (dict):

    Dict containing input channel codes, hardware channel and name. Aditionally is possible to group channels with an extra ‘groups’ key. E.g.:

    >>> inChannels={'LE': (4, 'Left ear'),
                    'RE': (3, 'Right ear'),
                    'AR1': (5, 'Array mic 1'),
                    'AR2': (6, 'Array mic 2'),
                    'AR3': (7, 'Array mic 3'),
                    'Mic1': (1, 'Mic 1'),
                    'Mic2': (2, 'Mic 2'),
                    'groups': {'HATS': (4, 3),
                               'Array': (5, 6, 7)} }
    
  • inCompensations (), (dict):

    Magnitude compensation for each input transducers, but not mandatory for all. E.g.:

    >>> inCompensations={'AR1': (AR1SensFreq, AR1SensdBMag),
                         'AR2': (AR2SensFreq, AR2SensdBMag),
                         'AR3': (AR3SensFreq, AR3SensdBMag),
                         'Mic2': (M2SensFreq, M2SensdBMag) }
    
  • outChannels (default), (type):

    Dict containing output channel codes, hardware channel and name. E.g.:

    >>> outChannels={'O1': (1, 'Dodecahedron 1'),
                     'O2': (2, 'Dodecahedron 2'),
                     'O3': (4, 'Room sound system') }
    
  • outCompensations (default), (type):

    Magnitude compensation for each output transducers, but not mandatory for all. E.g.:

    >>> outCompensations={'O1': (Dodec1SensFreq, Dodec1SensdBMag),
                          'O2': (Dodec2SensFreq, Dodec2SensdBMag) }
    
  • averages (), (int):

    Number of averages per take. This option is directly connected to the confidence interval calculated by the MeasurementPostProcess class methods. Important in case you need some statistical treatment;

  • pause4Avg (), (bool):

    Option for pause between averages;

  • noiseFloorTp (), (float):

    Recording time length in seconds for noisefloor measurement take type;

  • calibrationTp (default), (type):

    Recording time length in seconds for microphone indirect calibration take type;

class pytta.roomir.MeasurementData(MS, skipFileInit=False)

Class intended to store and retrieve from disc the acquired data as MeasuredThing objects plus the MeasurementSetup. Used to calculate the impulsive responses and calibrated responses as well.

Instantiation:

>>> MS = pytta.roomir.MeasurementSetup(...)
>>> D = pytta.roomir.MeasurementData(MS)
  • MS (), (roomir.MeasurementSetup):

    MeasurementSetup object;

  • save_take(…):

    Save an acquired roomir.TakeMeasure in disc;

  • get(…):

    Retrieves from disc MeasuredThings that matches the provided tags and returns a dict;

  • calculate_ir(…):

    Calculate the Impulsive Responses from the provided dict, which is obtained trough the get(…) method. Saves the result as new MeasuredThing objects;

  • calibrate_res(…):

    Apply indirect calibration to the measured signals from the provided dict, which is obtained trough the get(…) method. Saves the result as new MeasuredThing objects;

For further information on methods see its specific documentation.

save_take(TakeMeasureObj)

Saves in disc the resultant roomir.MeasuredThings from a roomir.TakeMeasure’s run.

  • TakeMeasureObj (), (roomir.TakeMeasure)

Usage:

>>> myTake = roomir.TakeMeasure(kind="roomres", ...)
>>> myTake.run()
>>> D.save_take(myTake)
get(*args, skipMsgs=False)

Gets from disc the MeasuredThings that matches with the provided tags as non-keyword arguments.

  • non-keyword arguments (), (string):

    Those are tags. Tags are the main information about the roomir.MeasuredThings found on its filename stored in disc. You can mix as many tags as necessary to define well your search. The possible tags are:

    • kind (e.g. roomres, roomir… See other available kinds

      in roomir.MeasuredThing’s docstrings);

      >>> D.get('roomres')  % Gets all measured roomres;
      
    • source-receiver cfg. (single info for ‘noisefloor’

      MeasuredThing kind, e.g. ‘R3’; or a pair for other kinds, e.g. ‘S1-R1’);

      >>> D.get('S1')  % Gets everything measured in source
                       % position 1
      
    • output-input cfg. (single channel for ‘miccalibration’,

      e.g. ‘Mic1’; output-input pair for other kinds, e.g. ‘O1-Mic1’):

      >>> D.get('O1')  % Gets everything measured through
                       % ouput 1
      
      >>> D.get('O1','Mic1')  % or
      >>> D.get('O1-Mic1')
      
    • excitation signal (e.g. ‘SWP19’):

      >>> D.get('SWP20')  % Gets everything measured with
                          % excitation signal 'SWP20'
      
    • take counter (e.g. ‘_1’, ‘_2’, …):

      >>> D.get('_1')  % Gets all first takes
      

    Only MeasuredThings that matches all provided tags will be returned.

  • skipMsgs (false), (bool):

    Don’t show the search’s resultant messages.

  • getDict (dict):

    Dict with the MeasuredThing’s filenames as keys and the MeasuredThing itself as values. e.g.:

    >>> getDict = {'roomres_S1-R1_O1-Mic1_SWP19_1':
                       roomir.MeasuredThing}
    

Specific usage example:

Get the ‘roomir’ MeasuredThing’s first take at S1-R1 with Mic1, Output1, and sweep:

>>> getDict = MeasurementData.get('roomrir', 'Mic1-O1', '_1', ...
                                  'SWP19', 'S1-R1')

As you see, the order doesn’t matter because the algorithm just look for matching tags in the filenames.

calculate_ir(getDict, calibrationTake=1, skipInCompensation=False, skipOutCompensation=False, skipBypCalibration=False, skipRegularization=False, skipIndCalibration=False, IREndManualCut=None, IRStartManualCut=None, skipSave=False, whereToOutComp='excitation')

Gets the dict returned from the roomir.MeasuremenData.get() method, calculate the impulsive responses, store to disc, and return the correspondent getDict. Check the input arguments below for options.

This method generates new MeasuredThings with a kind derived from the measured kind. The possible conversions are:

  • ‘roomres’ MeasuredThing kind to a ‘roomir’ MeasuredThing kind;

  • ‘channelcalibration’ to ‘channelcalibir’;

  • ‘sourcerecalibration’ to ‘sourcerecalibir’ (for the Strengh

    Factor recalibration method. See pytta.rooms.G for more information);

  • getDict (), (dict):

    Dict from the roomir.MeasurementData.get(…) method;

  • calibrationTake (1), (int):

    Choose the take from the ‘miccalibration’ MeasuredThing for the indirect calibration of the correspondent input channels;

  • skipInCompensation (False), (bool):

    Option for skipping compensation on the input chain with the provided response to the MeasurementSetup;

  • skipOutCompensation (False), (bool):

    Option for skipping compensation on the output chain with the provided response to the MeasurementSetup;

  • skipBypCalibration (False), (bool):

    Option for skipping bypass calibration. Bypass calibration means deconvolving with the impulsive response measured between the output and input of the soundcard.

  • skipRegularization (False), (bool):

    Option for skipping Kirkeby’s regularization. For more information see pytta.ImpulsiveResponse’s docstrings.

  • skipIndCalibration (False), (bool):

    Option for skipping the indirect calibration;

  • IREndManualCut (None), (float):

    Manual cut of the calculated impulsive response;

  • IRStartManualCut (None), (float):

    Manual cut of the calculated impulsive response;

  • skipSave (False), (bool):

    Option to skip saving the new MeasuredThings to disc. Usefull when you need to calculated the same impulsive response with different options and don’t want to override the one saved previously.

  • getDict (dict):

    Dict with the calculated MeasuredThings, with filenames as keys and the MeasuredThing itself as values. e.g.:

    >>> getDict = {'roomir_S1-R1_O1-Mic1_SWP19_1':
                       roomir.MeasuredThing}
    
calibrate_res(getDict, calibrationTake=1, skipInCompensation=False, skipSave=False)

Gets the dict returned from the roomir.MeasuremenData.get() method, apply the indirect calibration, store to disc, and return the correspondent getDict. Check the input arguments below for options.

This method generates new MeasuredThings with a kind derived from the measured kind. The possible conversions are:

  • ‘roomres’ MeasuredThing kind to a ‘calibrated-roomres’;

  • ‘noisefloor’ to ‘calibrated-noisefloor’;

  • ‘sourcerecalibration’ to ‘calibrated-sourcerecalibration’;

  • getDict (), (dict):

    Dict from the roomir.MeasurementData.get(…) method;

  • calibrationTake (1), (int):

    Choose the take from the ‘miccalibration’ MeasuredThing for the indirect calibration of the correspondent input channels;

  • skipInCompensation (False), (bool):

    Option for skipping compensation on the input chain with the provided response to the MeasurementSetup;

  • skipSave (False), (bool):

    Option to skip saving the new MeasuredThings to disc.

  • getDict (dict):

    Dict with the calculated MeasuredThings, with filenames as keys and the MeasuredThing itself as values. e.g.:

    >>> getDict = {'calibrated-roomres_S1-R1_O1-Mic1_SWP19_1':
                       roomir.MeasuredThing}
    
class pytta.roomir.TakeMeasure(MS, kind, inChSel, receiversPos=None, excitation=None, outChSel=None, outputAmplification=0, sourcePos=None, tempHumid=None)

Class intended to hold a measurement take configuration, take the measurement, and obtain the MeasuredThing for each channel/group in inChSel property.

  • MS (), (roomir.MeasurementSetup):

    The setup of the current measurement;

  • tempHumid (), (pytta.classes.lju3ei1050):

    Object for communication with the LabJack U3 with the probe EI1050 for acquiring temperature and humidity. For more information check pytta.classes.lju31050 docstrings;

  • kind (), (string):

    Possible measurement kinds:

    • ‘roomres’: room response to the excitation signal;

    • ‘noisefloor’: acquire noise floor for measurement quality

      analysis;

    • ‘miccalibration’: acquire calibrator signal (94dB SPL @ 1kHz)

      for indirect calibration;

    • ‘channelcalibration’: acquire response of the ouput connected

      to the input channel;

    • ‘sourcerecalibration’: acquire recalibration response for

      Strength Factor measurement. For more information check pytta.rooms.strength_factor doctrings.

  • inChSel (), (list):

    Active input channels (or groups) for the current take. E.g.:

    >>> inChSel = ['Mic2', 'AR2']
    
  • receiversPos (), (list):

    List with the positions of each input channel/group. E.g.:

    >>> receiversPos = ['R2', 'R4']
    
  • excitation (), (string):

    Code of the excitation signal provided to the MeasurementSetup. E.g.:

    >>> excitation = 'SWP19'
    
  • outChSel (), (string):

    Code of the output channel provided to the MeasurementSetup. E.g.:

    >>> outChSel = 'O1'
    
  • outputAmplification (0) (float):

    Output amplification in dB;

  • sourcePos (), (string):

    Source’s position. E.g.:

    >>> sourcePos = 'R1'
    
  • run():

    Acquire data;

  • measuredThings (list):

    Contains the MeasuredThing objects resultant from the measurement take.

run()

Take measurement (initializate acquisition).

Has no input arguments.

Usage:

>>> myTake.run()
>>> D.save_take(myTake)
class pytta.roomir.MeasuredThing(kind='', arrayName='', measuredSignals=[], timeStamps=[], tempHumids=[], inChannels=None, sourcePos=None, receiverPos=None, excitation=None, outChannel=None, outputAmplification=0)

Obtained through a roomir.TakeMeasure object. Contains information of a measurement take for one source-receiver configuration. Shouldn’t be instantiated by user.

  • kind (str):

    Possible kinds for a MeasuredThing:

    • ‘roomres’;

    • ‘roomir’ (‘roomres’ after IR calculation);

    • ‘noisefloor’;

    • ‘miccalibration’

    • ‘sourcerecalibration’;

    • ‘recalibir’ (‘sourcerecalibration’ after IR calculation);

    • ‘channelcalibration’;

    • ‘channelcalibir’ (‘channelcalibration’ after IR calculation);

  • arrayName (str):

    Code of the input channel or group (array);

  • measuredSignals (list):

    Contains the resultant SignalObjs or ImpulsiveResponses;

  • timeStamps (list):

    Contains the timestamps for each measurement take;

  • tempHumids (list):

    Contains the temperature and humidity readings for each measurement take;

  • inChannels (roomir._MeasurementChList):

    Measurement channel list object. Identifies the used soundcard’s input channels;

  • sourcePos (str):

    Source position;

  • receiverPos (str):

    Receiver’s (microphone or array) position;

  • excitation (str):

    Excitation signal code in MeasurementSetup;

  • outChannel (roomir._MeasurementChList):

    Measurement channel list object. Identifies the used soundcard’s output channel;

  • outputAmplification (float):

    Output amplification in dB set for the take;

  • outputLinearGain (float):

    Output amplification in linear scale;

  • numChannels (float):

    The number of channels;

  • averages (int):

    The number of averages;

class pytta.roomir.MeasurementPostProcess(nthOct=3, minFreq=100, maxFreq=10000)

Holds a measurement post processing session.

  • nthOct (3), (int):

    Number of bands per octave;

  • minFreq (100), (float):

    Minimum analysis’ frequency;

  • maxFreq (1000), (float):

    Minimum analysis’ frequency;

  • RT (getDict, decay, IREndManualCut)

    Calculates the average reverberation time for each source-receiver pair from the provided getDict. Also calculates a 95% confidence interval from a T-Student distribution, which is dependent on the number of averages. For more information on reverberation time calculation go to pytta.rooms.reverberation_time

  • G (Lpe_avgs, Lpe_revCh, V_revCh, T_revCh, Lps_revCh, Lps_inSitu):

    Calculates the strength factor from the G terms provided by several getDict-like dicts from other G methods of this class.

  • G_Lpe_inSitu (roomirsGetDict, IREndManualCut):

    Calculates the sound exposure level of the room impulsive response. For more information about this G term go to pytta.rooms.G_Lpe;

  • G_Lpe_revCh(roomirsGetDict, IREndManualCut):

    Calculates the sound exposure level of the reverberation chamber’s impulsive response. For more information about this G term go to pytta.rooms.G_Lpe;

  • G_Lps (sourcerecalibirGetDict):

    Calculates the sound exposure level of the recalibration impulsive response. For more information about this G term go to pytta.rooms.G_Lps;

  • G_T_revCh (roomirsGetDict, IREndManualCut, T):

    Calculates the mean reverberation time of the reverberation chamber;

For further information check the specific method’s docstrings.

RT(roomirsGetDict, decay=20, IREndManualCut=None)

Calculates the average reverberation time for each source-receiver pair from the dict provided by the roomir.MeasurementData.get method.

Also calculates a 95% confidence interval from a T-Student distribution, which is dependent on the number of averages. For more information on reverberation time calculation go to pytta.rooms.reverberation_time.

  • getDict (‘Time [s]’), (str):

    a dict from the roomir.MeasurementData.get method containing MeasuredThings of the type ‘roomir’ (room impulsive response);

  • decay (20), (int):

    dynamic range of the line fit;

  • IREndManualCut (None), (float):

    remove the end of the impulsive response from IREndManualCut, given in seconds;

  • TR (dict):

    a dict containing the mean reverberation time (Analysis) for each source-receiver configuration, which is a key;

G_Lps(recalibirsGetDict)

Calculates the mean sound exposure level from the recalibration impulsive responses. For more information about this G term go to pytta.rooms.G_Lps;

  • G_Lps (), (dict from rmr.D.get(…)):

    a dict from the roomir.MeasurementData.get method containing MeasuredThings of the type ‘recalibir’;

  • finalLps (Analysis):

    an Analysis object with the averaged recalibration exposure level;

G_Lpe_inSitu(roomirsGetDict, IREndManualCut=None)

Calculates the room impulsive response’ sound exposure level for each source-receiver cfg. For more information about this G term go to pytta.rooms.G_Lpe;

Receives

  • roomirsGetDict (), ():

    a dict from the roomir.MeasurementData.get method containing MeasuredThings of the type ‘roomir’ (room impulsive response);

  • IREndManualCut (None), (float):

    remove the end of the impulsive response from IREndManualCut, given in seconds;

  • Lpe_avgs (dict):

    a dict containing a list with the sound exposure level averages (Analyses) for each source-receiver configuration, which is a key;

G_Lpe_revCh(roomirsGetDict, IREndManualCut=None)

Calculates the mean sound exposure level of the reverberation chamber’s impulsive response. For more information about this G term go to pytta.rooms.G_Lpe;

  • roomirsGetDict (), ():

    a dict from the roomir.MeasurementData.get method containing MeasuredThings of the type ‘roomir’ (room impulsive response);

  • IREndManualCut (None), (float):

    remove the end of the impulsive response from IREndManualCut, given in seconds;

  • Lpe (Analysis):

    an Analysis with the mean sound exposure level calculated from all the reverberation chamber’s impulsive responses;

G(Lpe_avgs, Lpe_revCh, V_revCh, T_revCh, Lps_revCh, Lps_inSitu)

Calculates the mean strength factor for each source-receiver configuration with the G terms provided by other methods of this class. Also provides some basic statistical treatment.

For further information on the recalibration method (to correct changes on the source’s sound power) check:

Christensen, C. L.; Rindel, J. H. APPLYING IN-SITU RECALIBRATION FOR SOUND STRENGTH MEASUREMENTS IN AUDITORIA.

  • Lpe_avgs (), (dict from rmr.get(…)):

    a dict provided by the rmr.get(…) method. Calculates a mean G for all source-receiver configurations provided with the dict. Also calculates the 95% confidence interval for a T-Student distribution;

  • Lpe_revCh (), (Analysis):

    a pytta.Analysis object with the mean exposure level inside the reverberation chamber during the source calibration (sound power measurement);

  • V_revCh (), (float):

    the volume of the reverberation chamber;

  • T_revCh (), (Analysis):

    a pytta.Analysis object for the reverberation chamber’s reverberation time;

  • Lps_revCh (), (Analysis)

    the exposure level of the recalibration procedure in the reverberation chamber;

  • Lps_inSitu (), (Analysis):

    the exposure level of the recalibration procedure in situ;

Return (type):

  • G (dict):

    a dict containing the mean G (Analysis) for each source-receiver configuration, which is a key;

G_T_revCh(roomirsGetDict, IREndManualCut=None, T=20)

Calculates the mean reverberation time of the reverberation chamber;

  • roomirsGetDict (), ():

    a dict from the roomir.MeasurementData.get method containing MeasuredThings of the type ‘roomir’ (room impulsive response);

  • IREndManualCut (None), (float):

    remove the end of the impulsive response from IREndManualCut, given in seconds;

  • T_revCh (Analysis):

    an Analysis with the mean reverberation time calculated from all the reverberation chamber’s impulsive responses;

pytta.roomir.med_load(medname)

Loads a measurement to continue measuring or either post processing.

Usage:

>>> MS, D = roomir.med_load('measurement name')
  • medname (), (str):

    the measurement name given in the MeasurementSetup object instantiation;

  • (roomir.MeasurementSetup, roomir.MeasurementData) (tuple)