python wrapper for rubberband

Overview

pyrubberband

PyPI Build Status Coverage Status GitHub license Documentation Status

A python wrapper for rubberband.

For now, this just provides lightweight wrappers for pitch-shifting and time-stretching.

All processing is done via the command-line through files on disk. In the future, this could be improved by directly wrapping the C library instead.

Install Rubberband on OS X

brew install https://gist.githubusercontent.com/faroit/b67c1708cdc1f9c4ddc9/raw/942bbedded22f05abab0d09b52383e7be4aee237/rubberband.rb

Example usage

>>> import soundfile as sf
>>> import pyrubberband as pyrb
>>> # Read mono wav file
>>> y, sr = sf.read("test.wav")
>>> # Play back at double speed
>>> y_stretch = pyrb.time_stretch(y, sr, 2.0)
Comments
  • Error: Please verify that rubberband-cli is installed

    Error: Please verify that rubberband-cli is installed

    Description

    I am new to this project and have been searching for time-stretching and pitch-shifting functionalities in python when I found this so, to test its working, I ran the "Example Usage" code from the pyrubberband github with one of my file but I got this error (image below).

    1 2

    I tried finding the solution to this on web, but had no leads as of now.

    Versions

    Windows-10-10.0.17134-SP0
    Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
    NumPy 1.16.4
    SoundFile 0.9.0
    

    Moreover

    I think the problem is with the OS (I'm using windows, but found OS X codes around the web), and by the way I also tried pip install rubberband-cli in the prompt, cuz the error said "rubberband-cli not installed" but that generated another error :-

    Collecting rubberband-cli
    ERROR: Could not find a version that satisfies the requirement rubberband-cli (from versions: none)
    ERROR: No matching distribution found for rubberband-cli
    

    Later, I downloaded rubberband cli from here and tried installing that as well but that too didn't help.

    So finally I am here, hoping to get some positive response from the community. Thanks !

    opened by srajan-jha 14
  • Added timemap stretch option

    Added timemap stretch option

    I added a function that allows users to perform the timemap stretch option of rubberband (see doc here). It is largely based on the current code.

    I've also added a test in the tests file.

    Here is an example of time map that stretches a 5 seconds audio file by: Leaving second 0 to 1 as is Speeding up seconds 1 to 3 by a factor 2. (it corresponds to seconds 1 to 2 in the stretched audio) Leaving the rest of the audio as is.

    time_map = [(0, 0), (sr, sr), (3*sr, 2*sr), (5*sr, 4*sr)]

    enhancement 
    opened by marcsarfa 13
  • replace librosa.load with pysoundfile.read

    replace librosa.load with pysoundfile.read

    I really like librosa but importing it only for the read/write capability can make things complicated. There are other libraries which only focus on audio I/O like pysoundfile and therefore have less dependencies and are more flexible.

    This PR therefore removes librosa dependency and replace it with pysoundfile. I know that pysoundfile is not optimal because it not pure python but since timestretching/pitch shifting is often applied on general audio files a library which supports a large number of input and output formats like portaudio is beneficial. Also to my knowledge there are currently no better solutions for python.

    I've also added a note howto easily install rubberband cli on mac by providing a homebrew recipe

    enhancement 
    opened by faroit 11
  • require soundfile, not pysoundfile

    require soundfile, not pysoundfile

    pysoundfile is deprecated: https://github.com/bastibe/PySoundFile

    What does this implement/fix? Explain your changes.

    The PySoundFile page on GitHub indicates that PySoundFile was renamed to SoundFile.

    The install command is now pip install soundfile.

    Any other comments?

    I had to comment out the pytest lines in setup.cfg in order to run the tests. But, the tests did pass!

    Running pytest with setup.cfg as is results in:

    ↪ pytest
    ================================================================================ test session starts ================================================================================
    platform darwin -- Python 3.6.12, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
    rootdir: /Users/nw_henderson/github.com/nwh/pyrubberband, configfile: setup.cfg
    plugins: cov-2.10.1, pep8-1.0.6
    collected 0 items / 1 error                                                                                                                                                         
    Coverage.py warning: No data was collected. (no-data-collected)
    
    ====================================================================================== ERRORS =======================================================================================
    ___________________________________________________________________________ ERROR collecting test session ___________________________________________________________________________
    Direct construction of Pep8Item has been deprecated, please use Pep8Item.from_parent.
    See https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent for more details.
    
    ---------- coverage: platform darwin, python 3.6.12-final-0 ----------
    Name                       Stmts   Miss  Cover   Missing
    --------------------------------------------------------
    pyrubberband/__init__.py       3      3     0%   4-7
    pyrubberband/pyrb.py          72     72     0%   3-257
    pyrubberband/version.py        1      1     0%   4
    --------------------------------------------------------
    TOTAL                         76     76     0%
    
    ============================================================================== short test summary info ==============================================================================
    ERROR 
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ================================================================================= 1 error in 0.09s ==================================================================================
    
    opened by nwh 4
  • add feature for parsing ableton ASD file

    add feature for parsing ableton ASD file

    Reference Issue

    N/A

    What does this implement/fix? Explain your changes.

    This adds a function ableton_asd_to_time_map for parsing Ableton .asd warp files into a time_map list to be used with pyrb.timemap_stretch.

    Any other comments?

    Example usage:

    import pyrb
    import librosa
    
    sr = 44100
    bpm = 120.
    
    y = librosa.load('song.wav', sr=sr)[0]
    time_map = pyrb.ableton_asd_to_time_map('song.wav.asd', y, sr, bpm)
    new_song = pyrb.timemap_stretch(y, sr, time_map)
    
    from scipy import io
    import scipy.io.wavfile
    io.wavfile.write('new_song.wav', sr, new_song )
    

    I wrote the code after reading https://github.com/jtxx000/extract-warp-markers. That project showed how to extract the BPM. I did some extra probing to find out how to get other fields such as loop_start, loop_end, start_marker, end_marker, loop_on. I think having that information could be really useful for other developers. Perhaps pyrubberband could handle looping one day.

    It's possible that this function could break if Ableton changes their ASD format... But I still think it's worth sharing. I'm using Ableton 10.1.30.

    opened by DBraun 3
  • Preserve original data type

    Preserve original data type

    sf.read defaults to reading files as float64, which causes pyrubberband to implicitly convert all processed audio into float64 regardless of the original data type. This change makes pyrubberband preserve the data type of the input by reading it back in the same format.

    enhancement 
    opened by joonoro 1
  • [Not a Bug] How to time_stretch without changing the pitch?

    [Not a Bug] How to time_stretch without changing the pitch?

    I followed this example that I found on Medium but it doesn't seem to work. When the playbackRate is increased, how can I correct the pitch so that it is the same as the original audio?

    Screen Shot 2021-09-21 at 7 55 27 PM

    I have also tried the following by passing the output of time_stretch to the input of pitch_shift

    # Play back at 1.5X speed
    y_stretch = pyrb.time_stretch(audioData, sampleRate, audioSpeed)
    # Play back two 1.5x tones
    y_shift = pyrb.pitch_shift(y_stretch, sampleRate, audioSpeed)
    soundfile.write(f'{tmp_name}.wav', y_shift, sampleRate, format='wav')
    
    opened by Jun711 4
  • Adding support for single valued `rbargs`

    Adding support for single valued `rbargs`

    Reference Issue

    Fixes Issue #21

    What does this implement/fix? Explain your changes.

    Arguments to CLI, parsed through rbargs can be single or dual valued, but currently breaks if it's single valued. for e.g. pyrb.pitch_shift(wav_data, n_semitones, rbargs={'--formant'}) won't work.

    This current implementation allows us to restore that functionality by parsing an empty value '' to the CLI.

    This fix allows us to parse flags through in the form of rbargs={'--flag' : ''} while retaining the kwargs format.

    Any other comments?

    I do feel that this leaves us a bit wanting for something nicer but it's just a step forward to allow some functionality for now. We can explore making the extra argument as None instead of '', but I figured this is probably just as intuitive for these occasional use-cases.

    opened by adityatb 11
  • Can't pass flags (rbargs) with keyword but no value

    Can't pass flags (rbargs) with keyword but no value

    Description

    Some flags in rubberband are not followed by a value, e.g. --no-lamination or --pitch-hq. The current implementation always expects rbargs as pairs of keyword and argument (in dict format), making it impossible to use flags that don't take values.

    Steps/Code to Reproduce

    import pyrubberband
    
    # Generate a random signal and time-stretch it
    sr = 22050
    y = np.random.randn(5 * sr)
    
    y_stretch = pyrubberband.time_stretch(y, sr, rate=1.5, rbargs={"-c": "6"})  # works
    y_stretch = pyrubberband.time_stretch(y, sr, rate=1.5, rbargs={"--pitch-hq": ""})  # fails
    y_stretch = pyrubberband.time_stretch(y, sr, rate=1.5, rbargs={"--pitch-hq": " "})  # fails
    y_stretch = pyrubberband.time_stretch(y, sr, rate=1.5, rbargs={"--pitch-hq": None})  # fails
    

    Expected Results

    Should be possible to call no-value flags such as --pitch-hq. Included some examples above of syntax that could be supported with dicts (e.g. None). Alternative dict could be replaced with e.g. tuple that can have either 1 or 2 elements.

    Actual Results

    ---------------------------------------------------------------------------
    CalledProcessError                        Traceback (most recent call last)
    <ipython-input-45-8758af91c0ad> in <module>
          5 filename = '/Users/salamon/dev/scaper/tests/data/audio/foreground/human_voice/42-Human-Vocal-Voice-all-aboard_edit.wav'
          6 audio, sr = soundfile.read(filename)
    ----> 7 audio_pitch = pyrubberband.pitch_shift(audio, sr, 1, rbargs=params)
          8 Audio(data=audio_pitch.T, rate=sr)
    
    ~/dev/miniconda3/envs/scaper35/lib/python3.5/site-packages/pyrubberband/pyrb.py in pitch_shift(y, sr, n_steps, rbargs)
        255     rbargs.setdefault('--pitch', n_steps)
        256 
    --> 257     return __rubberband(y, sr, **rbargs)
    
    ~/dev/miniconda3/envs/scaper35/lib/python3.5/site-packages/pyrubberband/pyrb.py in __rubberband(y, sr, **kwargs)
         72         arguments.extend([infile, outfile])
         73 
    ---> 74         subprocess.check_call(arguments, stdout=DEVNULL, stderr=DEVNULL)
         75 
         76         # Load the processed audio.
    
    ~/dev/miniconda3/envs/scaper35/lib/python3.5/subprocess.py in check_call(*popenargs, **kwargs)
        269         if cmd is None:
        270             cmd = popenargs[0]
    --> 271         raise CalledProcessError(retcode, cmd)
        272     return 0
        273 
    
    CalledProcessError: Command '['rubberband', '-q', '-c', '6', '--pitch-hq', ' ', '--pitch', '1', '/var/folders/j4/2cgkdym179b76zljmlm1d6yc0000gn/T/tmpu311s4a2.wav', '/var/folders/j4/2cgkdym179b76zljmlm1d6yc0000gn/T/tmpermm7whf.wav']' returned non-zero exit status 2
    

    Versions

    Darwin-18.2.0-x86_64-i386-64bit Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 16:30:03) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] NumPy 1.18.2 SoundFile 0.9.0

    opened by justinsalamon 1
  • Some functions added

    Some functions added

    Reference Issue

    No reference issue

    What does this implement/fix? Explain your changes.

    Implement a function that were not wrapped: frequency multiply: To multiply all frequencies by a certain factor, helpful with some stuff that shifting by semitones cannot achieve. Is the -f option in the CLI

    tempo shift: Instead of calculating manually the ratio conversion for the tempo, use the function already included in rubberband

    enhancement 
    opened by migperfer 2
  • long window mode for signals with sr <= 210Hz

    long window mode for signals with sr <= 210Hz

    Pyrubberband will hang when faced with low-sr signals unless the --window-long flag is set. This PR adds that flag for signals below 210Hz and allows the process to complete.

    opened by markostam 8
  • Low sample rate signal hang with rubberband

    Low sample rate signal hang with rubberband

    I've noticed that when you try to use rubberband on very low-samplerate signals (anything 210Hz and below) rubberband will hang.

    These both hang:

    y = np.random.rand(1024)
    
    shifted = pyrubberband.pitch_shift(y=y, sr=210, n_steps=2)
    stretched = pyrubberband.time_stretch(y=y, sr=210, rate=0.5)
    

    These both work

    y = np.random.rand(1024)
    
    shifted = pyrubberband.pitch_shift(y=y, sr=211, n_steps=2)
    stretched = pyrubberband.time_stretch(y=y, sr=211, rate=0.5)
    

    The rubberband CLI has the same behavior; it hangs during the first studying pass at 99% CPU until you send it a break:

    $ rubberband -d3 -t 2.0 /tmp/tmpzGl2Zt.wav /tmp/tmpzGl2Zt_2.wav
    Using crispness level: 5 (Crisp monophonic instrumental)
    Using time ratio 2 and frequency ratio 1
    RubberBandStretcher::Impl::Impl: rate = 125, options = 16
    configure: effective ratio = 2
    configure: analysis window size = 8, synthesis window size = 8, fft size = 8, increment = 0 (approx output increment = 0)
    configure: outbuf size = 8192
    Window area: 0.5; synthesis window area: 0.5
    FFT::FFT(8): using implementation: fftw
    Not real time mode: prefilling
    configure: effective ratio = 2
    configure: analysis window size = 8, synthesis window size = 8, fft size = 8, increment = 0 (approx output increment = 0)
    configure: outbuf size = 8192
    Not real time mode: prefilling
    configure: effective ratio = 2
    configure: analysis window size = 8, synthesis window size = 8, fft size = 8, increment = 0 (approx output increment = 0)
    configure: outbuf size = 8192
    Pass 1: Studying...
    

    Interestingly, this only seems to be an issue when rate for time_stretch < 1 or when n_steps for pitch_shift > 0, otherwise it runs fine.

    I haven't had time to dig into the rubberband source and likely will not any time soon but I've noticed that passing the --window-long flag will allow it to run to completion. IE these both run fine:

    y = np.random.rand(1024)
    
    shifted = pyrubberband.pitch_shift(y=y, sr=210, n_steps=2, rbargs={"-q":"--window-long"})
    stretched = pyrubberband.time_stretch(y=y, sr=210, rate=0.5, rbargs={"-q":"--window-long"})
    

    It's hacky, but would it make sense to simply add a conditional that would add the --window-long flag to any sr <= 210?

    opened by markostam 0
