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 tool for retrieving audio in the past

Rewinder A tool for retrieving audio in the past. Ever felt like, I need to remember that discussion which happened 10 min back. Now you can! Rewind a

Bharat 1 Jan 24, 2022
This is an OverPowered Vc Music Player! Will work for you and play music in Voice Chatz

VcPlayer This is an OverPowered Vc Music Player! Will work for you and play music in Voice Chatz Telegram Voice-Chat Bot [PyTGCalls] ⇝ Requirements ⇜

1 Dec 20, 2021
This is my voice assistant Patric!

voice-assistant This is my voice assistant Patric! You can add can add commands and even modify his name Indice How to use Installation guide How to u

Norbert Gabos 1 Jun 28, 2022
❤️ 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
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
A simple voice detection system which can be applied practically for designing a device with capability to detect a baby’s cry and automatically turning on music

Auto-Baby-Cry-Detection-with-Music-Player A simple voice detection system which can be applied practically for designing a device with capability to d

2 Dec 15, 2021
SomaFM Plugin for Kodi

SomaFM XBMC Plugin This description is a bit outdated. You can simply install this addon by browsing the official repositories from within Kodi. Insta

7 Jan 21, 2022
ianZiPu is a way to write notation for Guqin (古琴) music.

PyBetween Wrapper for Between - 비트윈을 위한 파이썬 라이브러리 Legal Disclaimer 오직 교육적 목적으로만 사용할수 있으며, 비트윈은 VCNC의 자산입니다. 악의적 공격에 이용할시 처벌 받을수 있습니다. 사용에 따른 책임은 사용자가

Nancy Yi Liang 8 Nov 25, 2022
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
Any-to-any voice conversion using synthetic specific-speaker speeches as intermedium features

MediumVC MediumVC is an utterance-level method towards any-to-any VC. Before that, we propose SingleVC to perform A2O tasks(Xi → Ŷi) , Xi means utter

谷下雨 47 Dec 25, 2022
Delta TTA(Text To Audio) SoftWare

Text-To-Audio-Windows Delta TTA(Text To Audio) SoftWare Info You Can Use It For Convert Your Text To Audio File You Just Write Your Text And Your End

Delta Inc. 2 Dec 14, 2021
Speech recognition module for Python, supporting several engines and APIs, online and offline.

SpeechRecognition Library for performing speech recognition, with support for several engines and APIs, online and offline. Speech recognition engine/

Anthony Zhang 6.7k Jan 08, 2023
This is a realtime voice translator program which gets input from user at any language and converts it to the desired language that the user asks

This is a realtime voice translator program which gets input from user at any language and converts it to the desired language that the user asks ...

Mohan Ram S 1 Dec 30, 2021
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
Vixtify - Python Controlled Music Player

Strumm Sound Playlist : Click me to listen Welcome to GitHub Pages You can use the editor on GitHub to maintain and preview the content for your websi

Vicky Kumar 2 Feb 03, 2022
Linear Prediction Coefficients estimation from mel-spectrogram implemented in Python based on Levinson-Durbin algorithm.

LPC_for_TTS Linear Prediction Coefficients estimation from mel-spectrogram implemented in Python based on Levinson-Durbin algorithm. 基于Levinson-Durbin

Zewang ZHANG 58 Nov 17, 2022
A simple python script to play bell sound in your system infinitely, just for fun and experimental purposes

A simple python script to play bell sound in your system infinitely, just for fun and experimental purposes

نافع الهلالي 1 Oct 29, 2021
Dataset and baseline code for the VocalSound dataset (ICASSP2022).

VocalSound: A Dataset for Improving Human Vocal Sounds Recognition Introduction Citing Download VocalSound Dataset Details Baseline Experiment Contact

Yuan Gong 58 Jan 03, 2023
無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア

無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのコア

Hiroshiba 0 Aug 29, 2022
ᴀ ʙᴏᴛ ᴛʜᴀᴛ ᴄᴀɴ ᴘʟᴀʏ ᴍᴜꜱɪᴄ ɪɴ ᴛᴇʟᴇɢʀᴀᴍ ɢʀᴏᴜᴘ ᴏɴ ᴠᴏɪᴄᴇ ᴄᴀʟʟ

GJ516 LOVER'S ııllıllı ♥️ ➤⃝Gᴊ516_ᴍᴜꜱɪᴄ_ʙᴏᴛ ♥️ ıllıllı ᴀ ʙᴏᴛ ᴛʜᴀᴛ ᴄᴀɴ ᴘʟᴀʏ ᴍᴜꜱɪᴄ ɪɴ ᴛᴇʟᴇɢʀᴀᴍ ɢʀᴏᴜᴘ ᴏɴ ᴠᴏɪᴄᴇ ᴄᴀʟʟ Requirements 📝 FFmpeg NodeJS nodesou

1 Nov 22, 2021