Giter Site home page Giter Site logo

ohollo / chord-extractor Goto Github PK

View Code? Open in Web Editor NEW
100.0 6.0 17.0 27.49 MB

Python library for extracting chords from multiple sound file formats

Home Page: https://ohollo.github.io/chord-extractor/

License: GNU General Public License v2.0

Python 96.87% Dockerfile 3.13%

chord-extractor's Introduction

chord-extractor

Python package

Python library for extracting chord sequences from sound files of multiple formats with the option of leveraging multiprocessing to source data from many files quickly. The extraction process wraps Chordino but is extensible to easily incorporate additional techniques.

Why?

  • Primarily intended for those analysing musical pieces and their harmonic progressions.
  • Chordino is a C++ Vamp Plugin for extracting chords but even with the helpful vamp Python wrapper, it is not trivial to set everything up. This project aims to help clarify the prerequisites and get the user up and running with extracting chords with as little fuss as possible.
  • Chord extraction of many files is time-consuming. This library gives the option of parallelization (on a particular machine) to cut the overall processing time considerably.
  • There are certain music files that are readily available but need converting prior to using the plugin (e.g. MIDI). This preprocessing is also included and can also be extended to convert other formats or other tasks that can take advantage of multiprocessing.

Installation

The package is hosted on PyPI, but prior to installing that there are a few prerequisite steps. The following instructions assume the latest versions of Ubuntu, and it is recommended to use a modern 64-bit Linux system. That said, equivalent steps should work if you are using another OS.

  • sudo apt-get install libsndfile1 - To read sound files.
  • (OPTIONAL) sudo apt-get install timidity - If wanting to extract chords from MIDIs (timidity converts midi to wav files).
  • (OPTIONAL) sudo apt-get install ffmpeg - If wanting to extract from mp3s
  • pip install numpy - numpy needs to be installed in your Python environment prior to installing chord-extractor. This is necessary as one of the package dependencies (vamp) requires it in its setup.py.

After that you are ready to run

pip install chord-extractor

NOTE: Included in the installation is a compiled library for Chordino. If you are using a Linux 64-bit OS, chord-extractor will default to using this binary. If you require a different version of the binary (i.e. you are using a different OS), please download the Vamp plugin pack installer for example if using another OS, please set the environment variable VAMP_PATH to point to the directory with the downloaded binary.

Usage

Extract chords from a single file:

from chord_extractor.extractors import Chordino

# Setup Chordino with one of several parameters that can be passed
chordino = Chordino(roll_on=1)  

# Optional, only if we need to extract from a file that isn't accepted by librosa
conversion_file_path = chordino.preprocess('/some_path/some_song.mid')

# Run extraction
chords = chordino.extract(conversion_file_path)
# => [  ChordChange(chord='N', timestamp=0.371519274), 
#       ChordChange(chord='C', timestamp=0.743038548), 
#       ChordChange(chord='Am7b5', timestamp=8.54494331),...]

To perform extraction of many files, even with various file types, we can pass a list of files in a single function. Here we can have 2 conversions running in parallel (preprocessing), and 2 extractions in parallel.

from chord_extractor.extractors import Chordino
from chord_extractor import clear_conversion_cache, LabelledChordSequence

files_to_extract_from = [
  '/path/file1.mid',
  '/path/file2.wav',
  '/path/file3.mp3',
  '/path/file4.ogg'
]

def save_to_db_cb(results: LabelledChordSequence):
    # Every time one of the files has had chords extracted, receive the chords here 
    # along with the name of the original file and then run some logic here, e.g. to 
    # save the latest data to DB

chordino = Chordino()

# Optionally clear cache of file conversions (e.g. wav files that have been converted from midi)
clear_conversion_cache()

# Run bulk extraction
res = chordino.extract_many(files_to_extract_from, callback=save_to_db_cb, num_extractors=2,
                            num_preprocessors=2, max_files_in_cache=10, stop_on_error=False)
# => LabelledChordSequence(
#	id='/tmp/extractor/d8b8ab2f719e8cf40e7ec01abd116d3a', 
#	sequence=[ChordChange(chord='N', timestamp=0.371519274), 
#	    ChordChange(chord='C', timestamp=0.743038548), 
#	    ChordChange(chord='Am7b5', timestamp=8.54494331),...])

If you want to implement your own extraction logic and/or add functionality to convert from another file format, whilst still taking advantage of the inbuilt multiprocessing logic, this can be done by extending the base class ChordExtractor

from chord_extractor import ChordExtractor, ChordChange
from typing import Optional, List
import os

