Changelog#
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
2.0.0 - 2023-03-18#
Welcome PyFLP 2.0 🎉 Read the previous changelogs to get the complete list of changes.
Added#
FruityBloodOverdrive
- thanks to @@ttaschke #120.
Changed#
Docs are way more easier to navigate now.
Fixed#
VSTPluginEvent.__setitem__
and_VSTPluginProp._set
#113.
Removed#
Support for PyPy 3.7 (unable to run tox, cannot find a download).
2.0.0a7 - 2022-12-19#
Added#
Changed#
Renamed
PlaylistEvent.track_index
toPlaylistEvent.track_rvidx
.Optimized
Arrangement.tracks
iteration logic - 50% lesser time to run tests.StructEventBase.value
raisesNotImplementedError
.Ambiguous
Pattern.__iter__
refactored into a propertyPattern.notes
.Pattern.index
renamed toPattern.iid
.Improved
__repr__
strings; replaced withModelReprMixin
at some places use__str__
for a more human readable representation.
Fixed#
Patterns.__getitem__
didn’t work with pattern names as documented.
Removed#
Ambiguous
__index__
methods from a bunch of model classes.Unimplemented
Slot.controllers
.
2.0.0a6 - 2022-11-19#
Added#
Changed#
Channel.group
becomes a read-only property (modify event to change channel group).PLItemBase.offsets
and its fields inPlaylistEvent
are float32 Thanks tochrslg
from Stackoverflow and @jubabrut.Track.height
returns anstr
of its percentage e.g.100%
.Instrument.plugin
andSlot.plugin
return_PluginBase
for unimplemented native plugins #102.Reimplemented
EventTree
to use a list and got a 10+% perf boost in unit tests.
Fixed#
Removed#
Track.locked_height
as what this quantity stores is unknown to me yet.Use of fixture factories in unittests #74.
2.0.0a5.post - 2022-10-31#
Changed#
Upgrade
construct-typing
to 0.5.3.
2.0.0a5 - 2022-10-28#
Added#
Implementation for
Channel
andPattern
playlist items #84.FX.remove_dc
,FX.trim
,FX.fix_trim
,FX.crossfade
,FX.length
,FX.normalize
,FX.inverted
,FX.start
#55.Normalized linear values for certain properties, more user friendly to deal with. The required encode / decode is done at event level itself.
TimeStretching.time
,TimeStretching.pitch
,TimeStretching.multiplier
#87.(Undiscovered)
MIDIControllerEvent
.Delay.mod_x
,Delay.mod_y
,Delay.fat_mode
andDelay.ping_pong
#88.Improve enum performance by using
f-enum
library (pyflp.parse
is 50% faster).Time.gate
,Time.shift
andTime.full_porta
#89.Experimental Python 3.11 support is back.
A shit ton of flags in
VSTPlugin
and refactoring #95.WrapperEvent.page
,WrapperEvent.height
,WrapperEvent.width
#93.ItemModel.__setitem__
propagates back changes to owner event #97.
Changed#
PlaylistItemBase.offsets
now returns start and end offsets.Use git commit for
construct-typing
which has fixed certain bugs.Rename
PlaylistItemBase
toPLItemBase
andPatternPlaylistItem
toPatternPLItem
.Rename
Polyphony
membersis_mono
tomono
andis_porta
toporta
.NoModelsFound
also basesLookupError
now.Compiled
VSTPluginEvent.STRUCT
.
Fixed#
Removed#
PlaylistItemBase.start_offset
andPlaylistItemBase.end_offset
.Redundant exceptions
ExpectedValue
,UnexpectedType
.Undiscovered
num_inputs
,num_outputs
andvst_number
fromVSTPlugin
.
2.0.0a4 - 2022-10-22#
The way models were passed events has changed. I designed a new data structure
called EventTree
(check pyflp._events
) to allow the insertion and
deletion of events like a list while preserving the speed of a dict lookups.
Sounds awfully like multidict
except that it doesn’t allow mutable views.
EventTree
knows its parents and any attempt to insert or delete an event
from it will also affect its parents and vice-versa. Took quite some to do.
EventTree
will allow for insertion / removal of events when corresponding
descriptor setters / deleters (yet to implement) are invoked. This can allow
for wonderful things like creating new channels, moving inserts etc.
Added#
Changed#
Simplified some
__repr__
strings.Event IDs are all
EventEnum
members (better repr-strings).PyFLP is guaranteed to be not thread-safe.
Moved up
Sampler.cut_group
to_SamplerInstrument
.
Fixed#
ModelReprMixin
.
Removed#
2.0.0a3 - 2022-10-08#
Added#
100% mypy tested for all you mypy geeks. It makes me play cat-and-mouse.
Automation
points and LFO, via #29.
Changed#
All
StructBaseEvent
classes overhauled to use theconstruct
library.EventBase.__len__
is nowEventBase.size
, a property.Shift all subclass event parsing to
PODEventBase
.Replace all uses of
bytesioex
with equivalents fromconstruct
.Struct definitions moved to
StructEventBase
itself.Enums used in structs directly now inherit from
construct_typed.EnumBase
.LFO
renamed toSamplerLFO
to be distinguishable fromAutomationLFO
.
Fixed#
Removed#
_StructMeta
(voodoo magic) andStructBase
frompyflp._events
.SoundgoodizerMode
,FruityFastDistKind
,StereoEnhancerInvertPosition
,StereoEnhancerEffectPosition
frompyflp.plugin
in favour of equivalent string literals.Protocol subclassing of
EventBase
hierarchy.Faulty
EventBase.__hash__
.Python 3.11 support due to https://github.com/timrid/construct-typing/issues/15
Incomplete support for
Sequence
in model collections.
2.0.0a2 - 2022-10-01#
Added#
FX.clip
,FX.fade_stereo
,FX.freq_tilt
,FX.pogo
,FX.ringmod
,FX.swap_stereo
&FX.reverse
#55.TimeStretching.mode
andStretchMode
#56.Playback.start_offset
#57.Content.declick_mode
andDeclickMode
#58.User guide and contibutor’s guide.
Official support for Python 3.11.
Super basic
__repr__
forStructBase
to ease debugging.Envelope.amount
,Envelope.synced
,LFO.amount
,LFO.attack
,LFO.predelay
&LFO.speed
#69.
Changed#
Moved
stretching
toSampler
, instruments don’t have it.Note.key
now returns a note name with octave #66.A cleaner implementation of
MixerParamsEvent
.Layer.__repr__
now shows the number of children also.Separated test assets into presets for better isolation of results #6.
Renamed
LFO.is_synced
toLFO.synced
andLFO.is_retrig
toLFO.retring
.StructBase
andListEventBase
are lazily evaluated now.Model collections are indexable by item names as well #45.
Fixed#
Removed#
Images for individual FX properties as they were redundant.
Redundant member
_SamplerInstrument.flags
.
2.0.0a1 - 2022-09-21#
Added#
PlaylistItemBase.group
forChannelPlaylistItem
andPatternPlaylistItem
#36.More info in contributor’s guide.
VSCode Python extension configuration, recommended extensions and tasks.
ChannelRack.height
which tells the height of the channel rack in pixels.Track[x]
returnsTrack.items[x]
.Patterns
warns when tried to be accessed with an index of 0.Note.group
, a number which notes of the same group share #28.Note.slide
which indicates whether a note is a sliding note.Plugin wrapper properties to docs.
A user guide section in docs.
Sampler.content
,Layer.random
&Layer.crossfade
#24.Playback.ping_pong_loop
.
Changed#
Pattern.notes
refactored intoPattern.__iter__
.Sampler.sample_path
returnspathlib.Path
instead ofstr
now #41.PluginID.Data
events get parsed during event collection itself.All models are now equatable and hashable.
Fixed#
Arrangement
parsing logic is incorrect #32.Track.color
returnsint
instead ofcolour.Color
#33._PlaylistItemStruct.track_index
should be 2 bytes #36.Tracks don’t get assigned playlist items #37.
KeyError when accessing
Track.content_locked
#38.Channel type wasn’t correctly detected at times #40.
Arrangements.height
was actuallyChannelRack.height
#43.TypeError when accessing
Insert.dock
#44.Pattern.note
andPattern.controllers
#48.Track.items
#49Certain properties of
Note
were interpreted incorrectly.Slot.plugin
wasn’t working at all (events, properties, repr) #53.FruitySend.send_to
was interepreted incorrectly.Instrument.plugin
andSlot.plugin
setter.Playback.use_loop_points
.
Removed#
Arrangements.height
.
2.0.0a0 - 2022-09-14#
PyFLP has been rewritten ✨
Highlights:
Richer events: Variable data events now parse their structure themselves. Fixed size events are categorized closely to the data they represent.
Lazy evaluation: Properties are evaluated as lazily as possible to prevent the use of private variables and keep them synced with event data.
Neatly organised models: Appropriate use of composition and subclassing.
Zero pre-parse field validation: Makes sense for an undocumented format.
Fully type hinted: Ensures strict adherence with pyright.
Simplified single-level module hierarchy to ease imports.
Docs now contain images for corresponding model types.
The major version number bump indicates a breaking change, however I would highly encourage you to upgrade to this version. **I WILL NOT BE MAINTAINING OLDER VERSIONS.**
1.1.2 - Unreleased#
Fixed#
#9, thanks to @zacanger.
1.1.1 - 2022-07-10#
Added#
Avoid mkdocs warnings in tox.
Changed#
_FLObject._save
always returns a list now.CI: Merge
dev
andpublish
workflows into one.
Fixed#
#8.
Type hints and type variables are much better.
FSoftClipper
property setter typo caused it to be set to zero.ChannelParameters._save()
didn’t return an event.
Removed#
Wait action in CI workflow.
setup-cfg-fmt
pre-commit hook, why?
1.1.0 - 2022-05-29#
Added#
Support for Fruity Stereo Enhancer @@nickberry17
Instructions for alternate methods to install PyFLP.
Changed#
Improvements to CI
Fixed#
Incorrect encoding used to dump UTF-16 strings in
_TextEvent
.#4.
Removed#
_FLObject.max_count
,MaxInstancesError
,test_flobject.py
and_MaxInstancedFLObject
.Gitter links from README and room itself, due to inactivity.
1.0.1 - 2022-04-02#
This update is more about QOL improvements, testing and refactoring. Few bugs have been fixed as well, while Python 3.6 support has been deprecated.
Added#
Adopted
bandit
._MaxInstancedFLObject
:FLObject
with a limit on number of instances.GPL3 short license headers.
Missing docs about
PatternNote
andPatternController
events.Exceptions:
InvalidHeaderSizeError
,InvalidMagicError
andMaxInstancesError
.Import statements in submodules to simplify import process externally.
Test validators and properties and project version setter.
OTT plugin to test project to test VST plugins.
Changed#
All use of
assert
has been replaced by exceptions (bandit: assert-used).Version links in changelog now show changes.
LF line endings used and enforced everywhere.
ppq
field moved to_FLObject
fromPlaylist
.Much improved
tox.ini
and pre-commit configuration.Modules which aren’t meant for external use are prefixed with a _.
Simplified property declaration.
Deprecated#
Python 3.6 support will be dropped in a future major release.
Fixed#
All this time,
VSTPluginEvent
was never getting created/saved.Lint errors reported by flake8, pylint and bandit.
Just realised
__setattr__
works only on instances 😅, came up with_FLObjectMeta
which is the metaclass used by_FLObject
.
Removed#
Redundant
__repr__
fromPatternNote
.
1.0.0 - 2021-11-12#
Highlights#
The entire module hierarchy of PyFLP has been simplified.
Internal/abstract base classes have bee renamed to start with _.
repr
for_FLObject
subclasses.The way properties are handled is now completely changed.
Data events get parsed by a
DataEvent
subclass.Way better testing, with a coverage of whooping 79%.
color
properties now return acolour.Color
object.Almost everything has a docstring now, even enum members.
PyFLP has adopted Contributor Covenant Code of Conduct v2.1.
Added#
__repr__()
for all_FLObject
subclasses.Channel.color
,Insert.color
andPattern.color
now returncolour.Color
. This is implemented byColorEvent
(*which subclassesDWordEvent
*).New event implementations for
ChannelFX.EventID
(Cutoff
,Fadein
,Fadeout
and more).New event implementations for
Channel.EventID
(ChannelTracking
,ChannelLevels
,ChannelLevelOffsets
,ChannelPolyphony
and more).Channel.cut_group
implementingChannel.EventID.CutSelfCutBy
.Remote controllers (
RemoteController
). Accessible fromProject.controllers
.Saving for
VSTPlugin
.All enum members used by
FLObject
subclasses now have a docstring.Added links in docstrings to official FL Studio Manual wherever possible.
Parser.__build_event_store()
uses inner methods now to parse different kind of events; very helpful for the newDataEvents
.Added support for pattern controller events (
PatternController
,PatternControllerEvent
who implementPatternEventID.Controllers
).Many attribute docstrings now include minimum, maximum and default values. These limits are enforced by setters.
Added
.editorconfig
, using CRLF line endings btw.Added
test_parser.py
andtest_events.py
.Parser.parse_zip
now accepts abytes
object forzip_file
parameter.Misc.registered
forMisc.EventID.Registered
.
Changed#
All
_FLObject
subclasses have been moved to parentpyflp/
frompyflp/flobject/
to ease import names.All
Event
subclasses have been moved in a singleevent.py
andevent/
folder is removed.All event ID enum names are now inner classes of
_FLObject
subclasses.Constructor of
Project
has been simplified.VSTPlugin
‘s underlying event now supports saving, it has been refactored out of_parse_data_event
also.InsertParametersEvent
to replace the equivalent parsing inInsert._parse_data_event
.The
TODO
(deleted now) has been changed to reflect the type of goals._FLObject.save
is now_FLObject._save
.Some constants present in
utils.py
have been moved toconstants.py
.Docs include a brief summary of the underlying data event wherever applicable.
Minor property name changes; made them more concise.
Absolute imports are used everywhere now.
Fixed#
ChannelFXReverb
was not getting initialised.InsertParamsEvent
was not getting initialised.Syntax is highlighted in the docs as expected now.
FNotebook2
text parsing.Insert.routing
returnedTrue
for all tracks.Misc.start_date
andMisc.work_time
parsing.
Removed#
Any and all sort of logging, not useful anymore. Haven’t seen any 3rd party Python library ever using it. Used
warnings
wherever necessary.mypy
. Its useless tbh, I will use types as I see fit.Setters for all properties containing
_FLObject
(or any sort of a collection of them), e.g. Arrangement.tracks.
0.2.0#
Highlights#
PyFLP has passed the null test for a full project of mine (FL 20.7.2) 🥳.
This library uses code from FLParser, a GPL license project, PyFLP is now under GPL.
API reference documentation is complete now.
Few new events implemented for
Channel
.Refactored
FLObject
andPlugin
.
FLObject
refactoring#
parseprop
is now_parseprop
.All
_parseprop
delegates are now “protected” as well.setprop
is now_setprop
.
Added#
ChannelEvent.Delay
is implemented byChannelDelay
andChannel.delay
.Event.to_raw
andEvent.dump
now log when they are called.Exceptions
DataCorruptionDetected
andOperationNotPermitted
.
Fixed#
Can definitely say, all naming inconsistencies have been fixed.
Fixed
TimeMarker
assign toArrangement
logic inParser
.Extraneous data dumped sometimes by
InsertSlotEvent.Plugin
, caused due to double dumping of same events.Empty pattern events,
PatternEvent.Name
andPatternEvent.Color
don’t get saved.
❗ These versions below don’t work due to naming inconsistencies 😅, you will not find them 👇
0.1.2#
Added#
More docs.
Add some new properties/events to
Channel
.A sample empty FLP has been provided to allow running tests.
All
FLObject
subclasses now have a basic__repr__
method.
Fixed#
Improve the GitHub workflow action, uploads to PyPI will not happen unless the test is passed.
Fix all naming inconsistencies caused due to migration to `\ ``BytesIOEx`<https://github.com/demberto/BytesIOEx>`_</del>` Not all.
Known issues#
Same as in 0.1.1
0.1.1#
The first version of PyFLP that works correctly 🥳 No, unfortunately
Highlights#
Changed documentation from Sphinx to MkDocs.
FLPInfo is now a separate package.
FLPInspect is now a separate package.
PyFLP now uses BytesIOEx as an external dependency.
Fixed#
ByteEvent
,WordEvent
andDWordEvent
now raise aTypeError
. when they are initialised with the wrong size of data.Fix setup.cfg, project structure is now as expected, imports will work.
Docs are now up and running.
Known issues#
Extraneous data dumped sometimes by
InsertSlotEvent.Plugin
, why this is caused is not known.
❗ These versions below don’t work because I didn’t know how to configure ``setup.cfg`` properly 😅
0.1.0#
flpinspect
- An FLP Event Viewer made using Tkinter.flpinfo
- A CLI utility to get basic information about an FLP.Switched to MIT License.
Added#
Lots of changes, refactoring and code cleanup of
pyflp
.New docs.
Changes to
README
.Adopted ``black` <https://github.com/psf/black>`_ coding style.
Added a
log_level
argument toParser
.Project.create_zip
copies stock samples as well now.Project.get_events
for getting just the events; they are not parsed. Read docs for more info about this.Event
classes now have an__eq__
and__repr__
method.
Fixed#
Tests don’t give module import errors.
Pattern
event parsing.Initialise
_count
to 0, everytimeParser
is initialised.Project.create_zip
now works as intended.Overhauled logging.
A lot of potential bugs in
FLObject
subclasses.
Known issues#
flpinfo
doesn’t output correctly sometimes due to long strings.Extraneous data dumped sometimes by
InsertSlotEvent.Plugin
, why this is caused is not known.