Sync Toolbox - Python package with reference implementations for efficient, robust, and accurate music synchronization based on dynamic time warping (DTW)

Overview

Python Package using Conda Python package

Sync Toolbox

This repository contains a Python package called Sync Toolbox, which provides open-source reference implementations for full-fledged music synchronization pipelines and yields state-of-the-art alignment results for a wide range of Western music.

Using suitable feature representations and cost measures, the toolbox's core technology is based on dynamic time warping (DTW), which brings the feature sequences into temporal correspondence. To account for efficiency, robustness and, accuracy, our toolbox integrates and combines techniques such as multiscale DTW (MsDTW), memory-restricted MsDTW (MrMsDTW), and high-resolution music synchronization.

If you use the Sync Toolbox in your research, please consider the following references.

References

Meinard Müller, Henning Mattes, and Frank Kurth. An Efficient Multiscale Approach to Audio Synchronization. In Proceedings of the International Society for Music Information Retrieval Conference (ISMIR): 192–197, 2006.

Sebastian Ewert, Meinard Müller, and Peter Grosche. High Resolution Audio Synchronization Using Chroma Onset Features. In Proceedings of IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP): 1869–1872, 2009.

Thomas Prätzlich, Jonathan Driedger, and Meinard Müller Memory-Restricted Multiscale Dynamic Time Warping. In Proceedings of the IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP): 569–573, 2016.

Installing

If you just want to try our example notebooks, you can run them using Binder directly in your browser: Binder

To install the Sync Toolbox locally, you can use the Python package manager pip:

pip install synctoolbox

We recommend to do this inside a conda or virtual environment. Note: On some systems, you may see errors related with soundfile when calling some functions or executing our example notebooks. soundfile is a dependency of librosa, which is used by the Sync Toolbox. In case of errors, you may have to install libsndfile using your package manager, e.g., sudo apt install libsndfile1. Alternatively, you may create a conda environment, install librosa using conda and then install the Sync Toolbox with the pip command from above. See here for further information if you are experiencing these issues.

If you want to run the example notebooks locally, you must first install the Sync Toolbox to resolve all dependencies. Then, you can clone this repository using

git clone https://github.com/meinardmueller/synctoolbox.git

install Jupyter using

pip install jupyter

and then start the notebook server via

jupyter notebook

Finally, HTML exports of the example notebooks are provided under "Releases".

Usage

Fully worked examples for using the sync toolbox are provided in the accompanying Jupyter notebooks. In sync_audio_audio_simple.ipynb, we show how to use the toolbox to synchronize two recordings of the same piece of music using standard chroma features. We also compare runtimes for standard DTW and MrMsDTW. In sync_audio_audio_full.ipynb, we expand this example and demonstrate how to build a full synchronization pipeline that yields state-of-the-art results. Finally, sync_audio_score_full.ipynb shows a similar pipeline for synchronizing a music recording with the corresponding score.

There is also an API documentation for the Sync Toolbox:

https://meinardmueller.github.io/synctoolbox

Contributing

We are happy for suggestions and contributions. We would be grateful for either directly contacting us via email ([email protected]) or for creating an issue in our Github repository. Please do not submit a pull request without prior consultation with us.

Tests

We provide automated tests for each feature and different variants of MrMsDTW. These ensure that the outputs match the ground truth matrices provided in the tests/data folder.

To execute the test script, you will need to install extra requirements for testing:

pip install 'synctoolbox[tests]'
pytest tests

Licence

The code for this toolbox is published under an MIT licence. This does not apply to the data files. Schubert songs are taken from the Schubert Winterreise Dataset. The Chopin prelude example files are taken from the FMP notebooks.

Acknowledgements

The synctoolbox package builds on results, material, and insights that have been obtained in close collaboration with different people. We would like to express our gratitude to former and current students, collaborators, and colleagues who have influenced and supported us in creating this package, including Vlora Arifi-Müller, Michael Clausen, Sebastian Ewert, Christian Fremerey, and Frank Kurth. The main authors of Sync Toolbox are associated with the International Audio Laboratories Erlangen, which are a joint institution of the Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU) and Fraunhofer Institute for Integrated Circuits IIS. We also thank the German Research Foundation (DFG) for various research grants that allowed us for conducting fundamental research in music processing (in particular, MU 2686/7-2, DFG-MU 2686/14-1).

