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)
An 8D music player made to enjoy Halloween this year!🤘

HAPPY HALLOWEEN buddy! Split Player Hello There! Welcome to SplitPlayer... Supposed To Be A 8DPlayer.... You Decide.... It can play the ordinary audio

Akshat Kumar Singh 1 Nov 04, 2021
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
This Is Telegram Music UserBot To Play Music Without Being Admin

This Is Telegram Music UserBot To Play Music Without Being Admin

Krishna Kumar 36 Sep 13, 2022
We built this fully functioning Music player in Python. The music player allows you to play/pause and switch to different songs easily.

We built this fully functioning Music player in Python. The music player allows you to play/pause and switch to different songs easily.

1 Nov 19, 2021
Musillow is a music recommender app that finds songs similar to your favourites.

MUSILLOW The music recommender app Check it out now!!! View Demo · Report Bug · Request Feature About The App Musillow is a music recommender app that

3 Feb 03, 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
:notes: Cross-platform music player

Exaile Exaile is a music player with a simple interface and powerful music management capabilities. Features include automatic fetching of album art,

Exaile 327 Dec 19, 2022
Code for "Audio-driven Talking Face Video Generation with Learning-based Personalized Head Pose"

Audio-driven Talking Face Video Generation with Learning-based Personalized Head Pose We provide PyTorch implementations for our arxiv paper "Audio-dr

Ran Yi 497 Jan 09, 2023
A python program to cut longer MP3 files (i.e. recordings of several songs) into the individual tracks.

I'm writing a python script to cut longer MP3 files (i.e. recordings of several songs) into the individual tracks called ReCut. So far there are two

Dönerspiess 1 Oct 27, 2021
Gammatone-based spectrograms, using gammatone filterbanks or Fourier transform weightings.

Gammatone Filterbank Toolkit Utilities for analysing sound using perceptual models of human hearing. Jason Heeris, 2013 Summary This is a port of Malc

Jason Heeris 188 Dec 14, 2022
Marsyas - Music Analysis, Retrieval and Synthesis for Audio Signals

Welcome to MARSYAS. MARSYAS is a software framework for rapid prototyping of audio applications, with flexibility and extensibility as primary concer

Marsyas Developers Group 364 Oct 31, 2022
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
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
Tradutor de um arquivo MIDI para ser usado em um simulador RISC-V(RARS)

Tradutor_MIDI-RISC-V Tradutor de um arquivo MIDI para ser usado em um simulador RISC-V(RARS) *O resultado sai com essa formatação: nota,duração,nota,d

Gabriel B. G. 4 Sep 02, 2022
Telegram Bot to play music in VoiceChat with Channel Support and autostarts Radio.

VCPlayerBot Telegram bot to stream videos in telegram voicechat for both groups and channels. Supports live streams, YouTube videos and telegram media

Abdisamad Omar Mohamed 1 Oct 15, 2021
Klangbecken: The RaBe Endless Music Player

Klangbecken Klangbecken is the minimalistic endless music player for Radio Bern RaBe based on liquidsoap. It supports configurable and editable playli

Radio Bern RaBe 8 Oct 09, 2021
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
A python package for calculating the PESQ.

PyPESQ (WIP) Pypesq is a python wrapper for the PESQ score calculation C routine. It only can be used in evaluation purpose. INSTALL pip install https

Jingdong Li 269 Dec 18, 2022
Converting UGG files from Rode Wireless Go II transmitters (unsompressed recordings) to WAV format

Rode_WirelessGoII_UGG2wav Converting UGG files from Rode Wireless Go II transmitters (uncompressed recordings) to WAV format Story I backuped the .ugg

Ján Mazanec 31 Dec 22, 2022
Neural building blocks for speaker diarization: speech activity detection, speaker change detection, overlapped speech detection, speaker embedding

⚠️ Checkout develop branch to see what is coming in pyannote.audio 2.0: a much smaller and cleaner codebase Python-first API (the good old pyannote-au

pyannote 2.1k Dec 31, 2022