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
Hide Your Secret Message in any Wave Audio File.

HiddenWave Embedding secret messages in wave audio file What is HiddenWave Hiddenwave is a python based program for simple audio steganography. You ca

TechChip 99 Dec 28, 2022
Some utils for auto speech recognition

About Some utils for auto speech recognition. Utils Util Description Script Reset audio Reset sample rate, sample width, etc of audios.

1 Jan 24, 2022
Sequencer: Deep LSTM for Image Classification

Sequencer: Deep LSTM for Image Classification Created by Yuki Tatsunami Masato Taki This repository contains implementation for Sequencer. Abstract In

Yuki Tatsunami 111 Dec 16, 2022
Using python to generate a bat script of repetitive lines of code that differ in some way but can sort out a group of audio files according to their common names

Batch Sorting Using python to generate a bat script of repetitive lines of code that differ in some way but can sort out a group of audio files accord

David Mainoo 1 Oct 29, 2021
A python program for visualizing MIDI files, and displaying them in a spiral layout

SpiralMusic_python A python program for visualizing MIDI files, and displaying them in a spiral layout For a hardware version using Teensy & LED displ

Gavin 6 Nov 23, 2022
An audio guide for destroying oracles in Destiny's Vault of Glass raid

prophet An audio guide for destroying oracles in Destiny's Vault of Glass raid. This project allows you to make any encounter with oracles without hav

24 Sep 15, 2022
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 04, 2023
Xbot-Music - Bot Play Music and Video in Voice Chat Group Telegram

XBOT-MUSIC A Telegram Music+video Bot written in Python using Pyrogram and Py-Tg

Fariz 2 Jan 20, 2022
Accompanying code for our paper "Point Cloud Audio Processing"

Point Cloud Audio Processing Krishna Subramani1, Paris Smaragdis1 1UIUC Paper For the necessary libraries/prerequisites, please use conda/anaconda to

Krishna Subramani 17 Nov 17, 2022
A Python library and tools AUCTUS A6 based radios.

A Python library and tools AUCTUS A6 based radios.

Jonathan Hart 6 Nov 23, 2022
Mopidy is an extensible music server written in Python

Mopidy Mopidy is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. Y

Mopidy 7.6k Jan 05, 2023
OpenClubhouse - A third-part web application based on flask to play Clubhouse audio.

OpenClubhouse - A third-part web application based on flask to play Clubhouse audio.

1.1k Jan 05, 2023
❤️ This Is The EzilaXMusicPlayer Advaced Repo 🎵

Telegram EzilaXMusicPlayer Bot 🎵 A bot that can play music on telegram group's voice Chat ❤️ Requirements 📝 FFmpeg NodeJS nodesource.com Python 3.7+

Sadew Jayasekara 11 Nov 12, 2022
Basically Play Pauses the song when it is safe to do so. when you die in a round

Basically Play Pauses the song when it is safe to do so. when you die in a round

AG_1436 1 Feb 13, 2022
PianoPlayer - Automatic fingering generator for piano scores

PianoPlayer - Automatic fingering generator for piano scores

Marco Musy 571 Jan 02, 2023
live coding in python + supercollider

live coding in python + supercollider

Zack 6 Feb 06, 2022
DaisyXmusic ❤ A bot that can play music on Telegram Group and Channel Voice Chats

DaisyXmusic ❤ is the best and only Telegram VC player with playlists, Multi Playback, Channel play and more

TeamOfDaisyX 34 Oct 22, 2022
Praat in Python, the Pythonic way

Parselmouth - Praat in Python, the Pythonic way Parselmouth is a Python library for the Praat software. Though other attempts have been made at portin

Yannick Jadoul 786 Jan 09, 2023
Code for csig audio deepfake detection

FMFCC Audio Deepfake Detection Solution This repo provides an solution for the 多媒体伪造取证大赛. Our solution achieve the 1st in the Audio Deepfake Detection

BokingChen 9 Jun 04, 2022
Implementation of "Slow-Fast Auditory Streams for Audio Recognition, ICASSP, 2021" in PyTorch

Auditory Slow-Fast This repository implements the model proposed in the paper: Evangelos Kazakos, Arsha Nagrani, Andrew Zisserman, Dima Damen, Slow-Fa

Evangelos Kazakos 57 Dec 07, 2022