Releases(0.3.0)
Owner
Brian McFee
Assistant Professor of Music Technology and Data Science
Brian McFee
A music player designed for a University Project.

A music player designed for a University Project. Very flexibe and easy to use, a real life working application with user friendly controls. Hope u enjoy!!

Aditya Johorey 1 Nov 19, 2021
A Simple Script that will help you to Play / Change Songs with just your Voice

Auto-Spotify using Voice Recognition A Simple Script that will help you to Play / Change Songs with just your Voice Explore the docs » Table of Conten

Mehul Shah 1 Nov 21, 2021
extract unpack asset file (form unreal engine 4 pak) with extenstion *.uexp which contain awb/acb (cri/cpk like) sound or music resource

Uexp2Awb extract unpack asset file (form unreal engine 4 pak) with extenstion .uexp which contain awb/acb (cri/cpk like) sound or music resource. i ju

max 6 Jun 22, 2022
Voice to Text using Raspberry Pi

This module will help to convert your voice (speech) into text using Speech Recognition Library. You can control the devices or you can perform the desired tasks by the word recognition

Raspberry_Pi Pakistan 2 Dec 15, 2021
GNU Radio – the Free and Open Software Radio Ecosystem

GNU Radio is a free & open-source software development toolkit that provides signal processing blocks to implement software radios. It can be used wit

