Esempio n. 1
0
 def __enter__(self):
     """Allow AudioFile object to be opened by 'with' statements"""
     self.logger.debug("Opening soundfile {0}".format(self.filepath))
     if self.mode == 'r':
         if not os.path.exists(self.filepath):
             raise IOError(
                 "Cannot open {0} for reading as it cannot be "
                 "found.".format(self.filepath)
             )
         self.pysndfile_object = pysndfile.PySndfile(
             self.filepath,
             mode=self.mode
         )
         self.samplerate = self.get_samplerate()
         self.format = self.get_format()
         self.channels = self.get_channels()
         self.frames = self.get_frames()
         return self
     else:
         self.pysndfile_object = pysndfile.PySndfile(
             self.filepath,
             mode=self.mode,
             format=self.format,
             channels=self.channels,
             samplerate=self.samplerate
         )
         return self
Esempio n. 2
0
def main():
    files = [
        ("left ear", "left_ear.wav"),
        ("right ear", "right_ear.wav"),
    ]

    fig = plt.figure()

    for label, fname in files:
        sndfile = pysndfile.PySndfile(fname, 'r')
        if sndfile.channels() != 1:
            raise RuntimeError('please only load mono files')
        Fs = sndfile.samplerate()
        signal = sndfile.read_frames()

        time = np.arange(len(signal)) / float(Fs)
        plt.plot(time, signal, label=label)

    plt.legend(loc='lower center', ncol=2)

    plt.xlim([0.04, 0.07])

    plt.xlabel('time / s')
    plt.ylabel('amplitude')

    plt.suptitle('Comparison of Left and Right Ear Responses')

    #plt.tight_layout()

    plt.show()
    if render:
        plt.savefig('binaural_signals.svg',
                    bbox_inches='tight',
                    dpi=96,
                    format='svg')
Esempio n. 3
0
def sndreadmono(path: str,
                chan: int = 0,
                contiguous=True) -> t.Tuple[np.ndarray, int]:
    """
    Read a sound file as mono. If the soundfile is multichannel,
    the indicated channel `chan` is returned. 

    path: str
        The path to the soundfile
    chan: int
        The channel to return if the file is multichannel
    contiuous: bool
        If True, it is ensured that the returned array is contiguous
        This should be set to True if the samples are to be
        passed to `analyze`, which expects a contiguous array

    Returns: a tuple (samples:np.ndarray, sr:int)
    """
    snd = pysndfile.PySndfile(path)
    data = snd.read_frames(snd.frames())
    sr = snd.samplerate()
    if len(data.shape) == 1:
        mono = data
    else:
        mono = data[:, chan]
    if contiguous:
        mono = np.ascontiguousarray(mono)
    return (mono, sr)
Esempio n. 4
0
    def save_wave(self, filename):
        #        outinfo = pysndfile.construct_format(samplerate=self.samplerate,
        #                                  channels=1,
        #                                  format=(pysndfile.SF_FORMAT_WAV | pysndfile.SF_FORMAT_PCM_16),
        #                                  sections=1,
        #                                  seekable=1)

        o_sfile = pysndfile.PySndfile(filename, mode="w", format='wav')
        self.sfile.seek(self.f_start, 0)
        r = self.sfile.readf_double(
            self.f_end -
            self.f_start)  # read the sound file from f_start to f_end
        r = r / max(abs(r))  # to be between 0 and 1 ?

        # deal with stereo
        ch = self.sfile.info.channels

        # we force into mono by recalling the method we used for the extraction
        if ch == 2:
            if self.method == 2:
                nr = 0.5 * (r[::2] + r[1::2])
            else:
                nr = r[self.method::2]
        else:
            nr = r
        o_sfile.write_frames(nr)
