diff --git a/README.md b/README.md index 2b3e0a3..e7284a6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ _Python bindings for FluidSynth_ -This package contains python bindings for FluidSynth. FluidSynth is a software +This package contains Python bindings for FluidSynth. FluidSynth is a software synthesizer for generating music. It works like a MIDI synthesizer. You load patches, set parameters, then send NOTEON and NOTEOFF events to play notes. Instruments are defined in SoundFonts, generally files with the extension SF2. @@ -10,6 +10,8 @@ FluidSynth can either be used to play audio itself, or you can call a function that returns chunks of audio data and output the data to the soundcard yourself. FluidSynth works on all major platforms, so pyFluidSynth should also. +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/nwhitehead/pyfluidsynth/ci.yml) | ![PyPI - Version](https://img.shields.io/pypi/v/pyFluidSynth) | ![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/pyFluidSynth) | + ## Requirements @@ -26,6 +28,7 @@ is a self-contained Python package that includes [TinySoundFont](https://github.com/schellingb/TinySoundFont) for SoundFont playback and is permissively licensed. + ## Installation To use the latest official release: @@ -38,7 +41,7 @@ To use the latest official release: To use pre-release versions of this package, clone this repository, go to the repository directory, then do: - pip install . + pip install --editable . ## Example @@ -188,12 +191,12 @@ register it: fs = fluidsynth.Synth() # init and start the synthesizer as described aboveā€¦ -synthID = seq.register_fluidsynth(fs) +synth_id = seq.register_fluidsynth(fs) ``` -You have to keep the ID and use it as a `target` for the midi events +You have to keep `synth_id` and use it as a `target` for the midi events you want to schedule. Now, you can sequence actual notes: ```python -seq.note_on(time=500, absolute=False, channel=0, key=60, velocity=80, dest=synthID) +seq.note_on(time=500, absolute=False, channel=0, key=60, velocity=80, dest=synth_id) ``` If you use relative timing like above, the sequencer will schedule the event the specified time from the current position. @@ -202,7 +205,7 @@ absolute track positions (in ticks). So the following code snippet will do the same as the one above: ```python current_time = seq.get_tick() -seq.note_on(current_time + 500, 0, 60, 80, dest=synthID) +seq.note_on(current_time + 500, 0, 60, 80, dest=synth_id) ``` You can also register your own callback functions to be called at certain ticks: @@ -210,11 +213,11 @@ certain ticks: def seq_callback(time, event, seq, data): print('callback called!') -callbackID = sequencer.register_client("myCallback", seq_callback) +callback_id = sequencer.register_client("myCallback", seq_callback) -sequencer.timer(current_time + 2000, dest=callbackID) +sequencer.timer(current_time + 2000, dest=callback_id) ``` -Note that event and seq are low-level objects, not actual python objects. +Note that event and seq are low-level objects, not actual Python objects. You can find a complete example (inspired by [this one from the fluidsynth library](http://www.fluidsynth.org/api/index.html#Sequencer)) in the test folder. @@ -231,6 +234,7 @@ the functions incorrectly sometimes. This project was originally created by Nathan Whitehead `nwhitehe@gmail.com` but is the work of many. See [CONTRIBUTORS](./CONTRIBUTORS.md). + ## License Released under the LGPL v2.1 or any later diff --git a/fluidsynth.py b/fluidsynth.py index 1fbb577..082a13e 100644 --- a/fluidsynth.py +++ b/fluidsynth.py @@ -41,13 +41,11 @@ ) from ctypes.util import find_library -# DLL search method changed in Python 3.8 # https://docs.python.org/3/library/os.html#os.add_dll_directory -if hasattr(os, 'add_dll_directory'): - os.add_dll_directory(os.getcwd()) - os.add_dll_directory('C:\\tools\\fluidsynth\\bin') - # Workaround bug in find_library, it doesn't recognize add_dll_directory - os.environ['PATH'] += ';C:\\tools\\fluidsynth\\bin' +os.add_dll_directory(os.getcwd()) +os.add_dll_directory('C:\\tools\\fluidsynth\\bin') +# Workaround bug in find_library, it doesn't recognize add_dll_directory +os.environ['PATH'] += ';C:\\tools\\fluidsynth\\bin' # A function to find the FluidSynth library # (mostly needed for Windows distributions of libfluidsynth supplied with QSynth) diff --git a/pyproject.toml b/pyproject.toml index cf8e6a9..6336e59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,17 +7,15 @@ requires = [ "setuptools>=61.2" ] name = "pyfluidsynth" version = "1.3.4" description = "Python bindings for FluidSynth, a MIDI synthesizer that uses SoundFont instruments" -readme.content-type = "text/markdown" -readme.file = "README.md" +readme = { file = "README.md", content-type = "text/markdown" } authors = [ { name = "Nathan Whitehead", email = "nwhitehe@gmail.com" } ] classifiers = [ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - # "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.13", # Windows: https://github.com/nwhitehead/pyfluidsynth/issues/77 ] dependencies = [ "numpy" ] @@ -28,7 +26,7 @@ py-modules = [ "fluidsynth" ] include-package-data = false [tool.ruff] -target-version = "py38" +target-version = "py39" line-length = 123 lint.select = [ @@ -57,6 +55,7 @@ lint.select = [ "PERF", # Perflint "PGH", # pygrep-hooks "PIE", # flake8-pie + "PL", # Pylint "PT", # flake8-pytest-style "PYI", # flake8-pyi "RSE", # flake8-raise @@ -69,6 +68,7 @@ lint.select = [ "TD", # flake8-todos "TID", # flake8-tidy-imports "UP", # pyupgrade + "W", # pycodestyle "YTT", # flake8-2020 # "A", # flake8-builtins # "ANN", # flake8-annotations @@ -82,14 +82,14 @@ lint.select = [ # "FURB", # refurb # "ICN", # flake8-import-conventions # "N", # pep8-naming - # "PL", # Pylint # "PTH", # flake8-use-pathlib # "Q", # flake8-quotes # "RET", # flake8-return # "RUF", # Ruff-specific rules # "T20", # flake8-print # "TRY", # tryceratops - # "W", # pycodestyle ] lint.per-file-ignores."__init__.py" = [ "E402" ] lint.per-file-ignores."test/*" = [ "S101" ] +lint.pylint.allow-magic-value-types = [ "int", "str" ] +lint.pylint.max-args = 8 diff --git a/test/sequencerTest.py b/test/sequencerTest.py index 66ed022..fa9f999 100644 --- a/test/sequencerTest.py +++ b/test/sequencerTest.py @@ -12,7 +12,7 @@ def schedule_next_callback(): sequencer.timer(callbackdate, dest=mySeqID) def schedule_next_sequence(): - global now + global now # noqa: PLW0603 # the sequence to play # the beat : 2 beats per sequence sequencer.note(int(now + seqduration * 1/2), 0, 60, duration=250, velocity=80, dest=synthSeqID) @@ -38,7 +38,7 @@ def local_file_path(file_name: str) -> str: return join(dirname(__file__), file_name) if __name__=="__main__": - global sequencer, fs, mySeqID, synthSeqID, now + global sequencer, fs, mySeqID, synthSeqID, now # noqa: PLW0604 fs = fluidsynth.Synth() fs.start() # you might have to use other drivers: