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)
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