Пример #1
0
 def interaural_level_spectrum(self, azimuth, level_spectrum_filter=None):
     '''
     Apply a frequency-dependend interaural level difference
     corresponding to a given azimuth to a binaural sound.
     The level difference cues are taken from a filter generated
     with the _make_level_spectrum_filter function from an hrtf
     recording. The default will generate the filter from the MIT
     KEMAR recordings. The left and right channel of the sound
     should have the same level.
     Example:
     >>> noise = Binaural.pinknoise(kind='diotic')
     >>> noise.interaural_level_spectrum(azimuth=-45).play()
     '''
     if not level_spectrum_filter:
         ils = Binaural._make_level_spectrum_filter(
         )  # TODO: should cache this as a file in /data or global
     ils = ils[:, 1:]  # remove the frequency values (not necessary here)
     azis = ils[0, :]  # get vector of azimuths in ils filter bank
     ils = ils[1:, :]  # the rest is the filter
     # interpolate levels at azimuth
     levels = [
         numpy.interp(azimuth, azis, ils[:, i]) for i in range(ils.shape[1])
     ]
     fbank = Filter.cos_filterbank(length=self.nsamples,
                                   samplerate=self.samplerate)
     subbands_left = fbank.apply(self.left)
     subbands_right = fbank.apply(self.right)
     # change subband levels:
     subbands_left.level = subbands_left.level + levels / 2
     subbands_right.level = subbands_right.level - levels / 2
     out_left = Filter.collapse_subbands(subbands_left, filter_bank=fbank)
     out_right = Filter.collapse_subbands(subbands_right, filter_bank=fbank)
     return Binaural([out_left, out_right])
Пример #2
0
    def interaural_level_spectrum(self, azimuth, ils=None):
        """
        Apply an interaural level spectrum, corresponding to a sound sources azimuth, to a
        binaural sound. The interaural level spectrum consists of frequency specific interaural level differences
        which are computed from a head related transfer function (see the `make_interaural_level_spectrum()` method).
        The binaural sound is divided into frequency sub-bands and the levels of each sub-band are set according to
        the respective level in the interaural level spectrum. Then, the sub-bands are summed up again into one
        binaural sound.

        Arguments:
            azimuth (int | float): azimuth for which the interaural level spectrum is calculated.
            ils (dict): interaural level spectrum to apply.  If None, `make_interaural_level_spectrum()` is called.
            For repeated use, it is better to generate and keep the ils in a variable to avoid re-computing it.
        Returns:
            (slab.Binaural): A binaural sound with the interaural level spectrum corresponding to the given azimuth.
        Examples::

            noise = slab.Binaural.pinknoise(kind='diotic')
            ils = slab.Binaural.make_interaural_level_spectrum() # using default KEMAR HRTF
            noise.interaural_level_spectrum(azimuth=-45, ils=ils).play()
        """
        if ils is None:
            ils = Binaural.make_interaural_level_spectrum()
        ils_samplerate = ils['samplerate']
        original_samplerate = self.samplerate
        azis = ils['azimuths']
        level_diffs = ils['level_diffs']
        levels = numpy.array([numpy.interp(azimuth, azis, level_diffs[i, :]) for i in range(level_diffs.shape[0])])
        # resample the signal to the rate of the HRTF from which the filter was computed:
        resampled = self.resample(samplerate=ils_samplerate)
        fbank = Filter.cos_filterbank(length=resampled.n_samples, samplerate=ils_samplerate, pass_bands=True)
        subbands_left = fbank.apply(resampled.left)
        subbands_right = fbank.apply(resampled.right)
        # change subband levels:
        subbands_left.level = subbands_left.level + levels / 2
        subbands_right.level = subbands_right.level - levels / 2
        out_left = Filter.collapse_subbands(subbands_left, filter_bank=fbank)
        out_right = Filter.collapse_subbands(subbands_right, filter_bank=fbank)
        out = Binaural([out_left, out_right])
        return out.resample(samplerate=original_samplerate)