Comments
  • Unit tests fail

    Unit tests fail

    running the unit tests on python 3.8 using the proposed procedure seem to fail:

    base38 ❯ py.test tests                                                                                                (base38)
    ===================================================== test session starts =====================================================
    platform darwin -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
    rootdir: /Users/faro/repositories/synctoolbox
    collected 13 items
    
    tests/test_dtw.py ....                                                                                                  [ 30%]
    tests/test_features.py ....FF...                                                                                        [100%]
    
    ========================================================== FAILURES ===========================================================
    _____________________________________________________ test_pitch_features _____________________________________________________
    
        def test_pitch_features():
            audio_1, _ = librosa.load('data_music/Schubert_D911-03_HU33.wav', 22050)
            audio_2, _ = librosa.load('data_music/Schubert_D911-03_SC06.wav', 22050)
            f_pitch_1_gt = np.load('tests/data/f_pitch_1.npy')
            f_pitch_2_gt = np.load('tests/data/f_pitch_2.npy')
    
            f_pitch_1 = audio_to_pitch_features(f_audio=audio_1,
                                                Fs=22050,
                                                tuning_offset=1,
                                                feature_rate=50,
                                                verbose=False)
    
            f_pitch_2 = audio_to_pitch_features(f_audio=audio_2,
                                                Fs=22050,
                                                tuning_offset=7,
                                                feature_rate=50,
                                                verbose=False)
    
    >       assert np.allclose(f_pitch_1, f_pitch_1_gt, atol=1e-5)
    E       assert False
    E        +  where False = <function allclose at 0x7f85d8b23670>(array([[0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       ...,\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.]]), array([[0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       ...,\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.],\n       [0., 0., 0., ..., 0., 0., 0.]]), atol=1e-05)
    E        +    where <function allclose at 0x7f85d8b23670> = np.allclose
    
    tests/test_features.py:81: AssertionError
    ---------------------------------------------------- Captured stdout call -----------------------------------------------------
    ................................................................................................................................................................................
    __________________________________________________ test_pitch_onset_features __________________________________________________
    
        def test_pitch_onset_features():
            audio_1, _ = librosa.load('data_music/Schubert_D911-03_HU33.wav', 22050)
            audio_2, _ = librosa.load('data_music/Schubert_D911-03_SC06.wav', 22050)
            f_pitch_onset_1_gt = load_dict('tests/data/f_pitch_onset_1.pickle')
            f_pitch_onset_2_gt = load_dict('tests/data/f_pitch_onset_2.pickle')
    
            f_pitch_onset_1 = audio_to_pitch_onset_features(f_audio=audio_1,
                                                            Fs=22050,
                                                            tuning_offset=1,
                                                            verbose=False)
    
            f_pitch_onset_2 = audio_to_pitch_onset_features(f_audio=audio_2,
                                                            Fs=22050,
                                                            tuning_offset=7,
                                                            verbose=False)
    
    >       dict_allclose(f_pitch_onset_1, f_pitch_onset_1_gt, atol=1e-5)
    
    tests/test_features.py:101:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    tests/utils.py:26: in dict_allclose
        assert np.allclose(dict1[k], dict2[k], atol)
    <__array_function__ internals>:5: in allclose
        ???
    /opt/homebrew/Caskroom/miniconda/base/envs/base38/lib/python3.8/site-packages/numpy/core/numeric.py:2171: in allclose
        res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
    <__array_function__ internals>:5: in isclose
        ???
    /opt/homebrew/Caskroom/miniconda/base/envs/base38/lib/python3.8/site-packages/numpy/core/numeric.py:2272: in isclose
        return within_tol(x, y, atol, rtol)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    x = array([[[3.10917800e+04],
            [3.11484694e+04],
            [3.11824830e+04],
            [3.12164966e+04],
            [3.123...9819230e-09],
            [1.69793182e-09],
            [1.56447331e-09],
            [1.20539503e-09],
            [9.61932239e-10]]])
    y = array([[[3.10917800e+04],
            [3.11484694e+04],
            [3.11824830e+04],
            [3.12164966e+04],
            [3.123...7001423e-09],
            [1.67276090e-09],
            [1.54219300e-09],
            [1.18766368e-09],
            [9.48867734e-10]]])
    atol = 1e-08, rtol = 1e-05
    
        def within_tol(x, y, atol, rtol):
            with errstate(invalid='ignore'):
    >           return less_equal(abs(x-y), atol + rtol * abs(y))
    E           ValueError: operands could not be broadcast together with shapes (2,138,1) (2,136,1)
    
    /opt/homebrew/Caskroom/miniconda/base/envs/base38/lib/python3.8/site-packages/numpy/core/numeric.py:2258: ValueError
    ---------------------------------------------------- Captured stdout call -----------------------------------------------------
    ................................................................................................................................................................................21 (2, 138, 1) (2, 136, 1)
    =================================================== short test summary info ===================================================
    FAILED tests/test_features.py::test_pitch_features - assert False
    FAILED tests/test_features.py::test_pitch_onset_features - ValueError: operands could not be broadcast together with shapes ...
    ================================================ 2 failed, 11 passed in 56.14s ================================================
    

    related #5 https://github.com/openjournals/joss-reviews/issues/3434

    opened by faroit 17
  • numba error `key already in dictionary: 'index.5'` in tutorial notebook

    numba error `key already in dictionary: 'index.5'` in tutorial notebook

    Hi there,

    Thanks for making this code available!

    Just cloned the repo and tried to run the notebook sync_audio_score_full.ipynb. For cell 7 (in the section "Finding optimal shift of chroma vectors"), I'm getting an error message. Posting the complete stacktrace here. Please let me know if you require more information to address this.

    AssertionError                            Traceback (most recent call last)
    /tmp/ipykernel_25695/2527601981.py in <cell line: 3>()
          1 f_cens_1hz_audio = quantized_chroma_to_CENS(f_chroma_quantized_audio, 201, 50, feature_rate)[0]
          2 f_cens_1hz_annotation = quantized_chroma_to_CENS(f_chroma_quantized_annotation, 201, 50, feature_rate)[0]
    ----> 3 opt_chroma_shift = compute_optimal_chroma_shift(f_cens_1hz_audio, f_cens_1hz_annotation)
          4 print('Pitch shift between the audio recording and score, determined by DTW:', opt_chroma_shift, 'bins')
          5 
    
    ~/synctoolbox/synctoolbox/dtw/utils.py in compute_optimal_chroma_shift(f_chroma1, f_chroma2, chroma_transpositions, step_sizes, step_weights)
         42     for chroma_shift in chroma_transpositions:
         43         cost_matrix_tmp = cosine_distance(f_chroma1, shift_chroma_vectors(f_chroma2, chroma_shift))
    ---> 44         D, _, _ = compute_warping_path(cost_matrix_tmp, step_sizes=step_sizes, step_weights=step_weights)
         45         if D[-1, -1] < dtw_cost:
         46             dtw_cost = D[-1, -1]
    
    ~/synctoolbox/synctoolbox/dtw/core.py in compute_warping_path(C, step_sizes, step_weights, implementation)
        194                          sub_sequence=False)
        195 
    --> 196         wp = __E_to_warping_path(E=E,
        197                                  dn=dn,
        198                                  dm=dm,
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
        485                     e.patch_message('\n'.join((str(e).rstrip(), help_msg)))
        486             # ignore the FULL_TRACEBACKS config, this needs reporting!
    --> 487             raise e
        488         finally:
        489             self._types_active_call = []
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
        418         return_val = None
        419         try:
    --> 420             return_val = self.compile(tuple(argtypes))
        421         except errors.ForceLiteralArg as e:
        422             # Received request for compiler re-entry with the list of arguments
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in compile(self, sig)
        963                 with ev.trigger_event("numba:compile", data=ev_details):
        964                     try:
    --> 965                         cres = self._compiler.compile(args, return_type)
        966                     except errors.ForceLiteralArg as e:
        967                         def folded(args, kws):
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in compile(self, args, return_type)
        123 
        124     def compile(self, args, return_type):
    --> 125         status, retval = self._compile_cached(args, return_type)
        126         if status:
        127             return retval
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_cached(self, args, return_type)
        137 
        138         try:
    --> 139             retval = self._compile_core(args, return_type)
        140         except errors.TypingError as e:
        141             self._failed_cache[key] = e
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/dispatcher.py in _compile_core(self, args, return_type)
        150 
        151         impl = self._get_implementation(args, {})
    --> 152         cres = compiler.compile_extra(self.targetdescr.typing_context,
        153                                       self.targetdescr.target_context,
        154                                       impl,
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
        691     pipeline = pipeline_class(typingctx, targetctx, library,
        692                               args, return_type, flags, locals)
    --> 693     return pipeline.compile_extra(func)
        694 
        695 
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in compile_extra(self, func)
        427         self.state.lifted = ()
        428         self.state.lifted_from = None
    --> 429         return self._compile_bytecode()
        430 
        431     def compile_ir(self, func_ir, lifted=(), lifted_from=None):
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_bytecode(self)
        495         """
        496         assert self.state.func_ir is None
    --> 497         return self._compile_core()
        498 
        499     def _compile_ir(self):
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_core(self)
        474                     self.state.status.fail_reason = e
        475                     if is_final_pipeline:
    --> 476                         raise e
        477             else:
        478                 raise CompilerError("All available pipelines exhausted")
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler.py in _compile_core(self)
        461                 res = None
        462                 try:
    --> 463                     pm.run(self.state)
        464                     if self.state.cr is not None:
        465                         break
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in run(self, state)
        351                     (self.pipeline_name, pass_desc)
        352                 patched_exception = self._patch_error(msg, e)
    --> 353                 raise patched_exception
        354 
        355     def dependency_analysis(self):
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in run(self, state)
        339                 pass_inst = _pass_registry.get(pss).pass_inst
        340                 if isinstance(pass_inst, CompilerPass):
    --> 341                     self._runPass(idx, pass_inst, state)
        342                 else:
        343                     raise BaseException("Legacy pass in use")
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
         33         def _acquire_compile_lock(*args, **kwargs):
         34             with self:
    ---> 35                 return func(*args, **kwargs)
         36         return _acquire_compile_lock
         37 
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in _runPass(self, index, pss, internal_state)
        294             mutated |= check(pss.run_initialization, internal_state)
        295         with SimpleTimer() as pass_time:
    --> 296             mutated |= check(pss.run_pass, internal_state)
        297         with SimpleTimer() as finalize_time:
        298             mutated |= check(pss.run_finalizer, internal_state)
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/compiler_machinery.py in check(func, compiler_state)
        267 
        268         def check(func, compiler_state):
    --> 269             mangled = func(compiler_state)
        270             if mangled not in (True, False):
        271                 msg = ("CompilerPass implementations should return True/False. "
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/typed_passes.py in run_pass(self, state)
        238         pp.run(True)
        239         with fallback_context(state, msg):
    --> 240             rewrites.rewrite_registry.apply('after-inference', state)
        241         pp.remove_dels()
        242         return True
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/rewrites/registry.py in apply(self, kind, state)
         65             while work_list:
         66                 key, block = work_list.pop()
    ---> 67                 matches = rewrite.match(state.func_ir, block, state.typemap,
         68                                         state.calltypes)
         69                 if matches:
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in match(self, func_ir, block, typemap, calltypes)
       1339             return False
       1340         self.crnt_block = block
    -> 1341         self.new_body = guard(_inline_const_arraycall, block, func_ir,
       1342                               self.typingctx, typemap, calltypes)
       1343         return self.new_body is not None
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/ir_utils.py in guard(func, *args, **kwargs)
       1530     """
       1531     try:
    -> 1532         return func(*args, **kwargs)
       1533     except GuardException:
       1534         return None
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in _inline_const_arraycall(block, func_ir, context, typemap, calltypes)
       1509                 elif expr.op == 'call' and expr in calltypes:
       1510                     arr_var = inst.target
    -> 1511                     if guard(inline_array, inst.target, expr,
       1512                              state.stmts, state.list_vars, state.dels):
       1513                         state.modified = True
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/ir_utils.py in guard(func, *args, **kwargs)
       1530     """
       1531     try:
    -> 1532         return func(*args, **kwargs)
       1533     except GuardException:
       1534         return None
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/inline_closurecall.py in inline_array(array_var, expr, stmts, list_vars, dels)
       1440             index_var = ir.Var(scope, mk_unique_var("index"), loc)
       1441             index_typ = types.intp
    -> 1442             typemap[index_var.name] = index_typ
       1443             stmts.append(_new_definition(func_ir, index_var,
       1444                     ir.Const(i, loc), loc))
    
    ~/anaconda3/envs/rhythm_grammar/lib/python3.10/site-packages/numba/core/utils.py in __setitem__(self, key, value)
        373     def __setitem__(self, key, value):
        374         if key in self:
    --> 375             raise AssertionError("key already in dictionary: %r" % (key,))
        376         super(UniqueDict, self).__setitem__(key, value)
        377 
    
    AssertionError: Failed in nopython mode pipeline (step: nopython rewrites)
    key already in dictionary: 'index.5'
    
    opened by johentsch 7
  • Enable continous integration

    Enable continous integration

    to solve installation issues it could help to include a number of continuous integration tests that run

    • runs the unit tests and installs the package
    • test the package installation in a conda environment using different python versions

    https://github.com/openjournals/joss-reviews/issues/3434

    opened by faroit 7
  • Error running sync_audio_audio_full locally in macOS: Failed to execute rubberband

    Error running sync_audio_audio_full locally in macOS: Failed to execute rubberband

    I'm in a macOS Big Sur 11.2.3. The steps I followed:

    1. I created a Conda environment with Python 3.8
    2. Installed Sync Toolbox using pip install synctoolbox which worked correctly
    3. git clone https://github.com/meinardmueller/synctoolbox.git
    4. Installed Jupyter notebook
    5. Run sync_audio_audio_full

    In the following cell:

    !pip install pyrubberband
    import pyrubberband as pyrb
    
    pitch_shift_for_audio_1 = -opt_chroma_shift % 12
    if pitch_shift_for_audio_1 > 6:
        pitch_shift_for_audio_1 -= 12
    audio_1_shifted = pyrb.pitch_shift(audio_1, Fs, pitch_shift_for_audio_1)
    
    # Pyrubberband expects the warping path to be given in audio samples.
    # Here, we do the conversion and additionally clip values that are too large.
    time_map = wp.T / feature_rate * Fs
    time_map[time_map[:, 0] > len(audio_1), 0] = len(audio_1)
    time_map[time_map[:, 1] > len(audio_2), 1] = len(audio_2)
    audio_1_warped = pyrb.timemap_stretch(audio_1_shifted, Fs, time_map=time_map)
    
    stereo_sonification = np.stack([audio_1_warped, audio_2], axis=0)
    ipd.display(ipd.Audio(stereo_sonification, rate=Fs))
    
    

    I'm getting this error:

    ---------------------------------------------------------------------------
    FileNotFoundError                         Traceback (most recent call last)
    ~/miniconda3/envs/joss_review_2/lib/python3.8/site-packages/pyrubberband/pyrb.py in __rubberband(y, sr, **kwargs)
         73 
    ---> 74         subprocess.check_call(arguments, stdout=DEVNULL, stderr=DEVNULL)
         75 
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/subprocess.py in check_call(*popenargs, **kwargs)
        358     """
    --> 359     retcode = call(*popenargs, **kwargs)
        360     if retcode:
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/subprocess.py in call(timeout, *popenargs, **kwargs)
        339     """
    --> 340     with Popen(*popenargs, **kwargs) as p:
        341         try:
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
        857 
    --> 858             self._execute_child(args, executable, preexec_fn, close_fds,
        859                                 pass_fds, cwd, env,
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)
       1703                         err_msg = os.strerror(errno_num)
    -> 1704                     raise child_exception_type(errno_num, err_msg, err_filename)
       1705                 raise child_exception_type(err_msg)
    
    FileNotFoundError: [Errno 2] No such file or directory: 'rubberband'
    
    The above exception was the direct cause of the following exception:
    
    RuntimeError                              Traceback (most recent call last)
    /var/folders/j_/672m867d1f30v0qyvsddt71058rw_j/T/ipykernel_27940/816051359.py in <module>
          5 if pitch_shift_for_audio_1 > 6:
          6     pitch_shift_for_audio_1 -= 12
    ----> 7 audio_1_shifted = pyrb.pitch_shift(audio_1, Fs, pitch_shift_for_audio_1)
          8 
          9 # Pyrubberband expects the warping path to be given in audio samples.
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/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)
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/site-packages/pyrubberband/pyrb.py in __rubberband(y, sr, **kwargs)
         82 
         83     except OSError as exc:
    ---> 84         six.raise_from(RuntimeError('Failed to execute rubberband. '
         85                                     'Please verify that rubberband-cli '
         86                                     'is installed.'),
    
    ~/miniconda3/envs/joss_review_2/lib/python3.8/site-packages/six.py in raise_from(value, from_value)
    
    RuntimeError: Failed to execute rubberband. Please verify that rubberband-cli is installed.
    

    It seems that librosa's users reported a similar problem here. @ahnonay @yiitozer any advice?

    openjournals/joss-reviews#3434

    opened by magdalenafuentes 3
  • Installation issues due to restrictive package versions

    Installation issues due to restrictive package versions

    installation on google colab requires a certain amounts of uninstalls to meet the requirements by the synctoolbox dependencies:

    ERROR: jupyter-console 5.2.0 has requirement prompt-toolkit<2.0.0,>=1.0.0, but you'll have prompt-toolkit 3.0.19 which is incompatible.
    ERROR: google-colab 1.0.0 has requirement ipython~=5.5.0, but you'll have ipython 7.25.0 which is incompatible.
    ERROR: libfmp 1.1.2 has requirement ipython==7.8.*, but you'll have ipython 7.25.0 which is incompatible.
    ERROR: libfmp 1.1.2 has requirement matplotlib==3.1.*, but you'll have matplotlib 3.2.2 which is incompatible.
    ERROR: libfmp 1.1.2 has requirement numpy==1.17.*, but you'll have numpy 1.19.5 which is incompatible.
    ERROR: libfmp 1.1.2 has requirement pandas==1.0.*, but you'll have pandas 1.1.5 which is incompatible.
    ERROR: libfmp 1.1.2 has requirement scipy==1.3.*, but you'll have scipy 1.4.1 which is incompatible.
    

    this is mainly caused by the frozen requirements of libfmp. To address this, a new release of libfmp on pypi should be issued (see https://github.com/meinardmueller/libfmp/issues/4) and synctoolbox should dependent only on that version (v1.1.3?)

    opened by faroit 3
  • How to evaluate alignment quality?

    How to evaluate alignment quality?

    Thanks for making this library! I'm a noob to this field, so I may be missing something obvious.

    Is there a metric returned somewhere that indicates how well two audio tracks align? My use case is determining if a song is a cover of another, e.g. a pop song to a piano or guitar cover.

    opened by platers 2
  • Issues with soundfile when installing Sync Toolbox

    Issues with soundfile when installing Sync Toolbox

    This issue arised for @lutzhamel during the JOSS review process, see also: https://github.com/openjournals/joss-reviews/issues/3434

    In some cases when installing synctoolbox via pip, one gets errors related to soundfile which is a dependency of librosa.

    We hope to have addressed this issue in the latest commits on the master branch in two ways:

    • The example notebooks can now be run inside the browser using Binder, no installation necessary.
    • We have added additional explanations for users who want to install the toolbox locally. In particular, the issues with soundfile can usually be solved by running sudo apt install libsndfile1

    Dear @lutzhamel, thanks for making us aware of this problem. Please let us know if the latest changes have solved this for you.

    opened by ahnonay 2
  • Release with Python 3.9

    Release with Python 3.9

    Just as a reminder, since the release in pip right now is not working with python 3.9. In a conda environment with that python version I'm getting:

    (joss_review) cusp-vmn244:repos mf3734$ pip install synctoolbox
    ERROR: Could not find a version that satisfies the requirement synctoolbox (from versions: none)
    ERROR: No matching distribution found for synctoolbox
    

    Related to #6

    openjournals/joss-reviews#3434

    opened by magdalenafuentes 1
  • Nits on docs and repo

    Nits on docs and repo

    Hey @ahnonay and @yiitozer thanks for creating this useful toolbox. Looks really good. I'll drop here some nits to follow JOSS guidelines and make the repo even clearer:

    • JOSS recommends to add a statement of need in the documentation as well, so maybe it's worth to add not only the API description in the docs, but also a brief description and the statement in the index.
    • I recommend you add a brief description in the about field of the GitHub repo as well as a link to the docs in the website field. It will make it quicker for people to get to the docs and also understand what the repo is about

    openjournals/joss-reviews#3434

    opened by magdalenafuentes 1
  • Unit test fix

    Unit test fix

    • Unit tests added for the filterbank and peak search
    • test_conda.yml fixed (python version)
    • scipy.signal.filtfilt function replaced with scipy.signal.sosfiltfilt due to numerical instabilities.
    opened by yiitozer 0
Releases(v1.2.1)
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
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
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
Generating a structured library of .wav samples with Python.

sample-library Scripts for generating a structured sample library with Python Requires Docker about Samples are written to wave files in lib/. Differe

Ben Mangold 1 Nov 11, 2021
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
BART aids transcribe tasks by taking a source audio file and creating automatic repeated loops, allowing transcribers to listen to fragments multiple times

BART (Beyond Audio Replay Technology) aids transcribe tasks by taking a source audio file and creating automatic repeated loops, allowing transcribers to listen to fragments multiple times (with poss

2 Feb 04, 2022
TwitterMusicBot - A Twitter bot with Spotify integration.

A Twitter Music Bot 🤖 🎵 🎶 I created this project to learn more about APIs, so it only works for student purposes. Initially, delving into the Spoti

Gustavo Oliveira 2 Jan 02, 2022
User-friendly Voice Cloning Application

Multi-Language-RTVC stands for Multi-Language Real Time Voice Cloning and is a Voice Cloning Tool capable of transfering speaker-specific audio featur

Sven Eschlbeck 19 Dec 30, 2022
Mousai is a simple application that can identify song like Shazam

Mousai is a simple application that can identify song like Shazam. It saves the artist, album, and title of the identified song in a JSON file.

Dave Patrick 662 Jan 07, 2023
Port Hitsuboku Kumi Chinese CVVC voicebank to deepvocal. / 筆墨クミDeepvocal中文音源

Hitsuboku Kumi (筆墨クミ) is a UTAU virtual singer developed by Cubialpha. This project ports Hitsuboku Kumi Chinese CVVC voicebank to deepvocal. This is the first open-source deepvocal voicebank on Gith

8 Apr 26, 2022
L-SpEx: Localized Target Speaker Extraction

L-SpEx: Localized Target Speaker Extraction The data configuration and simulation of L-SpEx. The code scripts will be released in the future. Data Gen

Meng Ge 20 Jan 02, 2023
Make an audio file (really) long-winded

longwind Make an audio file (really) long-winded Daily repetitions are an illusion anyway.

Vincent Lostanlen 2 Sep 12, 2022
kapre: Keras Audio Preprocessors

Kapre Keras Audio Preprocessors - compute STFT, ISTFT, Melspectrogram, and others on GPU real-time. Tested on Python 3.6 and 3.7 Why Kapre? vs. Pre-co

Keunwoo Choi 867 Dec 29, 2022
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
Audio2midi - Automatic Audio-to-symbolic Arrangement

Automatic Audio-to-symbolic Arrangement This is the repository of the project "A

Ziyu Wang 24 Dec 05, 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
Reading list for research topics in sound event detection

Sound event detection aims at processing the continuous acoustic signal and converting it into symbolic descriptions of the corresponding sound events present at the auditory scene.

Soham 64 Jan 05, 2023
?️ Open Source Audio Matching and Mastering

Matching + Mastering = ❤️ Matchering 2.0 is a novel Containerized Web Application and Python Library for audio matching and mastering. It follows a si

Sergey Grishakov 781 Jan 05, 2023
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
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