<commit_before>'''Module of classes and function for the extraction of and analysis
of an audio sample into a spectrum and any related data.
'''

import numpy as np
import scipy.signal
import os
import scipy.io.wavfile as wav
import subprocess
from matplotlib import pyplot as plt

class Bbox(object):
    """
    object representing a 2D time-freq "slice" of a spectrogram
    spec .. spectrum object
    """
    def __init__(self, spec, start_freq=None, end_freq=None, start_time=None, end_time=None):
        self.start_freq = start_freq if start_freq is not None else 0.
        self.end_freq = end_freq if end_freq is not None else spec.freqs.max()
        self.start_time = start_time if start_time is not None else 0.
        self.end_time = end_time if end_time is not None else spec.duration
        self.spec = spec
    def ix(self):
        spec = self.spec
        start_freq_ix = np.argmin(np.abs(spec.freqs-self.start_freq))
        end_freq_ix = np.argmin(np.abs(spec.freqs-self.end_freq))
        start_time_ix = np.argmin(np.abs(spec.times-self.start_time))
        end_time_ix =  np.argmin(np.abs(spec.times-self.end_time))
        return slice(start_freq_ix, end_freq_ix), slice(start_time_ix, end_time_ix)

class Spectrum(object):
    """
    spectrogram of a sound
    sound .. Sound object
    """
    def __init__(self, sound, framesz=.2, hop=.1):
        self.sound = sound
        self.framesz = framesz
        self.hop = hop
        self.duration = sound.duration
        self.complex_arr, self.samplerate, self.freqs = stft(
            sound.data, sound.samplerate, self.framesz, self.hop
        )
        self._calc()
        self.times = np.linspace(0., self.duration, self.complex_arr.shape[0])

    def _calc(self):
        self.db_arr = 20.*np.log10(np.absolute(self.complex_arr))

    def isolate(self, start_freq=None, end_freq=None, start_time=None, end_time=None):
        bbox = Bbox(self, start_freq, end_freq, start_time, end_time)
        freq_slice, time_slice = bbox.ix()
        cpy = self.complex_arr[freq_slice, time_slice].copy()
        self.complex_arr[:,:]=.000001+.000001j
        self.complex_arr[freq_slice, time_slice] = cpy
        self._calc()

    def plot(self, *args, **kwargs):
        return spc_plot(self, **kwargs)

    def to_sound(self):
        data = istft(self.complex_arr, self.sound.samplerate, self.framesz, self.hop)
        s = Sound()
        s.from_array(data, self.sound.samplerate)
        return s


def spc_plot(self, start_freq=None, end_freq=None, start_time=None, end_time=None):
    """
    generate plot of all of or bbox of spectrogram
    self ... spectrogam object<commit_msg>added timeslice method<commit_after>'''Module of classes and function for the extraction of and analysis
of an audio sample into a spectrum and any related data.
'''

import numpy as np
import scipy.signal
import os
import scipy.io.wavfile as wav
import subprocess
from matplotlib import pyplot as plt

class Bbox(object):
    """
    object representing a 2D time-freq "slice" of a spectrogram
    spec .. spectrum object
    """
    def __init__(self, spec, start_freq=None, end_freq=None, start_time=None, end_time=None):
        self.start_freq = start_freq if start_freq is not None else 0.
        self.end_freq = end_freq if end_freq is not None else spec.freqs.max()
        self.start_time = start_time if start_time is not None else 0.
        self.end_time = end_time if end_time is not None else spec.duration
        self.spec = spec
    def ix(self):
        spec = self.spec
        start_freq_ix = np.argmin(np.abs(spec.freqs-self.start_freq))
        end_freq_ix = np.argmin(np.abs(spec.freqs-self.end_freq))
        start_time_ix = np.argmin(np.abs(spec.times-self.start_time))
        end_time_ix =  np.argmin(np.abs(spec.times-self.end_time))
        return slice(start_freq_ix, end_freq_ix), slice(start_time_ix, end_time_ix)

class Spectrum(object):
    """
    spectrogram of a sound
    sound .. Sound object
    """
    def __init__(self, sound, framesz=.2, hop=.1):
        self.sound = sound
        self.framesz = framesz
        self.hop = hop
        self.duration = sound.duration
        self.complex_arr, self.samplerate, self.freqs = stft(
            sound.data, sound.samplerate, self.framesz, self.hop
        )
        self._calc()
        self.times = np.linspace(0., self.duration, self.complex_arr.shape[0])

    def _calc(self):
        self.db_arr = 20.*np.log10(np.absolute(self.complex_arr))

    def isolate(self, start_freq=None, end_freq=None, start_time=None, end_time=None):
        bbox = Bbox(self, start_freq, end_freq, start_time, end_time)
        freq_slice, time_slice = bbox.ix()
        cpy = self.complex_arr[freq_slice, time_slice].copy()
        self.complex_arr[:,:]=.000001+.000001j
        self.complex_arr[freq_slice, time_slice] = cpy
        self._calc()

    def plot(self, *args, **kwargs):
        return spc_plot(self, **kwargs)

    def to_sound(self):
        """
        return a sound object converted from this spectrum
        """
        data = istft(self.complex_arr, self.sound.samplerate, self.framesz, self.hop)
        s = Sound()
        s.from_array(data, self.sound.samplerate)
        return s

    def timeslice(self, time):
        """
        return 1D slice of the decibel array
        time .. slice location (s)
        """
        time_ix = np.argmin(np.abs(self.times-time))
        return self.db_arr[:, time_ix]

def spc_plot(self, start_freq=None, end_freq=None, start_time=None, end_time=None):
    """
    generate plot of all of or bbox of spectrogram
    self ... spectrogam object
{'fraction_non_alphanumeric': 0.10692157904053814, 'fraction_numerical': 0.008320056647194193, 'mean_word_length': 2.8357094365241005, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '966690', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1852, 'n_words': 464}