GNU Radio 4.1k Jan 06, 2023
Improved Python UI to convert Youtube URL to .mp3 file.

YT-MP3 Improved Python UI to convert Youtube URL to .mp3 file. How to use? Just run python3 main.py Enter the URL of the video Enter the PATH of where

8 Jun 19, 2022
GNOME powered sound conversion

SoundConverter A simple sound converter application for the GNOME environment. It reads anything the GStreamer library can read, and writes Ogg Vorbis

Gautier Portet 188 Dec 17, 2022
This is a python package that turns any images into MIDI files that views the same as them

image_to_midi This is a python package that turns any images into MIDI files that views the same as them. This package firstly convert the image to AS

Rainbow Dreamer 4 Mar 10, 2022
Carnatic Notes Predictor for audio files

Carnatic Notes Predictor for audio files Link for live application: https://share.streamlit.io/pradeepak1/carnatic-notes-predictor-for-audio-files/mai

1 Nov 06, 2021
Speech Algorithms Collections

Speech Algorithms Collections

Ryuk 498 Jan 06, 2023
Python interface to the WebRTC Voice Activity Detector

py-webrtcvad This is a python interface to the WebRTC Voice Activity Detector (VAD). It is compatible with Python 2 and Python 3. A VAD classifies a p

John Wiseman 1.5k Dec 22, 2022
A Youtube audio player for your terminal