Esempio n. 5
0
File: io.py Progetto: mondeja/waves
    def save(self, filename, buffersize=0b10000000000):
        """Saves an audio instance to a file.

        Parameters
        ----------

        filename : str
          System disk path in which the file will be saved.

        buffsize : int, optional
          Number of bytes stored in memory buffer while reading and writing.
          Only used if the filename to write has been created opening from a
          file in disk.
        """
        with snd.PySndfile(
                filename,
                "w",
                format=65536 | 2,
                channels=self.n_channels,
                samplerate=self.fps,
        ) as target_file:
            target_file.set_strings(self.metadata or {})

            if self.filename:
                for frames in self.iter_chunks(buffersize=buffersize):
                    target_file.write_frames(frames)
            else:
                target_file.write_frames(self.dataframes)
                self.filename = filename
Esempio n. 6
0
def modal_analysis(fnames, max_frequency, room_dim=None):
    plt.figure()

    for fname in fnames:
        sndfile = pysndfile.PySndfile(fname, 'r')
        if sndfile.channels() != 1:
            raise RuntimeError('please only load mono files')
        n = sndfile.frames()
        sr = sndfile.samplerate()
        samples = sndfile.read_frames()
        fft = np.abs(np.fft.rfft(samples))
        freqs = np.fft.rfftfreq(n, d=1. / sr)
        mask = freqs < max_frequency
        fft = 20 * np.log10(fft[mask])
        freqs = freqs[mask]
        plt.plot(freqs, fft, label=os.path.basename(fname))

    if room_dim is not None:
        ranges = [[(x / i) ** 2 for x in range(10)] for i in room_dim]
        all_frequencies = [(SPEED_OF_SOUND / 2) * np.sqrt(a + b + c)
                           for a, b, c in itertools.product(*ranges)]
        filtered_frequencies = [i for i in all_frequencies if i < max_frequency]
        for f in filtered_frequencies:
            plt.axvline(f)

    plt.legend()
    plt.show()
Esempio n. 7
0
def sndwrite(samples: np.ndarray, sr: int, path: str, encoding=None) -> None:
    """
    samples: the samples to write
    sr: the samplerate
    path: the outfile to write the samples to (the extension will determine the format)
    encoding: the encoding of the samples. If None, a default is used, according to the
        extension of the outfile given. Otherwise, a tuple like ('float', 32) or ('pcm', 24)
        is expected (also a string of the form "float32" is supported). Of course, not
        all encodings are supported by each format
    """
    ext = os.path.splitext(path)[1].lower()
    if encoding is None:
        encoding = {
            '.wav': ('float', 32),
            '.aif': ('float', 32),
            '.flac': ('pcm', 24)
        }.get(ext)
        if encoding is None:
            raise ValueError(f"format {ext} not supported")
    fmt = _sndfile_format(ext, encoding)
    numchannels = 1 if len(samples.shape) == 1 else samples.shape[-1]
    snd = pysndfile.PySndfile(path,
                              mode='w',
                              format=fmt,
                              channels=numchannels,
                              samplerate=sr)
    snd.write_frames(samples)
    snd.writeSync()
Esempio n. 8
0
def get_max_level(filename):
    max_value = 0
    buffer_size = 4096
    audio_file = pysndfile.PySndfile(filename, 'r')
    n_samples_left = audio_file.frames()

    while n_samples_left:
        to_read = min(buffer_size, n_samples_left)

        try:
            samples = audio_file.read_frames(to_read)
        except RuntimeError:
            # this can happen with a broken header
            break

        # convert to mono by selecting left channel only
        if audio_file.channels() > 1:
            samples = samples[:, 0]

        max_value = max(max_value, numpy.abs(samples).max())

        n_samples_left -= to_read

    audio_file.close()

    return max_value