class MyExtractor(ChordExtractor):
    def __init__(self, some_new_setting):
      self.some_new_setting = ####
    
    def preprocess(self, path: str) -> Optional[str]:
        conversion_path = super().preprocess(path)
        ext = os.path.splitext(path)[1]
        if ext in ['.newfmt']:
          # preprocess file at path, convert to .newfmt and have path to new temporary file
          conversion_path = ####
        return conversion_path
    
    def extract(self, filepath: str) -> List[ChordChange]:
        # Custom extraction logic using self.some_new_setting perhaps

For more documentation see here.

Contributing

Contributions, whether adding new functionality or raising an issue, are always welcome. You can see instructions on how to contribute in the CONTRIBUTING.md.

chord-extractor's People

Contributors

ohollo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

chord-extractor's Issues

Python 3.9+ ?

Hi,
I would like to try your library but the setup.py forces python to be less than 3.9.
It is really the case? Can you bump to <4.0 ?
Thank you

Possible to match chord change with beat?

Hi, thank for the terrific package.

Chord Extractor can retrieve correct chord most of the time. However the timing is still not really accurate.

I've monitor the chord change with librosa beat tracker and notice a slight incorrect value of the time when chord changed. Sometime the timing is 1 or more beat before/after the chord actually changed.

Can you improuve that part?

Thank you.

When extracting, it will continuously output lyrics

I think that when extracting, not outputting things should make the process faster (saving I/O time). I added '-idqqq' to the timidity command in converters.py, and the verbose has indeed decreased, but it will still be output Lyrics, what is the reason?

Can't install on ubuntu 18 x64

Hi there, I've tried this on windows and it work perfect.

However as I tried to install on Ubuntu 18 there's an issue with "Failed building wheel for llvmlite"

Could you please help fix it. Thank.

tuanha@tuanha-MS-7918:~$ pip3 install chord_extractor
Collecting chord_extractor
  Using cached https://files.pythonhosted.org/packages/18/fe/d87737db490da2c13f23cd7120db3ee8aa27a32c465ded3903e733a5fc8c/chord_extractor-0.1.2-py3-none-any.whl
Collecting vamp (from chord_extractor)
Collecting librosa (from chord_extractor)
  Using cached https://files.pythonhosted.org/packages/e4/1c/23ef2fd02913d65d43dc7516fc829af709314a66c6f0bdc2e361fdcecc2d/librosa-0.9.2-py3-none-any.whl
