Пример #1
0
    def to_pcm_audio(self):

        oscillator = Oscillator(self._frequency, self._phase)
        envelope = Envelope()
        for point in self._amplitude_envelope_points:
            envelope.add_point(point)

        samples = oscillator.get_output(self._sample_times)
        samples *= envelope.get_output(self._sample_times)

        if self._base_pcm_audio:
            samples += self._base_pcm_audio.samples

        return PcmAudio(self._reference_pcm_audio.sampling_rate, samples)
Пример #2
0
def get_sound_factory(reference_pcm_audio, base_pcm_audio=None):

    class Sound(_Sound):

        _reference_pcm_audio = reference_pcm_audio
        _reference_spectrogram = Spectrogram(reference_pcm_audio.samples)
        _base_pcm_audio = base_pcm_audio
        _maximal_amplitude = numpy.max(
            [magnitudes.max() for magnitudes in _reference_spectrogram])

        _sample_times = numpy.linspace(
            0, reference_pcm_audio.duration, len(reference_pcm_audio.samples))

    base_sound_spectrogram = (
        Spectrogram(base_pcm_audio.samples) if base_pcm_audio else None)

    # Compute and overwrite maximal frequency

    minimal_significant_amplitude = 20.0

    significant_frequency_indices = [
        index for index, amplitudes in enumerate(
            zip(*Sound._reference_spectrogram))
        if numpy.max(amplitudes) >= minimal_significant_amplitude]

    maximal_frequency_index = numpy.max(significant_frequency_indices)

    Sound._maximal_frequency = Sound._reference_spectrogram.get_frequencies(
        Sound._reference_pcm_audio.sampling_rate)[maximal_frequency_index]

    # Compute and overwrite minimal frequency

    # if base_pcm_audio:

    #     significant_base_frequency_indices = [
    #         index for index, amplitudes in enumerate(
    #             zip(*base_sound_spectrogram))
    #         if numpy.max(amplitudes) >= minimal_significant_amplitude]

    #     minimal_frequency_index = numpy.min([
    #         index for index in significant_frequency_indices
    #         if index not in significant_base_frequency_indices])

    #     Sound._minimal_frequency = base_sound_spectrogram.get_frequencies(
    #         base_pcm_audio.sampling_rate)[minimal_frequency_index]
    #     print Sound._minimal_frequency

    # Compute amplitude limit envelope

    envelope = Envelope()

    frame_length = (
        Sound._reference_pcm_audio.duration / len(Sound._reference_spectrogram))

    for frame_index, magnitudes in enumerate(Sound._reference_spectrogram):
        if base_sound_spectrogram:
            magnitudes = magnitudes - base_sound_spectrogram[frame_index]
        envelope.add_point(
            Envelope.Point(
                time=frame_length * (frame_index + 0.5),
                value=numpy.max(magnitudes)
            )
        )

    Sound._amplitude_limit_envelope = envelope

    # Compute weights by frequencies

    def weight_by_frequency(frequency):
        """ To calculate weights this function uses a technique called
        "A-weighting" """
        return (12200 ** 2) * (frequency ** 4) / (
            (frequency ** 2 + 20.6 ** 2) *
            numpy.sqrt(frequency ** 2 + 107.7 ** 2) *
            numpy.sqrt(frequency ** 2 + 737.9 ** 2) *
            (frequency ** 2 + 12200 ** 2)
        )

    Sound._frequencies_weights = numpy.array(
        map(weight_by_frequency, Sound._reference_spectrogram.get_frequencies(
            Sound._reference_pcm_audio.sampling_rate)))

    return Sound