Esempio n. 9
0
    def read(cls, filename: str, start=0., end=0.) -> Sample:
        """
        Read samples from `filename`.

        Args:
            filename: the filename of the soundfile
            start: the time to start reading
            end: the end time to stop reading (0 to read until the end)

        Returns:
            a Sample
        """
        sndfile = pysndfile.PySndfile(filename)
        sr = sndfile.samplerate()
        if end == 0:
            endsample = sndfile.frames()
        else:
            endsample = int(sr * end)
            assert endsample < sndfile.frames()
        if start > 0:
            startsample = int(start * sr)
            sndfile.seek(startsample)
        else:
            startsample = 0
        samples = sndfile.read_frames(endsample - startsample)
        return cls(samples, samplerate=sr)
Esempio n. 10
0
def do_plot(ax, image_source_file, waveguide_file, absorption, max_frequency, room_dim):
    ax.set_title('Absorption: ' + str(absorption))

    ax.set_xlabel('frequency / Hz')
    ax.set_ylabel('magnitude / dB')

    if room_dim is not None:
        ranges = [[(x / i) ** 2 for x in range(10)] for i in room_dim]
        all_frequencies = [(SPEED_OF_SOUND / 2) * np.sqrt(a + b + c)
                           for a, b, c in itertools.product(*ranges)]
        filtered_frequencies = [i for i in all_frequencies if i < max_frequency]
        for f in filtered_frequencies:
            ax.axvline(f, color="0.75")

    for fname, label in [(image_source_file, 'image source'), (waveguide_file, 'waveguide')]:
        sndfile = pysndfile.PySndfile(fname, 'r')
        if sndfile.channels() != 1:
            raise RuntimeError('please only load mono files')
        n = sndfile.frames()
        sr = sndfile.samplerate()
        samples = sndfile.read_frames()
        fft = np.abs(np.fft.rfft(samples))
        freqs = np.fft.rfftfreq(n, d=1. / sr)
        mask = freqs < max_frequency
        fft = 20 * np.log10(fft[mask])
        freqs = freqs[mask]
        ax.plot(freqs, fft, label=label)
Esempio n. 11
0
 def __init__(self, fname):
     self.sfile = pysndfile.PySndfile(fname, 'r')
     if self.sfile.info.frames == 0:  # if number of frames in the wav file is equal to 0
         raise IOError, '%s not a correct wav file' % fname
     self.samplerate = self.sfile.info.samplerate  # sample rate = sound file sample rate
     self.frames = self.sfile.info.frames  # number of frames
     self.wav = self.sfile.readf_double(self.frames)
     self.sfile.close()
Esempio n. 12
0
def get_specgram_data(fname):
    sndfile = pysndfile.PySndfile(fname, 'r')
    if sndfile.channels() != 1:
        raise RuntimeError('please only load mono files')
    Fs = sndfile.samplerate()
    signal = sndfile.read_frames()
    pxx, freq, time = mlab.specgram(signal, NFFT=4096, Fs=Fs)
    return pxx, freq, time
Esempio n. 13
0
    def plt_file(ax, file_name, name):
        sndfile = pysndfile.PySndfile(file_name, 'r')
        if sndfile.channels() != 1:
            raise RuntimeError('please only load mono files')
        Fs = sndfile.samplerate()
        signal = sndfile.read_frames()

        time = np.arange(len(signal)) / float(Fs)
        ax.plot(time, signal)
        ax.text(0.001, 0.75, name)
Esempio n. 14
0
 def __init__(self, fname, f_size, timemax=-1):
     self.sfile = pysndfile.PySndfile(fname, 'r')
     if self.sfile.info.frames == 0:  # if number of frames in the wav file is equal to 0
         raise IOError, '%s not a correct wav file' % fname
     self.offset = 0  # current offset
     self.samplerate = self.sfile.info.samplerate  # sample rate = sound file sample rate
     self.frames = self.sfile.info.frames  # number of frames
     self.f_size = f_size
     self.last_time = -1  # flag for interrupted call
     self.nchunk = 0
     self.c_sounds = []
