Beispiel #1
0
    def externalize(self, hrtf=None):
        """
        Convolve the sound with a smoothed HRTF to evoke the impression of an external sound source without adding
        directional information, see Kulkarni & Colburn (1998) for why that works.

        Arguments:
            hrtf (None | slab.HRTF): The HRTF to use. If None use the one from the MIT KEMAR mannequin. The sound
                source at zero azimuth and elevation is used for convolution so it has to be present in the HRTF.
        Returns:
            (slab.Binaural): externalized copy of the instance.
        """
        if hrtf is None:
            hrtf = HRTF.kemar()  # load KEMAR as default
        # get HRTF for [0,0] direction:
        idx_frontal = numpy.where((hrtf.sources[:, 1] == 0) & (hrtf.sources[:, 0] == 0))[0][0]
        if not idx_frontal.size: # idx_frontal is empty
            raise ValueError('No frontal direction [0,0] found in HRTF.')
        _, h = hrtf.data[idx_frontal].tf(channels=0, n_bins=12, show=False)  # get low-res version of HRTF spectrum
        h[0] = 1  # avoids low-freq attenuation in KEMAR HRTF (unproblematic for other HRTFs)
        resampled_signal = copy.deepcopy(self)
        # if sound and HRTF has different samplerates, resample the sound, apply the HRTF, and resample back:
        resampled_signal = resampled_signal.resample(hrtf.data[0].samplerate)  # resample to hrtf rate
        filt = Filter(10**(h/20), fir=False, samplerate=hrtf.data[0].samplerate)
        filtered_signal = filt.apply(resampled_signal)
        filtered_signal = filtered_signal.resample(self.samplerate)
        return filtered_signal
Beispiel #2
0
 def externalize(self, hrtf=None):
     '''
     Convolve the sound object in place with a smoothed HRTF (KEMAR
     if no slab.HRTF object is supplied) to evoke the impression of
     an external sound source without adding directional information.
     See Kulkarni & Colburn (1998) for why that works.
     '''
     from slab import DATAPATH
     if not hrtf:
         hrtf = HRTF(DATAPATH +
                     'mit_kemar_normal_pinna.sofa')  # load the hrtf file
     idx_frontal = numpy.where((hrtf.sources[:, 1] == 0) & (
         hrtf.sources[:, 0] == 0))[0][0]  # get HRTF for [0,0] direction
     w, h = hrtf.data[idx_frontal].tf(channels=0, nbins=12,
                                      plot=False)  # get low-res spectrum
     # samplerate shoulf be hrtf.data[0].samplerate, hack to avoid having to resample, ok for externalization if rate are similar
     filt = Filter(10**(h / 20), fir=False, samplerate=self.samplerate)
     out = filt.apply(copy.deepcopy(self))
     return out