Collecting decorator>=4.0.10 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl
Collecting packaging>=20.0 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/05/8e/8de486cbd03baba4deef4142bd643a3e7bbe954a784dc1bb17142572d127/packaging-21.3-py3-none-any.whl
Collecting scikit-learn>=0.19.1 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/f5/ef/bcd79e8d59250d6e8478eb1290dc6e05be42b3be8a86e3954146adbc171a/scikit_learn-0.24.2-cp36-cp36m-manylinux1_x86_64.whl
Collecting soundfile>=0.10.2 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/e3/ba/42a4370e4fb84fd8956dabf115a0b7f0f3071400a52554526fe5fd32f275/soundfile-0.11.0-py2.py3-none-any.whl
Collecting resampy>=0.2.2 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/f2/d3/5209fd2132452f199b1ddf0d084f9fd5f5f910840e3b282f005b48a503e1/resampy-0.4.2-py3-none-any.whl
Collecting joblib>=0.14 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/7c/91/d3ba0401e62d7e42816bc7d97b82d19c95c164b3e149a87c0a1c026a735e/joblib-1.1.1-py2.py3-none-any.whl
Collecting pooch>=1.0 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/8d/64/8e1bfeda3ba0f267b2d9a918e8ca51db8652d0e1a3412a5b3dbce85d90b6/pooch-1.6.0-py3-none-any.whl
Collecting audioread>=2.1.9 (from librosa->chord_extractor)
Collecting numba>=0.45.1 (from librosa->chord_extractor)
Collecting numpy>=1.17.0 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/45/b2/6c7545bb7a38754d63048c7696804a0d947328125d81bf12beaa692c3ae3/numpy-1.19.5-cp36-cp36m-manylinux1_x86_64.whl
Collecting scipy>=1.2.0 (from librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/c8/89/63171228d5ced148f5ced50305c89e8576ffc695a90b58fe5bb602b910c2/scipy-1.5.4-cp36-cp36m-manylinux1_x86_64.whl
Collecting pyparsing!=3.0.5,>=2.0.2 (from packaging>=20.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl
Collecting threadpoolctl>=2.0.0 (from scikit-learn>=0.19.1->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/61/cf/6e354304bcb9c6413c4e02a747b600061c21d38ba51e7e544ac7bc66aecc/threadpoolctl-3.1.0-py3-none-any.whl
Collecting cffi>=1.0 (from soundfile>=0.10.2->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/3a/12/d6066828014b9ccb2bbb8e1d9dc28872d20669b65aeb4a86806a0757813f/cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Collecting requests>=2.19.0 (from pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl
Collecting appdirs>=1.3.0 (from pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl
Collecting llvmlite<0.37,>=0.36.0rc1 (from numba>=0.45.1->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/19/66/6b2c49c7c68da48d17059882fdb9ad9ac9e5ac3f22b00874d7996e3c44a8/llvmlite-0.36.0.tar.gz
Collecting setuptools (from numba>=0.45.1->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/b0/3a/88b210db68e56854d0bcf4b38e165e03be377e13907746f825790f3df5bf/setuptools-59.6.0-py3-none-any.whl
Collecting pycparser (from cffi>=1.0->soundfile>=0.10.2->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl
Collecting idna<4,>=2.5; python_version >= "3" (from requests>=2.19.0->pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl
Collecting urllib3<1.27,>=1.21.1 (from requests>=2.19.0->pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/fe/ca/466766e20b767ddb9b951202542310cba37ea5f2d792dae7589f1741af58/urllib3-1.26.14-py2.py3-none-any.whl
Collecting charset-normalizer~=2.0.0; python_version >= "3" (from requests>=2.19.0->pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/06/b3/24afc8868eba069a7f03650ac750a778862dc34941a4bebeb58706715726/charset_normalizer-2.0.12-py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.19.0->pooch>=1.0->librosa->chord_extractor)
  Using cached https://files.pythonhosted.org/packages/71/4c/3db2b8021bd6f2f0ceb0e088d6b2d49147671f25832fb17970e9b583d742/certifi-2022.12.7-py3-none-any.whl
Building wheels for collected packages: llvmlite
  Running setup.py bdist_wheel for llvmlite ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-covvbir1/llvmlite/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmpbuxhprdcpip-wheel- --python-tag cp36:
  running bdist_wheel
  /usr/bin/python3 /tmp/pip-build-covvbir1/llvmlite/ffi/build.py
  LLVM version... Traceback (most recent call last):
    File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 220, in <module>
      main()
    File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 210, in main
      main_posix('linux', '.so')
    File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 134, in main_posix
      raise RuntimeError(msg) from None
  RuntimeError: Could not find a `llvm-config` binary. There are a number of reasons this could occur, please see: https://llvmlite.readthedocs.io/en/latest/admin-guide/install.html#using-pip for help.
  error: command '/usr/bin/python3' failed with exit status 1
  
  ----------------------------------------
  Failed building wheel for llvmlite
  Running setup.py clean for llvmlite
Failed to build llvmlite
Installing collected packages: vamp, decorator, pyparsing, packaging, threadpoolctl, numpy, scipy, joblib, scikit-learn, pycparser, cffi, soundfile, llvmlite, setuptools, numba, resampy, idna, urllib3, charset-normalizer, certifi, requests, appdirs, pooch, audioread, librosa, chord-extractor
  Running setup.py install for llvmlite ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-covvbir1/llvmlite/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-leq86ucp-record/install-record.txt --single-version-externally-managed --compile --user --prefix=:
    running install
    /home/tuanha/.local/lib/python3.6/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
      setuptools.SetuptoolsDeprecationWarning,
    running build
    got version from file /tmp/pip-build-covvbir1/llvmlite/llvmlite/_version.py {'version': '0.36.0', 'full': 'e6bb8d137d922bec8beeb01a237254778759becd'}
    running build_ext
    /usr/bin/python3 /tmp/pip-build-covvbir1/llvmlite/ffi/build.py
    LLVM version... Traceback (most recent call last):
      File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 220, in <module>
        main()
      File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 210, in main
        main_posix('linux', '.so')
      File "/tmp/pip-build-covvbir1/llvmlite/ffi/build.py", line 134, in main_posix
        raise RuntimeError(msg) from None
    RuntimeError: Could not find a `llvm-config` binary. There are a number of reasons this could occur, please see: https://llvmlite.readthedocs.io/en/latest/admin-guide/install.html#using-pip for help.
    error: command '/usr/bin/python3' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-covvbir1/llvmlite/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-leq86ucp-record/install-record.txt --single-version-externally-managed --compile --user --prefix=" failed with error code 1 in /tmp/pip-build-covvbir1/llvmlite/
tuanha@tuanha-MS-7918:~$ 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.