AudioLine A lightweight Youtube audio player for your terminal Explore the docs » View Demo · Report Bug · Request Feature · Send a Pull Request About

Haseeb Khalid 26 Jan 04, 2023
Official implementation of A cappella: Audio-visual Singing VoiceSeparation, from BMVC21

Y-Net Official implementation of A cappella: Audio-visual Singing VoiceSeparation, British Machine Vision Conference 2021 Project page: ipcv.github.io

Juan F. Montesinos 12 Oct 22, 2022
:sound: Play and Record Sound with Python :snake:

Play and Record Sound with Python This Python module provides bindings for the PortAudio library and a few convenience functions to play and record Nu

spatialaudio.net 750 Dec 31, 2022
Minimal command-line music player written in Python

pyms Minimal command-line music player written in Python. Designed with elegance and minimalism. Resizes dynamically with your terminal. Dependencies

12 Sep 23, 2022
A voice assistant which can handle your everyday task and allows you to book items from your favourite store!

Voicely Table of Contents About The Project Built With Getting Started Prerequisites Installation Usage Roadmap Contributing License Contact Acknowled

Awantika Nigam 2 Nov 17, 2021
A python script that can play .mp3 URLs upon the ringing or motion detection of a Ring doorbell. The sound plays through Sonos speakers.

Ring x Sonos A python script that plays .mp3 files whenever a doorbell is rung or a doorbell detects motion. Features Music! Authors @braden Running T

braden 0 Nov 12, 2021
IDing the songs played on the do you radio show

IDing the songs played on the do you radio show

Rasmus Jones 36 Nov 15, 2022
The official repository for Audio ALBERT

AALBERT Here is also the official repository of AALBERT, which is Pytorch lightning reimplementation of the paper, Audio ALBERT: A Lite Bert for Self-

pohan 55 Dec 11, 2022
Voicefixer aims at the restoration of human speech regardless how serious its degraded.

Voicefixer aims at the restoration of human speech regardless how serious its degraded.

Leo 324 Dec 26, 2022