Esempio n. 15
0
def _wavwriter(outfile, sr=44100, bits=32):
    ext = os.path.splitext(outfile)[1][1:][:3].lower()
    assert bits in (32, 64)
    assert ext in ('wav', 'aif')
    encoding = "float%d" % bits
    fmt = pysndfile.construct_format(ext, encoding)
    f = pysndfile.PySndfile(outfile,
                            mode="w",
                            format=fmt,
                            channels=1,
                            samplerate=sr)
    return f
Esempio n. 16
0
def sndwrite(samples, sr, sndfile, encoding=None):
    """
    encoding: 'pcm8', 'pcm16', 'pcm24', 'pcm32', 'flt32'. 
              None to use a default based on the given extension
    """
    ext = os.path.splitext(sndfile)[1].lower()
    if encoding is None:
        encoding = _defaultEncodingForExtension(ext)
    fmt = _getFormat(ext, encoding)
    snd = pysndfile.PySndfile(sndfile,
                              mode='w',
                              format=fmt,
                              channels=_numchannels(samples),
                              samplerate=sr)
    snd.write_frames(samples)
    snd.writeSync()
Esempio n. 17
0
    def __init__(self, fname, offset=0):
        """
        Main init method
        :param fname: wav file name path
        :param offset: starting time
        """
        # keep only the filename
        self.fname = fname.split('/')[-1]
        self.frames = []

        # load file
        self.sfile = pysndfile.PySndfile(fname, 'r')

        self.samplerate = self.sfile.samplerate()
        f_offset = np.floor(offset * self.samplerate)
        self.sfile.seek(f_offset, 0)
        # keep trakc of chunks loaded
        self.nchunk = 0
Esempio n. 18
0
def main():
    files = [
        ("near (1m)", "large.wav", [1]),
        ("far (11.8m)", "large_spaced.wav", [np.sqrt(2**2 + 10**2 + 6**2)]),
    ]

    fig, axes = plt.subplots(nrows=len(files), sharex=True)

    cmap = plt.get_cmap('viridis')

    for (label, fname, distances), ax in zip(files, axes):
        sndfile = pysndfile.PySndfile(fname, 'r')
        if sndfile.channels() != 1:
            raise RuntimeError('please only load mono files')
        Fs = sndfile.samplerate()
        signal = sndfile.read_frames()

        time = np.arange(len(signal)) / float(Fs)
        ax.plot(time, signal)

        ax.set_xlim([0, 0.05])

        ax.set_title(label)
        ax.set_xlabel('time / s')
        ax.set_ylabel('amplitude')

        for dist in distances:
            time = dist / 340.0
            ax.axvline(time, linestyle='dotted', color='red')
            ax.text(time + 0.0005, -0.3, str.format('{0:.3g} s', time))

    plt.suptitle(
        'Differences in Direct Contribution Time for Different Source/Receiver Spacings'
    )

    plt.tight_layout()
    plt.subplots_adjust(top=0.9)

    plt.show()
    if render:
        plt.savefig('spacing_signals.svg',
                    bbox_inches='tight',
                    dpi=96,
                    format='svg')
Esempio n. 19
0
File: io.py Progetto: mondeja/waves
    def from_file(cls, filename):
        """Open a sound from a file.

        Parameters
        ----------

        filename : str
          File path in the disk to open.

        Returns
        -------

        :py:class:`waves.Sound`
          :py:class:`waves.Sound` instance.

        Raises
        ------

        FileNotFoundError
          If the file does not exists in the provided path.
        IsADirectoryError
          If the provided path points to a directory.

        Examples
        --------

        >>> from waves import Sound
        >>>
        >>> Sound.from_file("tests/files/stereo.wav")
        <waves.sound.main.Sound object at ...>
        >>>
        >>> Sound.from_file("tests/files/mono.wav")
        <waves.sound.main.Sound object at ...>
        """
        try:
            return cls.from_sndbuffer(snd.PySndfile(filename, "r"))
        except OSError as err:
            if "No such file or directory" in str(err):
                if os.path.isdir(filename):
                    raise IsADirectoryError(
                        f"'{filename}' is a directory") from None
                raise FileNotFoundError(
                    f"'{filename}' file not found") from None
            raise err
