Skip to content

✨ Fruity Blood Overdrive parser#63

Closed
ttaschke wants to merge 3 commits intodemberto:masterfrom
ttaschke:add-plugin-blood-overdrive
Closed

✨ Fruity Blood Overdrive parser#63
ttaschke wants to merge 3 commits intodemberto:masterfrom
ttaschke:add-plugin-blood-overdrive

Conversation

@ttaschke
Copy link
Contributor

Draft for blood overdrive parsing with support for just the new version of the plugin

"I",
)


Copy link
Contributor Author

@ttaschke ttaschke Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To support both the recent and the old version of BloodOverdrive two Structs would be used here.

class _FruityBloodOverdriveStruct(StructBase)
->
class _FruityBloodOverdriveNewStruct(StructBase)

class _FruityBloodOverdriveOldStruct(StructBase):
    PROPS = dict.fromkeys(
        (
            ...
            "pre_band",
            "color",
            "pre_amp",
            "x100",
            "post_filter",
            "post_gain",
            ...
        ),
        "I",
    )

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't think about how big the names would get, use _FruityBloodOverdriveStruct2 probably?

class FruityBloodOverdriveEvent(StructEventBase):
STRUCT = _FruityBloodOverdriveStruct


Copy link
Contributor Author

@ttaschke ttaschke Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BO event would set both versions of the struct, so NativePluginEvent can use the one it decides to be appropriate.

class FruityBloodOverdriveEvent(NativePluginEvent):
    struct_old = _FruityBloodOverdriveOldStruct
    struct_new = _FruityBloodOverdriveNewStruct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NativePluginEvent would look at the events stream and decide which plugin version it encountered.

class NativePluginEvent(StructEventBase)

    # check the version of the plugin based on stream size and/or plugin marker in the first 4 bytes?
   
    # set the appropriate struct

Copy link
Owner

@demberto demberto Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to consider whether I should just modify existing StructEventBase logic to accomodate multiple structs, since its very possible that the functionality NativePluginEvent might be used by other events

@ttaschke ttaschke marked this pull request as draft September 27, 2022 11:35
@demberto demberto changed the title [WIP] feat: add blood overdrive plugin parser [WIP] feat: fruity blood overdrive Sep 27, 2022
Copy link
Owner

@demberto demberto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for you to use FL Studio 20.8.4.2304, for modifying the test FLP? If not maybe I can add the FBO myself in a commit to this PR.

Nice work, thanks :))


INTERNAL_NAME = "Fruity Blood Overdrive"

plugin_marker = _PluginDataProp[int]() # 3
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to expose an internal parameter in the public interface.

I think this can be better exposed via a normal boolean is_old property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my workaround to get it to work with StructEventBase.
The proper way would probably be to read the first 4 bytes self._stream.read_I() and then set is_old in NativePluginEvent?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe, it can be added as a property in _PluginBase itself

