audio.py 1.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
import numpy as np
import io
import soundfile


class AudioSegment(object):
    """Monaural audio segment abstraction.
    """

    def __init__(self, samples, sample_rate):
        if not samples.dtype == np.float32:
            raise ValueError("Sample data type of [%s] is not supported.")
        self._samples = samples
        self._sample_rate = sample_rate
        if self._samples.ndim >= 2:
            self._samples = np.mean(self._samples, 1)

    @classmethod
    def from_file(cls, filepath):
        samples, sample_rate = soundfile.read(filepath, dtype='float32')
        return cls(samples, sample_rate)

    @classmethod
    def from_bytes(cls, bytes):
        samples, sample_rate = soundfile.read(
            io.BytesIO(bytes), dtype='float32')
        return cls(samples, sample_rate)

    def apply_gain(self, gain):
        self.samples *= 10.**(gain / 20.)

    def resample(self, target_sample_rate):
        raise NotImplementedError()

    def change_speed(self, rate):
        raise NotImplementedError()

    @property
    def samples(self):
        return self._samples.copy()

    @property
    def sample_rate(self):
        return self._sample_rate

    @property
    def duration(self):
        return self._samples.shape[0] / float(self._sample_rate)


class SpeechSegment(AudioSegment):
    def __init__(self, samples, sample_rate, transcript):
        AudioSegment.__init__(self, samples, sample_rate)
        self._transcript = transcript

    @classmethod
    def from_file(cls, filepath, transcript):
        audio = AudioSegment.from_file(filepath)
        return cls(audio.samples, audio.sample_rate, transcript)

    @classmethod
    def from_bytes(cls, bytes, transcript):
        audio = AudioSegment.from_bytes(bytes)
        return cls(audio.samples, audio.sample_rate, transcript)

    @property
    def transcript(self):
        return self._transcript