Esempio n. 20
0
def sndread(sndfile, start=0, end=0):
    ext = os.path.splitext(sndfile)[1]

    if ext == '.mp3':
        return _sndread_mp3(sndfile, start=start, end=end)

    sf = pysndfile.PySndfile(sndfile)
    sr = sf.samplerate()
    duration = sf.frames() / sr
    if end <= 0:
        end = duration - end
    if start >= end:
        raise ValueError(f"Asked to read 0 frames: start={start}, end={end}")
    if start > 0:
        if start > duration:
            raise ValueError(
                f"Asked to read after end of file (start={start}, duration={duration}"
            )
        sf.seek(int(start * sr))
    frames = sf.read_frames(int((end - start) * sr))
    return frames, sr
Esempio n. 21
0
def open_sndfile_to_write(filename: str,
                          channels=1,
                          samplerate=48000,
                          bits: int = None) -> pysndfile.PySndfile:
    """
    The format is inferred from the extension (wav, aiff, flac, etc.)

    if bits is given, it is used. otherwise it is inferred from the format
    """
    encodings = {
        'wav': {
            16: "pcm16",
            24: "pcm24",
            32: "float32"
        },
        'aif': {
            16: "pcm16",
            24: "pcm24",
            32: "float32",
        },
        'flac': {
            16: "pcm16",
            24: "pcm24",
            32: "pcm24"
        }
    }
    base, ext = os.path.splitext(filename)
    ext = ext[1:].lower()
    if not ext or ext not in encodings:
        raise ValueError(f"The extension ({ext}) is not supported")

    encoding = encodings[ext].get(bits)
    if encoding is None:
        raise ValueError(f"no format possible for {ext} with {bits} bits")
    fmt = pysndfile.construct_format(ext, encoding)
    return pysndfile.PySndfile(filename,
                               'w',
                               format=fmt,
                               channels=channels,
                               samplerate=samplerate)
Esempio n. 22
0
    def rename_file(self, filename):
        """
        Renames the audio file associated with the object to the name
        specified as an argument

        Arguments:

        - filename: the new path of the audio file.
        """
        # TODO: Consider the race condition here. Is this a problem?
        # Check name doesn't already exist
        if os.path.exists(filename):
            raise ValueError("The filepath: {0} is an already existing file")
        # Check name is a valid file path
        if not os.path.exists(os.path.dirname(filename)):
            raise ValueError("The filepath: {0} does not point to an existing "
                             "directory".format(filename))
        # Check name has the same extension as previous file
        old_ext = os.path.splitext(self.filepath)[1]
        new_ext = os.path.splitext(filename)[1]
        if old_ext != new_ext:
            raise ValueError("The renamed file's extension ({0})"
                             "must be the same as the original extension"
                             "({1})".format(old_ext, new_ext))
        # Delete pysndfile object
        seek = self.get_seek_position()
        del self.pysndfile_object
        # Rename file
        os.rename(self.filepath, filename)
        # Reinitialize pysndfile object
        self.pysndfile_object = pysndfile.PySndfile(
            filename,
            mode='r',
            format=self.format,
            samplerate=self.samplerate,
            channels=self.channels
        )
        self.filepath = filename
        # Re-set seek position to previous position
        self.seek(seek, 0)
Esempio n. 23
0
    def __init__(self,
                 input_filename,
                 fft_size,
                 window_function=numpy.hanning):
        max_level = get_max_level(input_filename)

        self.audio_file = pysndfile.PySndfile(input_filename, 'r')
        self.nframes = self.audio_file.frames()
        self.samplerate = self.audio_file.samplerate()
        self.fft_size = fft_size
        self.window = window_function(self.fft_size)
        self.spectrum_range = None
        self.lower = 100
        self.higher = 22050
        self.lower_log = math.log10(self.lower)
        self.higher_log = math.log10(self.higher)
        self.clip = lambda val, low, high: min(high, max(low, val))

        # figure out what the maximum value is for an FFT doing the FFT of a DC signal
        fft = numpy.fft.rfft(numpy.ones(fft_size) * self.window)
        max_fft = (numpy.abs(fft)).max()
        # set the scale to normalized audio and normalized FFT
        self.scale = 1.0 / max_level / max_fft if max_level > 0 else 1