pyflp/plugin.py Outdated
| Default | 10000 | 0.0000 |
"""

unknown_event_first = _PluginDataProp[int]()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as a above for both unknown events

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed in 6b9e167

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I meant to say, remove them

class FruityBloodOverdriveEvent(StructEventBase):
STRUCT = _FruityBloodOverdriveStruct


Copy link
Owner

@demberto demberto Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to consider whether I should just modify existing StructEventBase logic to accomodate multiple structs, since its very possible that the functionality NativePluginEvent might be used by other events

"I",
)


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't think about how big the names would get, use _FruityBloodOverdriveStruct2 probably?

@demberto demberto added the enhancement New feature or request label Sep 27, 2022
@demberto demberto added this to the PyFLP 2.0.0 milestone Sep 27, 2022
@ttaschke ttaschke force-pushed the add-plugin-blood-overdrive branch from 978554c to 6b9e167 Compare September 27, 2022 12:43
@ttaschke
Copy link
Contributor Author

ttaschke commented Sep 27, 2022

@demberto
Thanks for the review.

I am still unsure whether this should first be released using StructEventBase to support the new Blood Overdrive version only or a complete implementation of NativePluginEvent supporting both versions.
The latter seems to become a bigger refactoring project including modifying StructEventBase and potentially writing NativePluginEvent with support for other events in mind, as you mentioned in #63 (comment).
Just an implementation for the new versions seems more doable given my current grasp of the pyflp API and so on.

Properties

#63 (comment)
#63 (comment)
-> How would plugin_marker, _u1 and _u2 be parsed if not set as a PluginDataProp in class FruityBloodOverdrive?
This probably depends on above-mentioned choice, as this would be handled in NativePluginEvent instead (See: #63 (comment))

Test FLP

Is it possible for you to use FL Studio 20.8.4.2304, for modifying the test FLP? If not maybe I can add the FBO myself in a commit to this PR.

Unfortunately, some project-related properties are changed when saving the same file in another FL Studio breaking existing tests.
Sorry for the inconvenience, but yes it would be great, if you could add Blood Overdrive to the test FLP 🙏
Here is a reference for how I had it set up: #42 (reply in thread)

@demberto
Copy link
Owner

demberto commented Sep 28, 2022

How would plugin_marker, _u1 and _u2 be parsed if not set as a PluginDataProp in class FruityBloodOverdrive?

Structs of some other plugins have a unused / unknown data. StructEventBase will populate its _props dictionary, as it is instantiated. This means, the event already has the property values inside it, and the model just provides a public interface to the known / useful values. The _PluginDataProp just reads from the StructEventBase._props.

This was a conscious design decision of PyFLP 2.0 to provide as informative events as I can in case they are displayed in a tool like FLPEdit, or if the model parsing logic fails due to haphazard event ordering or their absence, these would be a good fallback.

Unfortunately, some project-related properties are changed when saving the same file in another FL Studio breaking existing tests.

Yea. I completely forgot that the licensee name will change if you just save the FLP. To solve this issue, I have create a test-asset-isolation branch to explore the solutions in #6.

Native plugins have FST files in FL Studio's plugin database. I am refactoring the tests to use this new layout, while the full FLP will just be used for project settings, and a few other things which cannot be exported to presets.

I am still unsure whether this should first be released using StructEventBase to support the new Blood Overdrive version only or a complete implementation of NativePluginEvent supporting both versions.
The latter seems to become a bigger refactoring project including modifying StructEventBase and potentially writing NativePluginEvent with support for other events in mind

If NativePluginEvent is created it will mean this multiple struct parsing logic will be limited to subclasses of NativePluginEvent.

If instead, just the existing StructEventBase is modified to accept multiple possible struct layouts and its implementation modified to choose one based on the size of the stream, it can be use anywhere else. I think we should be going with this option.

@demberto
Copy link
Owner

@ttaschke I have reworked most of the unit tests to use presets, including plugins, it should be very easy to add a blood overdrive preset and test it.

@ttaschke
Copy link
Contributor Author

@demberto
Awesome. Thanks!
I will try this out and then give the StructEventBase changes a go.

@ttaschke
Copy link
Contributor Author

@demberto
Hi, I just wanted to check in and see if all the things we discussed before (testing, construct / struct changes) can now be considered stable, so that I can modify this PR accordingly?

@demberto
Copy link
Owner

@ttaschke Yes. Infact you don't need to have 2 different structs at all, you can cover all parsing logic by the classes provided in construct.

@demberto demberto changed the title [WIP] feat: fruity blood overdrive feat: Fruity Blood Overdrive Oct 17, 2022
@demberto demberto changed the title feat: Fruity Blood Overdrive feat: Fruity Blood Overdrive parser Oct 17, 2022
@demberto demberto changed the title feat: Fruity Blood Overdrive parser ✨ Fruity Blood Overdrive parser Oct 19, 2022
@demberto
Copy link
Owner

Hey @ttaschke long time no talks. What do you plan to do with this PR?

@ttaschke
Copy link
Contributor Author

@demberto
Sorry, this got lost in my backlog somehow.

I just started changing the code in this PR to use construct and added a separate .fst for testing. Given how much changed in PyFLP since opening this PR, I think it will be cleanest to open a new PR for a fresh branch (https://github.com/demberto/PyFLP/compare/master...ttaschke:PyFLP:add-plugin-parser-blood-overdrive?expand=1).

@demberto
Copy link
Owner

demberto commented Dec 29, 2022

@ttaschke I am actually considering restructuring the modules into more submodules. pyflp.channel is my prime candidate but pyflp.plugin packs too much into a single module as well. I will be creating a different branch for it however. It will require quite some changes to the docs as well. Currently, the situation is so bad, I need to literally search for a class with Ctrl + F all the time

@ttaschke ttaschke closed this Feb 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants