Python wrapper around sox.

Related tags

Audio pysox
Overview

pysox

Python wrapper around sox. Read the Docs here.

PyPI version Documentation Status GitHub license PyPI

Build Status Coverage Status

PySocks

This library was presented in the following paper:

R. M. Bittner, E. J. Humphrey and J. P. Bello, "pysox: Leveraging the Audio Signal Processing Power of SoX in Python", in Proceedings of the 17th International Society for Music Information Retrieval Conference Late Breaking and Demo Papers, New York City, USA, Aug. 2016.

Install

This requires that SoX version 14.4.2 or higher is installed.

To install SoX on Mac with Homebrew:

brew install sox

If you want support for mp3, flac, or ogg files, add the following flags:

brew install sox --with-lame --with-flac --with-libvorbis

on Linux:

apt-get install sox

or install from source.

To install the most up-to-date release of this module via PyPi:

pip install sox

To install the master branch:

pip install git+https://github.com/rabitt/pysox.git

or

git clone https://github.com/rabitt/pysox.git
cd pysox
python setup.py install

Tests

If you have a different version of SoX installed, it's recommended that you run the tests locally to make sure everything behaves as expected, by simply running:

pytest

Examples

import sox
# create transformer
tfm = sox.Transformer()
# trim the audio between 5 and 10.5 seconds.
tfm.trim(5, 10.5)
# apply compression
tfm.compand()
# apply a fade in and fade out
tfm.fade(fade_in_len=1.0, fade_out_len=0.5)
# create an output file.
tfm.build_file('path/to/input_audio.wav', 'path/to/output/audio.aiff')
# or equivalently using the legacy API
tfm.build('path/to/input_audio.wav', 'path/to/output/audio.aiff')
# get the output in-memory as a numpy array
# by default the sample rate will be the same as the input file
array_out = tfm.build_array(input_filepath='path/to/input_audio.wav')
# see the applied effects
tfm.effects_log
> ['trim', 'compand', 'fade']

Transform in-memory arrays:

import numpy as np
import sox
# sample rate in Hz
sample_rate = 44100
# generate a 1-second sine tone at 440 Hz
y = np.sin(2 * np.pi * 440.0 * np.arange(sample_rate * 1.0) / sample_rate)
# create a transformer
tfm = sox.Transformer()
# shift the pitch up by 2 semitones
tfm.pitch(2)
# transform an in-memory array and return an array
y_out = tfm.build_array(input_array=y, sample_rate_in=sample_rate)
# instead, save output to a file
tfm.build_file(
    input_array=y, sample_rate_in=sample_rate,
    output_filepath='path/to/output.wav'
)
# create an output file with a different sample rate
tfm.set_output_format(rate=8000)
tfm.build_file(
    input_array=y, sample_rate_in=sample_rate,
    output_filepath='path/to/output_8k.wav'
)

Concatenate 3 audio files:

import sox
# create combiner
cbn = sox.Combiner()
# pitch shift combined audio up 3 semitones
cbn.pitch(3.0)
# convert output to 8000 Hz stereo
cbn.convert(samplerate=8000, n_channels=2)
# create the output file
cbn.build(
    ['input1.wav', 'input2.wav', 'input3.wav'], 'output.wav', 'concatenate'
)
# the combiner does not currently support array input/output

Get file information:

import sox
# get the sample rate
sample_rate = sox.file_info.sample_rate('path/to/file.mp3')
# get the number of samples
n_samples = sox.file_info.num_samples('path/to/file.wav')
# determine if a file is silent
is_silent = sox.file_info.silent('path/to/file.aiff')
# file info doesn't currently support array input
Comments
  • Version1.2

    Version1.2

    • [x] fix set_input_format in Combiner
    • [x] implement stretch
    • [x] implement speed
    • [x] implement sinc
    • [x] implement phaser
    • [x] implement mcompand
    • [x] implement echos
    • [x] implement echo
    • [x] implement bend
    opened by rabitt 18
  • Use Transformer in-memory with stdin/stdout

    Use Transformer in-memory with stdin/stdout

    This PR tries to address #6. I basically followed the code by @carlthome in pysndfx here: https://github.com/carlthome/python-audio-effects/blob/master/pysndfx/dsp.py#L472. I followed the discussion in the issue and implemented a new function that belongs to Transformer called build_array, which takes in a numpy array. The main issue is keeping track of all of the information that would normally be in the header of the audio file. Instead, these have to be passed as arguments to build_array, both for the input and output.

    I modified all of the tests. Each piece of the Transformer is tested by taking an input file and passing it through sox to write to an output file. So in the tests, what I do is load both the input file and the output file as numpy arrays, pass the input array into tfm.build_array and collect the output array (which is the second argument in the tuple, matching the API of tfm.build). Then, I do an np.allclose between the loaded output array from the output file and the output array. Every test was modified in this way, except for one, which I can't get working in the time I tried to put this together today. That test is test_bitdepth_valid, here: https://github.com/pseeth/pysox/blob/master/tests/test_transform.py#L1347.

    This change to the tests is encapsulated in a single function tfm_assert_array_to_file_output which you'll see calls to sprinkled throughout the test.

    To do all this, I modified the sox function in a backwards compatible way. I probably need to up coverage a bit still but this is hopefully okay to PR now for feedback.

    Let me know if this is a good start and how to get this merged, if possible! It would go a long way to making pysox super efficient for Scaper, thus why I'm here. :)

    Thanks!

    opened by pseeth 15
  • Use directly in memory, instead of via files, possible?

    Use directly in memory, instead of via files, possible?

    Would it be possible to input audio as ndarray:s into pysox directly as well as files from disk? Why I'm asking is because I'm using librosa for onset detection, and thus already have the audio loaded, but would still like to apply some audio effects and stuff afterwards.

    Like maybe the constructors could do a type check, and build() could return the destination audio or something?

    y = librosa.load(path)[0]
    tfm = sox.Transformer(y)
    # Do stuff...
    y = tfm.build()
    

    I realize this adds extra complexity to pysox (like having librosa as a dependency or similar) which is intended to be a clean wrapper around SoX, so I get if it's deemed out of scope. Just asking!

    enhancement 
    opened by carlthome 14
  • [MRG] bugfix file_info.bitrate (b -> B in sox flag), define bitdepth, return None when file info is NA

    [MRG] bugfix file_info.bitrate (b -> B in sox flag), define bitdepth, return None when file info is NA

    file_info.bitrate used to call soxi with flag -b rather than -B Yes, -b is not the bit rate but the bit depth This PR changes -b into -B in file_info.bitrate It also defines a new function, file_info.bitdepth, which does what bitrate did earlier I updated the tests accordingly Closes #68, Closes #78, closes #84

    bug 
    opened by lostanlen 13
  • Handle pathlib.Path path types

    Handle pathlib.Path path types

    Since python 3.4 there has been a new object-oriented interface to handling paths. This PR adds support for pathlib.Path for functions which take a path as input. I make heavy use of pathlib.Path in my code these days, and while I can do the cast to string myself, I find that more and more libraries are supporting pathlib, and so I offer this PR.

    In practice, since pathlib.Path is implicitly cast to string, there are only a couple of minor places where this is important - any function which performs a string-based operation on a variable which could be a path.

    In order to make sure the tests pass, because this a python3-only feature, I also removed 2.7 from your .travis.yml file. Since python2 is EOL, and your readme doesn't include a python2 badge in the top, it seemed like this should be okay. If not, let me know and I'll see if I can come up with some test flags for python2 which would skip these tests or something.

    opened by cjacoby 11
  • Support using same file path for input & output

    Support using same file path for input & output

    Sox doesn't support using the same file as both input and output - doing this will result in an empty, invalid audio file. While this is sox behavior and not pysox, it would be nice if pysox took care of this behind the scenes. Right now the user needs to worry about this logic themselves, e.g. like this:

    import tempfile
    import shutil
    from scaper.util import _close_temp_files
    
    audio_infile = '/Users/justin/Downloads/trimtest.wav'
    audio_outfile = '/Users/justin/Downloads/trimtest.wav'
    start_time = 2
    end_time = 3
    
    tfm = sox.Transformer()
    tfm.trim(start_time, end_time)
    if audio_outfile != audio_infile:
        tfm.build(audio_infile, audio_outfile)
    else:
        # must use temp file in order to save to same file
        tmpfiles = []
        with _close_temp_files(tmpfiles):
            # Create tmp file
            tmpfiles.append(
                tempfile.NamedTemporaryFile(
                    suffix='.wav', delete=True))
            # Save trimmed result to temp file
            tfm.build(audio_infile, tmpfiles[-1].name)
            # Copy result back to original file
            shutil.copyfile(tmpfiles[-1].name, audio_outfile)
    

    Pysox does issue a warning when a file is about to be overwritten, which is even more confusing under this scenario since the user (who might be unfamiliar with the quirks of sox) has no reason to think that the overwritten file will be invalid.

    opened by justinsalamon 11
  • Remove grep dependency, parse help string in python

    Remove grep dependency, parse help string in python

    Calling grep breaks pysox (and subsequently) scaper on windows. This PR addresses this be removing the use of grep altogether and parsing the sox help string directly in python.

    Addresses issue #66 in pysox, issue justinsalamon/scaper#25 in scaper

    opened by justinsalamon 10
  • Implement Transformer:noiseprof and noisered

    Implement Transformer:noiseprof and noisered

    Implement #37. Also, I found we need a method to clear effects in Transformer so we do not need to instancing a new tfs.

    Also noiseprof effect is very special as the output prof file name is not after input filename but after noiseprof. In shell the whole command should be something like sox noise.mp3 -n noiseprof noise.prof where -n is a null file. I really do not understand sox works that way and the -n seems to be useless. As -n is in the position of output filename so the real output file is sentenced in noiseprof() function.

    Example:

    >>> import sox
    >>> tfs = sox.Transformer()
    >>> tfs.noiseprof()
    <sox.transform.Transformer object at 0x7f140c221250>
    >>> tfs.build('/home/lancaster/pb-4.wav', '-n')
    WARNING:root:This install of SoX cannot process . files.
    True
    >>> tfs.effects
    ['noiseprof', 'noise.prof']
    >>> tfs.clear_effects()
    >>> tfs.effects
    []
    >>> tfs.noisered(amount=0.3)
    WARNING:root:This install of SoX cannot process .prof files.
    <sox.transform.Transformer object at 0x7f140c221250>
    >>> tfs.build('/home/lancaster/pb-4.wav', '/home/lancaster/clear.wav')
    WARNING:root:output_file: /home/lancaster/clear.wav already exists and will be overwritten on build
    True
    

    It works well during my test, I am new to PR and not familiar with coveralls so I just test it in console... I didn't find why these WARNING exists. They may need to be fixed later...

    opened by Page-David 9
  • Updated build API for 1.4.0

    Updated build API for 1.4.0

    Implements option B from issue #106

    • build_file takes array or file inputs and generates file outputs, returning a boolean
    • build_array takes array or file inputs and returns np.ndarray outputs

    build_file is an alias for build, and I moved the documentation to point people towards using build_file, while keeping build fully functional.

    I also did a little cleanup of how set_input_format and set_output_format work - rather than storing the list of format arguments to be passed to sox, it stores a dictionary which is parsed when running build/build_array, which cleans up the build functions substantially.

    opened by rabitt 6
  • v1.4.0 build api

    v1.4.0 build api

    So far, in 1.4.0a0, we've overloaded the build API to support 4 cases:

    1. file in, file out status = tfm.build(input_filepath=..., output_filepath=...)
    2. file in, array out status, out, err = tfm.build(input_filepath=...)
    3. array in, file out status = tfm.build(input_array=..., sample_rate_in=..., output_filepath=...)
    4. array in, array out status, out, err = tfm.build(input_array=..., sample_rate_in=...)

    The pros:

    • it's backwards compatible
    • it's all in one function

    The cons:

    • the returns change in a confusing way as a function of the combination of inputs
    • only certain combinations of inputs are valid

    Do we want to keep it this way? Some other alternatives: A. write 4 separate functions. We keep build as file in-file out for backwards compatiblity and define 3 new functions for the other cases B. write 2 separate functions, one for file output and one for array output, keeping the input argument logic (e.g. build and build_array, similar to @pseeth 's original PR) in order to support either file or array input for both functions C. keep build as it is currently, and write 4 additional wrapper functions for each of the 4 cases that internally call build ... other ideas?

    Would love to hear people's thoughts. cc @pseeth @nicolamontecchio @psobot @carlthome @hadware @lostanlen

    question 
    opened by rabitt 6
  • Switch to using a named logger so callers can configure log levels.

    Switch to using a named logger so callers can configure log levels.

    Closes #51. This is kind of hacky, but should work and should allow callers to configure pysox logging via logging.getLogger('sox') on the global logging object.

    opened by psobot 6
Releases(v0.4.0)
Owner
Rachel Bittner
Rachel Bittner
python wrapper for rubberband

pyrubberband A python wrapper for rubberband. For now, this just provides lightweight wrappers for pitch-shifting and time-stretching. All processing

Brian McFee 106 Nov 28, 2022
A Python wrapper for the high-quality vocoder "World"

PyWORLD - A Python wrapper of WORLD Vocoder Linux Windows WORLD Vocoder is a fast and high-quality vocoder which parameterizes speech into three compo

Jeremy Hsu 583 Dec 15, 2022
A python wrapper for REAPER

pyreaper A python wrapper for REAPER (Robust Epoch And Pitch EstimatoR) Installation pip install pyreaper Demonstration notebnook http://nbviewer.jupy

Ryuichi Yamamoto 56 Dec 27, 2022
cross-library (GStreamer + Core Audio + MAD + FFmpeg) audio decoding for Python

audioread Decode audio files using whichever backend is available. The library currently supports: Gstreamer via PyGObject. Core Audio on Mac OS X via

beetbox 419 Dec 26, 2022
Audio fingerprinting and recognition in Python

dejavu Audio fingerprinting and recognition algorithm implemented in Python, see the explanation here: How it works Dejavu can memorize audio by liste

Will Drevo 6k Jan 6, 2023
Python library for audio and music analysis

librosa A python package for music and audio analysis. Documentation See https://librosa.org/doc/ for a complete reference manual and introductory tut

librosa 5.6k Jan 6, 2023
Python Audio Analysis Library: Feature Extraction, Classification, Segmentation and Applications

A Python library for audio feature extraction, classification, segmentation and applications This doc contains general info. Click here for the comple

Theodoros Giannakopoulos 5.1k Jan 2, 2023
Scalable audio processing framework written in Python with a RESTful API

TimeSide : scalable audio processing framework and server written in Python TimeSide is a python framework enabling low and high level audio analysis,

Parisson 340 Jan 4, 2023
nicfit 425 Jan 1, 2023
Python module for handling audio metadata

Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC, MP4, Monkey's Audio, MP3, Musepack, Ogg Opus, Ogg FLAC, Ogg Speex, Ogg The

Quod Libet 1.1k Dec 31, 2022
Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python 2 or 3

tinytag tinytag is a library for reading music meta data of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python Install pip install tinytag

Tom Wallroth 577 Dec 26, 2022
Telegram Voice-Chat Bot Written In Python Using Pyrogram.

Telegram Voice-Chat Bot Telegram Voice-Chat Bot To Play Music From Various Sources In Your Group Support All linux based os. Windows Mac Diagram Requi

TheHamkerCat 314 Dec 29, 2022
Expressive Digital Signal Processing (DSP) package for Python

AudioLazy Development Last release PyPI status Real-Time Expressive Digital Signal Processing (DSP) Package for Python! Laziness and object representa

Danilo de Jesus da Silva Bellini 642 Dec 26, 2022
cross-library (GStreamer + Core Audio + MAD + FFmpeg) audio decoding for Python

audioread Decode audio files using whichever backend is available. The library currently supports: Gstreamer via PyGObject. Core Audio on Mac OS X via

beetbox 359 Feb 15, 2021
Python I/O for STEM audio files

stempeg = stems + ffmpeg Python package to read and write STEM audio files. Technically, stems are audio containers that combine multiple audio stream

Fabian-Robert Stöter 72 Dec 23, 2022
Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python 2 or 3

tinytag tinytag is a library for reading music meta data of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python Install pip install tinytag

Tom Wallroth 435 Feb 17, 2021
Python library for handling audio datasets.

AUDIOMATE Audiomate is a library for easy access to audio datasets. It provides the datastructures for accessing/loading different datasets in a gener

Matthias 121 Nov 27, 2022
Expressive Digital Signal Processing (DSP) package for Python

AudioLazy Development Last release PyPI status Real-Time Expressive Digital Signal Processing (DSP) Package for Python! Laziness and object representa

Danilo de Jesus da Silva Bellini 573 Feb 8, 2021
A Python library for audio data augmentation. Inspired by albumentations. Useful for machine learning.

Audiomentations A Python library for audio data augmentation. Inspired by albumentations. Useful for deep learning. Runs on CPU. Supports mono audio a

Iver Jordal 1.2k Jan 7, 2023