Esempio n. 24
0
def _read_pysndfile(filename):
    f = pysndfile.PySndfile(filename)
    nframes = f.frames()
    data = f.read_frames(nframes)
    return data, f.samplerate()
Esempio n. 25
0
import pysndfile
import numpy as np

inputText = input("Enter an input sentence: ")
inputWords = inputText.split()  #razdvaja riječi i sprema u words
outputFile = './sentences/' + inputText  #ime izlazne datoteke
sentenceObject = pysndfile.PySndfile(
    outputFile, 'rw', pysndfile.construct_format('wav', 'float64'), 1, 16000
)  #kreira novu datoteku u koju će zapisivati(format se mora proslijediti u obliku integera koji kreira funkcija construct_format iz stringova koji joj se zadaju)

#za svaku riječ iz ulazne rečenice
for word in inputWords:
    wordFilePath = './words/' + word  #pronađe riječ u bazi
    wordObject = pysndfile.PySndfile(
        wordFilePath)  #stvara objekt iz trenutne riječi
    wordData = wordObject.read_frames(
    )  #čita i privremeno pohranjuje data iz objekta
    sentenceObject.write_frames(
        wordData)  #zapisuje gore pohranjene podatke na kraj izlazne datoteke
Esempio n. 26
0
File: io.py Progetto: mondeja/waves
 def _init_f(self):
     if not self.f:
         self.f = snd.PySndfile(self.filename, "r")
     else:
         self.f.seek(0, mode="r")
Esempio n. 27
0
def main():
    fig, ax = plt.subplots(nrows=2, sharex=False)

    cmap = plt.get_cmap('viridis')

    sndfile = pysndfile.PySndfile('vault.wav', 'r')
    if sndfile.channels() != 1:
        raise RuntimeError('please only load mono files')
    Fs = sndfile.samplerate()
    signal = sndfile.read_frames()
    NFFT = 2048
    pxx, freq, time = mlab.specgram(signal,
                                    NFFT=NFFT,
                                    noverlap=NFFT / 2,
                                    Fs=Fs)

    def do_impulse_plot():
        time = np.arange(len(signal)) / float(Fs)
        ax[0].plot(time, signal)

        ax[0].set_xlim([0, 0.1])

        ax[0].set_xlabel('time / s')
        ax[0].set_ylabel('amplitude')

        time = 7.12 / 340.0
        ax[0].axvline(time, linestyle='dotted', color='red')
        ax[0].text(
            time + 0.0005, -0.5,
            str.format('{0:.3g} s (earliest possible diffraction time)', time))

    def do_spec_plot():
        Z = 10 * np.log10(pxx)

        vmin = -200
        vmax = np.nanmax(Z)

        im = ax[1].pcolormesh(time,
                              freq,
                              Z,
                              cmap=cmap,
                              vmin=vmin,
                              vmax=vmax,
                              rasterized=True)
        ax[1].set_xlim([0, 1])

        ax[1].set_ylim(20, 20000)
        ax[1].set_yscale('log')

        ax[1].set_xlabel('time / s')
        ax[1].set_ylabel('frequency / Hz')

        cb = fig.colorbar(im)
        cb.set_label('dB')

    do_impulse_plot()
    do_spec_plot()

    plt.suptitle('Early Response in Vault Model')

    plt.tight_layout()
    plt.subplots_adjust(top=0.9)

    plt.show()
    if render:
        plt.savefig('vault_response.svg',
                    bbox_inches='tight',
                    dpi=96,
                    format='svg')