SPPAS 4.22

https://sppas.org/

Module sppas.src.annotations

Class sppasRMS

Description

SPPAS integration of the automatic RMS estimator on intervals.

Estimate the root-mean-square of segments, i.e. sqrt(sum(S_i^2)/n). This is a measure of the power in an audio signal.

Constructor

Create a new sppasRMS instance.

Parameters
  • log: (sppasLog) Human-readable logs.
View Source
def __init__(self, log=None):
    """Create a new sppasRMS instance.

    :param log: (sppasLog) Human-readable logs.

    """
    super(sppasRMS, self).__init__('rms.json', log)
    self.__rms = IntervalsRMS()

Public functions

fix_options

Fix all options.

Parameters
  • options: (sppasOption)
View Source
def fix_options(self, options):
    """Fix all options.

        :param options: (sppasOption)

        """
    for opt in options:
        key = opt.get_key()
        if key == 'tiername':
            self.set_tiername(opt.get_value())
        elif key == 'minmax':
            self.set_minmax(opt.get_value())
        elif 'pattern' in key:
            self._options[key] = opt.get_value()
        else:
            raise AnnotationOptionError(key)

set_tiername

Fix the tiername option.

Parameters
  • tier_name: (str)
View Source
def set_tiername(self, tier_name):
    """Fix the tiername option.

        :param tier_name: (str)

        """
    self._options['tiername'] = sppasUnicode(tier_name).to_strip()

set_minmax

Fix the minmax option.

Parameters
  • value: (bool) Add 2 more tiers in the result with min and max
View Source
def set_minmax(self, value):
    """Fix the minmax option.

        :param value: (bool) Add 2 more tiers in the result with min and max

        """
    self._options['minmax'] = bool(value)

estimator

Estimate RMS on all non-empty intervals.

Parameters
  • tier: (sppasTier)
View Source
def estimator(self, tier):
    """Estimate RMS on all non-empty intervals.

        :param tier: (sppasTier)

        """
    rms_avg = sppasTier('RMS')
    rms_values = sppasTier('RMS-values')
    rms_mean = sppasTier('RMS-mean')
    rms_min = sppasTier('RMS-min')
    rms_max = sppasTier('RMS-max')
    rms_avg.set_media(tier.get_media())
    rms_values.set_media(tier.get_media())
    rms_mean.set_media(tier.get_media())
    rms_min.set_media(tier.get_media())
    rms_max.set_media(tier.get_media())
    for ann in tier:
        content = serialize_labels(ann.get_labels())
        if len(content) == 0:
            continue
        begin = ann.get_lowest_localization()
        end = ann.get_highest_localization()
        self.__rms.estimate(begin.get_midpoint(), end.get_midpoint())
        rms_tag = sppasTag(self.__rms.get_rms(), 'int')
        rms_avg.create_annotation(ann.get_location().copy(), sppasLabel(rms_tag))
        labels = list()
        for value in self.__rms.get_values():
            labels.append(sppasLabel(sppasTag(value, 'int')))
        rms_values.create_annotation(ann.get_location().copy(), labels)
        rms_mean_tag = sppasTag(self.__rms.get_mean(), 'float')
        rms_mean.create_annotation(ann.get_location().copy(), sppasLabel(rms_mean_tag))
        rms_min_tag = sppasTag(self.__rms.get_min(), 'float')
        rms_min.create_annotation(ann.get_location().copy(), sppasLabel(rms_min_tag))
        rms_max_tag = sppasTag(self.__rms.get_max(), 'float')
        rms_max.create_annotation(ann.get_location().copy(), sppasLabel(rms_max_tag))
    return (rms_avg, rms_values, rms_mean, rms_min, rms_max)

get_inputs

Return the channel and the tier with ipus.

Parameters
  • input_files: (list)
Raises

NoTierInputError

Returns
  • (Channel, sppasTier)
View Source
def get_inputs(self, input_files):
    """Return the channel and the tier with ipus.

        :param input_files: (list)
        :raise: NoTierInputError
        :return: (Channel, sppasTier)

        """
    ext = self.get_input_extensions()
    audio_ext = ext[0]
    annot_ext = ext[1]
    tier = None
    channel = None
    audio_filename = ''
    for filename in input_files:
        fn, fe = os.path.splitext(filename)
        if channel is None and fe in audio_ext:
            audio_speech = audioopy.aio.open(filename)
            n = audio_speech.get_nchannels()
            if n != 1:
                audio_speech.close()
            idx = audio_speech.extract_channel()
            channel = audio_speech.get_channel(idx)
            audio_filename = filename
            audio_speech.close()
        elif tier is None and fe in annot_ext:
            parser = sppasTrsRW(filename)
            trs_input = parser.read()
            tier = trs_input.find(self._options['tiername'], case_sensitive=False)
    if tier is None:
        logging.error("Tier with name '{:s}' not found.".format(self._options['tiername']))
        raise NoTierInputError
    if tier.is_interval() is False:
        logging.error('The tier should be of type: Interval.')
        raise AnnDataTypeError(tier.get_name(), 'IntervalTier')
    if tier.is_empty() is True:
        raise EmptyInputError(self._options['tiername'])
    if channel is None:
        logging.error('No audio file found or invalid one. An audio file with only one channel was expected.')
        raise NoChannelInputError
    extm = os.path.splitext(audio_filename)[1].lower()[1:]
    media = sppasMedia(os.path.abspath(audio_filename), mime_type='audio/' + extm)
    tier.set_media(media)
    return (channel, tier)

run

Run the automatic annotation process on an input.

Input file is a tuple with 2 files: the audio file and the annotation file

Parameters
  • input_files: (list of str) (audio, time-aligned items)
  • output: (str) the output name
Returns
  • (sppasTranscription)
View Source
def run(self, input_files, output=None):
    """Run the automatic annotation process on an input.

        Input file is a tuple with 2 files:
        the audio file and the annotation file

        :param input_files: (list of str) (audio, time-aligned items)
        :param output: (str) the output name
        :returns: (sppasTranscription)

        """
    channel, tier = self.get_inputs(input_files)
    self.__rms.set_channel(channel)
    rms_avg, rms_values, rms_mean, rms_min, rms_max = self.estimator(tier)
    trs_output = sppasTranscription(self.name)
    trs_output.set_meta('annotation_result_of', input_files[0])
    trs_output.append(rms_avg)
    trs_output.append(rms_values)
    trs_output.append(rms_mean)
    if self._options['minmax'] is True:
        trs_output.append(rms_min)
        trs_output.append(rms_max)
    if output is not None:
        if len(trs_output) > 0:
            output_file = self.fix_out_file_ext(output)
            parser = sppasTrsRW(output_file)
            parser.write(trs_output)
            return [output_file]
        else:
            raise EmptyOutputError
    return trs_output

get_output_pattern

Pattern this annotation uses in an output filename.

View Source
def get_output_pattern(self):
    """Pattern this annotation uses in an output filename."""
    return self._options.get('outputpattern', '-rms')

get_input_patterns

Pattern this annotation expects for its input filename.

View Source
def get_input_patterns(self):
    """Pattern this annotation expects for its input filename."""
    return [self._options.get('inputpattern1', ''), self._options.get('inputpattern2', '-palign')]

get_input_extensions

Extensions that the annotation expects for its input filename.

View Source
@staticmethod
def get_input_extensions():
    """Extensions that the annotation expects for its input filename."""
    return [sppasFiles.get_informat_extensions('AUDIO'), sppasFiles.get_informat_extensions('ANNOT_ANNOT')]