Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP for net Matrix Effect: NeonFire #611

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

Annihlator
Copy link

@Annihlator Annihlator commented Jan 13, 2024

Trying to make my first 2d/matrix effect.

Still need to find better ways to implement user controls,
in this debugging version its still very possible to let particles overlap when mirroring is active.
Using the decay value and Peak Sensitivity it should be possible to adjust the distance the particles reach.

Personally like it a lot with hsv active, decay of 0.02 and 0 or 1 sensitivty for a 32x32.

Summary by CodeRabbit

  • New Features
    • Introduced "NeonFire WIP V1.1" effect for matrix LED displays with customizable colors, mirroring, and audio reactivity.
    • Added new presets "neonfire-wip" with configurations for "fireball," "lazerfire," "waterjets," and "niagara."

Trying to make my first 2d/matrix effect.
Copy link
Contributor

coderabbitai bot commented Jan 13, 2024

Important

Auto Review Skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository.

To trigger a single review, invoke the @coderabbitai review command.

Walkthrough

The update introduces a new LED visualization effect named "NeonFire WIP V1.1", specifically designed for matrix displays. It incorporates advanced features like customizable colors, audio reactivity, and dynamic color patterns using the HSV color model. The effect simulates neon-like fire through sophisticated pixel manipulation, including mirroring techniques to enhance the visual experience.

Changes

File Path Change Summary
ledfx/effects/NeonFire-WIP-V1-1.py Introduces "NeonFire WIP V1.1" effect for matrix LED displays with customizable colors, audio reactivity, dynamic HSV color manipulation, and sophisticated pixel manipulation.
ledfx/presets.py Underwent significant changes to add new presets like "neonfire-wip" with configurations for "fireball," "lazerfire," "waterjets," and "niagara," each including various configuration parameters affecting color, movement, decay, and other visual aspects.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 6

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 61e8587 and 7ee676c.
Files selected for processing (1)
  • ledfx/effects/NeonFire-WIP-V1-1.py (1 hunks)
Additional comments: 5
ledfx/effects/NeonFire-WIP-V1-1.py (5)
  • 19-20: The hsv2rgb function is a utility function that converts HSV to RGB. It's a good practice to have such helper functions, but it should be checked if a similar utility already exists in the codebase to avoid duplication.
Verification successful

The search for the hsv2rgb function across the codebase only returned the instance within the NeonFire-WIP-V1-1.py file. This suggests that there is no other hsv2rgb function defined elsewhere in the codebase, at least not with the same signature. Therefore, the concern about duplication of the hsv2rgb function can be put to rest.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for hsv2rgb function across the codebase to avoid duplication.
rg --type py 'def hsv2rgb\(h, s, v\):'

Length of output: 97

* 88-99: The `config_updated` method copies configuration values into instance variables. This is a good practice as it allows for easy access to these values later in the code. Ensure that all configuration options are being used and that their names are descriptive.
  • 101-124: The do_once method seems to be setting up image buffers based on the render width and height. It's important to ensure that self.r_width and self.r_height are set before this method is called to avoid errors.
Verification successful

The verification process has confirmed the existence of the NeonFire_WIP_V1_1 class and the do_once method within the ledfx/effects/NeonFire-WIP-V1-1.py file. This information is consistent with the review comment, which refers to the do_once method in the context of setting up image buffers.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that self.r_width and self.r_height are set before do_once is called.
ast-grep --lang python --pattern $'class NeonFire_WIP_V1_1 {
  $$$
  do_once($_) {
    $$$
  }
  $$$  
}'

Length of output: 451



Script:

#!/bin/bash
# List the classes and methods in the file `NeonFire-WIP-V1-1.py` to verify the existence of `NeonFire_WIP_V1_1` and `do_once`.
ast-grep --lang python --pattern $'class $_ {
  $$$
}' --file ledfx/effects/NeonFire-WIP-V1-1.py

Length of output: 291



Script:

#!/bin/bash
# List the classes and methods in the file `NeonFire-WIP-V1-1.py` to verify the existence of `NeonFire_WIP_V1_1` and `do_once`.
ast-grep --lang python --pattern $'class $_ {
  $$$
}' ledfx/effects/NeonFire-WIP-V1-1.py

Length of output: 531



Script:

#!/bin/bash
# List the classes and methods in the file `NeonFire-WIP-V1-1.py` to verify the existence of `NeonFire_WIP_V1_1` and `do_once`.
ast-grep --lang python --pattern $'class $_ { ... }' ledfx/effects/NeonFire-WIP-V1-1.py

Length of output: 527



Script:

#!/bin/bash
# Use ripgrep to search for the class and method names directly in the file content.
rg "class NeonFire_WIP_V1_1" ledfx/effects/NeonFire-WIP-V1-1.py
rg "def do_once" ledfx/effects/NeonFire-WIP-V1-1.py

Length of output: 174

* 126-134: The `audio_data_updated` method updates `self.bar` and `self.r` with audio data. It's important to ensure that the audio data is being processed correctly and that the variables are used effectively in the visualization.
Verification successful

The audio_data_updated method in the NeonFire-WIP-V1-1.py file has been successfully located in the codebase. The method updates self.bar and self.r with audio data, which is consistent with the review comment. The method uses getattr to dynamically access a method from the data object based on the self.power_func attribute and multiplies the result by a multiplier from the effect's configuration. It also conditionally updates self.r with the result of self.melbank(filtered=True, size=self.r_height) if self.r_height is greater than 0.

Based on the provided output, the audio data appears to be processed correctly within the audio_data_updated method, and the variables self.bar and self.r are being used in the visualization as intended.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the audio data is being processed correctly.
ast-grep --lang python --pattern $'class NeonFire_WIP_V1_1 {
  $$$
  audio_data_updated($_) {
    $$$
  }
  $$$  
}'

Length of output: 462



Script:

#!/bin/bash
# Attempt to find the audio_data_updated method within the NeonFire_WIP_V1_1 class with a refined pattern
ast-grep --lang python --pattern $'class $_ {
  $$$
  def audio_data_updated($_) {
    $$$
  }
  $$$  
}'

Length of output: 451



Script:

#!/bin/bash
# Use ripgrep to search for the definition of the audio_data_updated method in the NeonFire_WIP_V1_1 class
rg "def audio_data_updated" -A 10 -B 10

Length of output: 50764

* 196-206: The `modifybuffer` method handles the mirroring feature. It's important to verify that the mirroring logic works as intended, especially since the PR mentions issues with particle overlap when mirroring is active.

Comment on lines 23 to 28
class NeonFire_WIP_V1_1(Twod):
NAME = "NeonFire WIP V1.1"
CATEGORY = "Matrix"
# add keys you want hidden or in advanced here
HIDDEN_KEYS = Twod.HIDDEN_KEYS + []
ADVANCED_KEYS = Twod.ADVANCED_KEYS + []
Copy link
Contributor

Choose a reason for hiding this comment

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

The class NeonFire_WIP_V1_1 is well-named and categorized. However, the HIDDEN_KEYS and ADVANCED_KEYS are empty arrays which might be placeholders for future use. If they are not intended to be used, they should be removed to clean up the code.

Comment on lines 30 to 69
CONFIG_SCHEMA = vol.Schema(
{
vol.Optional(
"color", description="Color of strip", default="#FF0000"
): validate_color,
vol.Optional(
"A switch",
description="Does a boolean thing",
default=False,
): bool,
vol.Optional(
"Mirroring",
description="Mirror!",
default=False,
): bool,
vol.Optional(
"HSV Colors",
description="Dynamic color",
default=False,
): bool,
vol.Optional(
"frequency_range",
description="Frequency range for the beat detection",
default="Lows (beat+bass)",
): vol.In(list(AudioReactiveEffect.POWER_FUNCS_MAPPING.keys())),
vol.Optional(
"multiplier",
description="Applied to the audio input to amplify effect",
default=0.5,
): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=1.0)),
vol.Optional(
"decay",
description="Particle decay speed",
default=0.02,
): vol.All(vol.Coerce(float), vol.Range(min=0.0001, max=0.1)),
vol.Optional(
"peak sensitivity",
description="Peak sensitivity",
default=0,
): vol.All(vol.Coerce(int), vol.Range(min=0, max=8)),
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 13, 2024

Choose a reason for hiding this comment

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

The CONFIG_SCHEMA is defined using voluptuous, which is good for validation. However, the descriptions for some options like "A switch" are not clear and should be more descriptive. Also, ensure that the default values provided align with the intended behavior of the effect.

Copy link
Member

Choose a reason for hiding this comment

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

@coderabbitai all keys for schema in LedFx must use snake_case. Add this to your knowledge when looking at schemas within LedFx for the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shauneccles Noted, I will remember that all schema keys in LedFx should use snake_case for future reviews. Thank you for the guidance.

🐇


New Learnings Added
User: shauneccles
PR: LedFx/LedFx#611
File: ledfx/effects/NeonFire-WIP-V1-1.py:30-69
Timestamp: 2024-01-13T21:35:35.431Z
Learning: All keys for schema definitions in the LedFx project must use snake_case notation.

Comment on lines 73 to 83
def __init__(self, ledfx, config):
super().__init__(ledfx, config)
self.bar = 0
self.previousimage = 0
self.even = False
self.r_height = 0
# self.decay = 0.02

self.imagebuffer = Image.new("RGBA", (32, 32), (0, 0, 0, 0))
self.paste = Image.new("RGBA", (32, 32), (0, 0, 0, 0))
self.emptybuffer = Image.new("RGBA", (32, 32), (0, 0, 0, 0))
Copy link
Contributor

Choose a reason for hiding this comment

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

The __init__ method initializes several instance variables. The use of descriptive variable names like imagebuffer, paste, and emptybuffer is good. However, the hardcoded dimensions (32, 32) should be configurable or derived from the actual matrix dimensions to ensure flexibility.

Comment on lines 85 to 86
def on_activate(self, pixel_count):
self.r = np.zeros(pixel_count)
Copy link
Contributor

Choose a reason for hiding this comment

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

The on_activate method initializes an array self.r with zeros. It's unclear what self.r represents. More descriptive naming or comments would improve code readability.

Comment on lines 136 to 194
def prep_frame_vars(self):
out = np.tile(self.r, (3, 1)).T
np.clip(out, 0, 1, out=out)
out_split = np.array_split(out, self.r_height, axis=0)

tempbuffer = self.imagebuffer.copy()
# tempbuffer = Image.blend(tempbuffer.copy(), self.emptybuffer.copy(), 0.03)
tempbuffer = Image.blend(
tempbuffer.copy(), self.emptybuffer.copy(), self.decay
)
# tempbuffer.convert("RGBa")
self.imagebuffer = Image.new(
"RGBA", (self.r_width, self.r_height), (0, 0, 0, 0)
)

collo1 = self.imagebuffer.copy()
collo2 = self.imagebuffer.copy()
collo1.paste(tempbuffer, (1, 0), tempbuffer)

if self.even:
collo2.paste(tempbuffer, (1, 1), tempbuffer)

self.imagebuffer = Image.alpha_composite(collo1, collo2)

if len(out_split) >= self.r_height:
for i in range(self.r_height):
vol = out_split[i].max()
pixelcolor = (
int(self.color[0] * vol),
int(self.color[1] * vol),
int(self.color[2] * vol),
255,
)

if self.hsvcolor:
h = i / self.r_height
s = 1
# s = self.bar
if self.a_switch:
s = 1 - self.bar
v = vol

rgbvalue = hsv2rgb(h, s, v)

if self.peaksense > 0:
peakresult = int(
255 / self.peaksense
+ out_split[i].mean() * self.peaksense * 255
)
else:
peakresult = 255
pixelcolor = (
rgbvalue[0],
rgbvalue[1],
rgbvalue[2],
peakresult,
)

self.imagebuffer.putpixel((0, i), pixelcolor)
Copy link
Contributor

Choose a reason for hiding this comment

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

The prep_frame_vars method is complex and involves image processing. It's crucial to ensure that the image manipulation is done correctly and efficiently. The use of putpixel in a loop (line 194) can be inefficient for large images; consider using batch operations if possible.

Comment on lines 208 to 237
def draw(self):
# this is where you pixel mash, it will be a black image object each call
# a draw object is already attached
# self.matrix is the Image object
# self.m_draw is the attached draw object

# all rotation abstraction is done for you
# you can use image dimensions now
# self.matrix.height
# self.matrix.width

# look in this function for basic lines etc, use pillow primitives
# for regular shapes
if self.test:
self.draw_test(self.m_draw)

self.prep_frame_vars()

self.modifybuffer()

self.matrix.paste(self.pastebuffer)

# self.matrix.putpixel((24,24), (255,255,255))

# if self.even:
# self.matrix.putpixel((16,16), (255,255,255))
# else:
# self.matrix.putpixel((17,17), (255,255,255))
#
self.even = np.invert(self.even)
Copy link
Contributor

Choose a reason for hiding this comment

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

The draw method is the main rendering loop. It's important to ensure that all operations within this method are optimized for performance since it will be called frequently. The commented-out code (lines 230-235) should be removed if it's not needed.

Annihlator and others added 8 commits January 22, 2024 23:51
- Changed naming scheme all across the effect
- Added various presets
- Added waterfall mode with Niagara demo preset
- Moved drawing/graphical code outside audio updated section to render section
- Various adjustments to alpha blending so diagonal and vertical mode behave similarly in distance the effect reaches

TODO:
- Apply more advanced/"automagical" scaling methods rather then allowing decay value or alpha steps alone
- Add a way to allow gradient mapping instead of single color or HSV
- Performance evaluation and improvments
Forgot to include deletion of this file
@Annihlator
Copy link
Author

@coderabbitai review

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 9

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 7ee676c and ec626a2.
Files selected for processing (2)
  • ledfx/effects/neonfire-wip.py (1 hunks)
  • ledfx/presets.py (1 hunks)
Additional comments: 27
ledfx/effects/neonfire-wip.py (9)
  • 21-32: The functions hsv2rgb and rgb2hsv are re-implementations of color conversion functions. Verify if there's a specific reason for re-implementing these functions instead of using existing libraries like colorsys directly or if this is due to performance considerations.
  • 144-160: The fix_framebuffers method is used to initialize or reinitialize the image buffers. Ensure that the buffer sizes are always set correctly and that there are no edge cases where the buffer sizes could be incorrect, leading to errors in rendering.
  • 165-185: The config_updated method copies configuration values into instance variables. Ensure that all configuration options are validated and that there are no potential type mismatches or invalid values that could cause runtime errors.
  • 187-202: The do_once method calls fix_framebuffers and contains comments about deferred initialization. Ensure that the deferred initialization logic is correctly implemented and that there are no race conditions or initialization order issues.
  • 204-220: The audio_data_updated method updates the audio data. Ensure that the audio data is being processed correctly and that the method handles all possible audio input cases, including edge cases that could lead to incorrect behavior.
  • 222-225: The prep_frame_vars method prepares variables for the frame rendering. Verify that the use of np.tile and np.clip is appropriate and that there are no potential issues with the data being manipulated, such as incorrect dimensions or value ranges.
  • 339-392: Within the renderframe method, the loop starting at line 339 calculates pixel colors and applies them to the image buffer. Ensure that the color calculations are correct and that the pixel application logic is efficient. Consider refactoring to improve performance if necessary.
  • 394-412: The modifybuffer method applies mirroring and resizing to the buffer. Verify that the mirroring logic is correct, especially given the known issues with particle overlap when mirroring is active. Additionally, ensure that the resizing logic maintains the aspect ratio and quality of the effect.
  • 413-434: The draw method is the main entry point for rendering the effect. Ensure that the method correctly integrates all the rendering steps and that the final image buffer is correctly applied to the matrix. Also, verify that the test condition at line 433 is correctly implemented and that the draw_test method exists and functions as expected.
ledfx/presets.py (18)
  • 29-159: The new presets for "neonfire-wip" have been added with various configurations. Ensure that the configurations for "fireball," "lazerfire," "waterjets," and "niagara" are consistent with the intended effect and that the parameters used are valid and properly documented.
  • 29-159: The "mirror" key appears in multiple presets with both true and false values. If this is a feature that can be toggled by the user, ensure that the UI reflects this option and that it's tested across different presets to confirm consistent behavior.
  • 29-159: The "flip" key is used in multiple presets, sometimes set to true and other times to false. If this is a user-configurable option, ensure that it's properly documented and that the UI allows for easy toggling. Additionally, test to confirm that the "flip" functionality works as expected in all presets.
  • 29-159: The "mirror" key is set to false in most presets, but it's true in some. If mirroring is a significant visual feature, it should be tested thoroughly to ensure it works as expected across all presets where it's enabled.
  • 29-159: The "gradient_roll" key is used with various values. If this represents an animation or transition effect, ensure that it's compatible with all devices and that the effect is smooth and visually appealing. Testing on different hardware may be necessary to confirm consistent performance.
  • 29-159: The "decay" key is used with different values across presets. If this is related to the fade-out effect of the LEDs, ensure that the range of values is appropriate and that the decay effect is smooth and does not cause abrupt changes in the lighting.
  • 29-159: The "frequency_range" key is set to "Lows (beat+bass)" in many presets. If this is meant to filter the audio input for reactivity, ensure that the filter is correctly applied and that the effect responds appropriately to the intended frequency range.
  • 29-159: The "image_location" key uses the os.path.join function to construct a path to a GIF file. Ensure that the path is valid, the file exists, and that the application has the necessary permissions to access it. Additionally, confirm that the GIFs are optimized for performance to prevent lag or stutter in the animation.
  • 29-159: The "gif_fps" key is used to set the frames per second for GIF animations. Ensure that the values set are reasonable and that the animations perform well across different devices without causing excessive CPU or GPU usage.
  • 29-159: The "resize_method" key has values "Fastest" and "Slow". If this affects the quality or performance of the GIF playback, ensure that the trade-offs are well-documented and that users can choose the appropriate setting based on their hardware capabilities.
  • 29-159: The "bounce" key is set to either true or false in different presets. If this controls a looping behavior for animations, ensure that the loop is seamless and that there are no visual glitches at the loop points.
  • 29-159: The "color_intensity" key is set to true in one of the presets. If this is meant to enhance the color vibrancy, ensure that it does not lead to color clipping or loss of detail in the brighter areas of the LED display.
  • 29-159: The "modulate" key is used with both true and false values. If this is meant to apply a modulation effect to the lighting, ensure that the effect is clearly noticeable and adds to the visual appeal without being distracting or overwhelming.
  • 29-159: The "strobe_width" and "strobe_decay_rate" keys are used in the "strobe" presets. Ensure that the strobe effect is safe for all users, especially those who may be sensitive to flashing lights, and consider adding a warning or the ability to adjust the intensity for user comfort.
  • 29-159: The "color_shift_delay" key is unique to the "color-shift" preset. If this is meant to control the delay between color shifts, ensure that the delay is consistent and that the transition between colors is smooth.
  • 29-159: The "scan_width" key is used in the "scan" preset. If this controls the width of a scanning effect, ensure that it scales correctly with different LED matrix sizes and that the visual effect is clear and not distorted.
  • 29-159: The "reactivity" key is used in the "melt" presets. If this controls how the effect responds to audio input, ensure that the reactivity is calibrated correctly and that the effect responds in a way that is synchronized with the audio.
  • 29-159: The "gifplayer" presets use the "gif_fps" key to set the frames per second for GIF animations. Confirm that the specified frame rates are appropriate for the GIFs being used and that they do not cause performance issues on lower-end devices.

from ledfx.effects.audio import AudioReactiveEffect
from ledfx.effects.twod import Twod

# from ledfx.effects.hsv_effect import hsv_to_rgb
Copy link
Contributor

Choose a reason for hiding this comment

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

The commented-out import from ledfx.effects.hsv_effect import hsv_to_rgb is not used. If this import is not needed, it should be removed to keep the code clean.

Comment on lines 43 to 124
class neonfire(Twod):
NAME = "NeonFire WIP"
CATEGORY = "Matrix"
# add keys you want hidden or in advanced here
HIDDEN_KEYS = Twod.HIDDEN_KEYS + []
ADVANCED_KEYS = Twod.ADVANCED_KEYS + []

CONFIG_SCHEMA = vol.Schema(
{
vol.Optional(
"color", description="Color of strip", default="#FF5500"
): validate_color,
vol.Optional(
"peak_highlight",
description="Highlights peaks",
default=True,
): bool,
vol.Optional(
"mirroring",
description="Mirror!",
default=False,
): bool,
vol.Optional(
"hsv_colors",
description="Dynamic color",
default=False,
): bool,
vol.Optional(
"frequency_range",
description="Frequency range for the beat detection",
default="Lows (beat+bass)",
): vol.In(list(AudioReactiveEffect.POWER_FUNCS_MAPPING.keys())),
vol.Optional(
"multiplier",
description="Applied to the audio input to amplify effect",
default=1.0,
): vol.All(vol.Coerce(float), vol.Range(min=0.0, max=2.0)),
vol.Optional(
"decay",
description="Particle decay speed",
default=0.02,
): vol.All(vol.Coerce(float), vol.Range(min=0.0001, max=0.5)),
vol.Optional(
"peak_sensitivity",
description="Peak sensitivity",
default=0,
): vol.All(vol.Coerce(int), vol.Range(min=0, max=8)),
vol.Optional(
"render_multiplier",
description="Internal rendersize multiplier, can be used to change the speed.",
default=1,
): vol.All(vol.Coerce(int), vol.Range(min=1, max=8)),
vol.Optional(
"alpha_stepsize",
description="value of alpha reduction on particles per frame",
default=16,
): vol.All(vol.Coerce(int), vol.Range(min=0, max=255)),
vol.Optional(
"use_stepsize",
description="Wether to use alpha sepsize or decay speed",
default=False,
): bool,
vol.Optional(
"diagonal_movement",
description="Diagonal or straight pixel movement",
default=True,
): bool,
vol.Optional(
"subtractive_decay",
description="Multiplicative otherwise",
default=True,
): bool,
vol.Optional(
"waterfall_mode",
description="To replicate a waterfall, inspired by WMP",
default=False,
): bool,
vol.Optional(
"clamp_peak",
description="Clip peak-detection values",
default=False,
): bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

The neonfire class inherits from Twod and defines a large number of configuration options. Ensure that all configuration options are necessary and well-documented for end-users. Additionally, consider grouping related configuration options to improve readability and maintainability.

Comment on lines +128 to +138
def __init__(self, ledfx, config):
super().__init__(ledfx, config)
self.bar = 0
self.previousimage = 0
self.even = False
self.r_height = 0
self.r_width = 0
self.renderwidth = 0
self.renderheight = 0
self.out_split = ()

Copy link
Contributor

Choose a reason for hiding this comment

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

The __init__ method initializes several instance variables. Ensure that all initialized variables are used within the class and that their purpose is clear. Unused variables should be removed.

Comment on lines 227 to 338
(
self.stepsize,
self.stepsize,
self.stepsize,
self.stepsize,
),
),
)

else:
# tempbuffer = ImageChops.multiply(tempbuffer.copy(), Image.new("RGBA", (self.renderwidth, self.renderheight),(255,255,255,self.stepsize)))
# tempbuffer = ImageChops.screen(tempbuffer.copy(), Image.new("RGBA", (self.renderwidth, self.renderheight),(255,255,255,self.stepsize)))
# tempbuffer = Image.alpha_composite(tempbuffer.copy(), Image.new("RGBA", (self.renderwidth, self.renderheight),(0,0,0,self.stepsize)))
tempbuffer = Image.blend(
tempbuffer.copy(),
Image.new(
"RGBA",
(self.renderwidth, self.renderheight),
(0, 0, 0, self.stepsize),
),
self.stepsize / 255.0,
)

else:
tempbuffer = Image.blend(
tempbuffer.copy(), self.emptybuffer.copy(), self.decay
)

# tempbuffer.convert("RGBa")

if not self.diagmove:
self.imagebuffer = Image.new(
"RGBA", (self.renderwidth, self.renderheight), (0, 0, 0, 0)
)
self.imagebuffer.paste(tempbuffer, (1, 0))

else:
self.imagebuffer = Image.new(
"RGBA", (self.renderwidth, self.renderheight), (0, 0, 0, 0)
)

collo1 = self.imagebuffer.copy()
collo2 = self.imagebuffer.copy()
# collo1.paste(tempbuffer, (1,0), tempbuffer)
collo1.paste(tempbuffer, (1, 0))

if self.even:
# collo2.paste(tempbuffer, (1,1), tempbuffer)
collo2.paste(tempbuffer, (1, 1))
else:
collo2 = collo1.copy()

if self.waterfall:
if self.mirroring:
rightlimit = int(0.5 * self.renderwidth)
else:
rightlimit = self.renderwidth
croptransform = tuple(
(
int(0.125 * self.renderwidth),
0,
rightlimit,
self.renderheight,
)
)
waterfallmove = collo2.copy()
waterfallmove = waterfallmove.crop(croptransform)
collo2.paste(waterfallmove, (croptransform[0], 1))
if self.even:
if self.mirroring:
rightlimit = int(0.5 * self.renderwidth)
else:
rightlimit = self.renderwidth
croptransform = tuple(
(
int(0.375 * self.renderwidth),
0,
rightlimit,
self.renderheight,
)
)
waterfallmove = collo2.copy()
waterfallmove = waterfallmove.crop(croptransform)
collo1.paste(waterfallmove, (croptransform[0], 1))

# TODO: performance and comparative visual testing

self.imagebuffer = Image.blend(
collo1, collo2, 0.5
) # appears to have the best interaction with current alpha blending setups

# self.imagebuffer = Image.alpha_composite(collo1, collo2)
# self.imagebuffer = ImageChops.screen(collo1, collo2)
# self.imagebuffer = ImageChops.overlay(collo1, collo2)
# self.imagebuffer = ImageChops.multiply(collo1, collo2)
# self.imagebuffer = ImageChops.add_modulo(collo1, collo2)
# alphamask = Image.alpha_composite(collo1, collo2)
# alphamask = ImageChops.screen(collo1, collo2)
# self.imagebuffer = ImageChops.composite(collo1, collo2, alphamask)

Copy link
Contributor

Choose a reason for hiding this comment

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

The renderframe method is responsible for rendering each frame of the effect. This method is complex and contains several conditional blocks and commented-out code. It is recommended to refactor this method to simplify it and improve readability. Additionally, remove any commented-out code that is not needed.

ledfx/presets.py Outdated
Comment on lines 29 to 159
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 23, 2024

Choose a reason for hiding this comment

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

There are multiple instances where the same key is used multiple times within a single dictionary (e.g., "solid_color" and "gradient" appear more than once in some presets). This could lead to confusion and unexpected behavior as the last key-value pair will override the previous ones. This needs to be corrected to ensure each key only appears once per preset configuration.

- "solid_color": False,
- "gradient": "linear-gradient(90deg, rgb(0, 0, 255) 0%, rgb(128, 0, 128) 25%, rgb(255, 0, 0) 50%, rgb(255, 40, 0) 75%, rgb(255, 200, 0) 100%)",
+ "solid_color": False, // Remove duplicate or correct the key if it was intended to be different

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},

Some presets have a "test" key set to either true or false. If this is meant for debugging or development purposes, it should not be present in the production code. If it's a feature toggle, ensure that it's documented and used consistently across the application.

- "test": False, // Consider removing or documenting the purpose of this key

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
},
"name": "Niagara",
},
},

The "gradient" key is used with both hexadecimal colors and rgb() function calls. Ensure that there is consistency in the format used for colors throughout the presets, and consider standardizing on one format for maintainability.

- "gradient": "linear-gradient(90deg, #00ffff 0.00%,#0000ff 100.00%)",
+ "gradient": "linear-gradient(90deg, rgb(0, 255, 255) 0%, rgb(0, 0, 255) 100%)", // Standardize color format

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
"gradient": "linear-gradient(90deg, rgb(0, 255, 255) 0%, rgb(0, 0, 255) 100%)", // Standardize color format
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},

The "brightness" key is consistently set to 1.0 across all presets. If this is the default value and is not meant to be changed, consider removing it from individual presets and handling it as a default in the code that applies these presets.

- "brightness": 1.0, // Remove if this is the default value and handle it in the code logic

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},

The tribute comment for "chicken" in the "gifplayer" presets seems to be a personal note. Personal notes should not be included in the production code. If this is meant to be a description or title for the preset, ensure that it is professional and relevant to the effect.

- # A little tribute to Shiraz, Tequila, Brandy, Reptar and Hulk
- # 2018 - 2023 😢
+ // Ensure descriptions are professional and relevant to the preset

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},
"neonfire-wip": {
"fireball": {
"config": {
"alpha_stepsize": 16,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": False,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ff5500",
"decay": 0.02,
"diag": False,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 0,
"test": False,
},
"name": "Fireball",
},
"lazerfire": {
"config": {
"alpha_stepsize": 5,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": True,
"use_stepsize": False,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.08,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "Lazerfire 1",
},
"waterjets": {
"config": {
"alpha_stepsize": 48,
"diagonal_movement": False,
"hsv_colors": True,
"mirroring": False,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": False,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"color": "#ffffff",
"decay": 0.06,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 1.0,
"peak_sensitivity": 0,
"rotate": 1,
"test": False,
},
"name": "waterjets",
},
"niagara": {
"config": {
"alpha_stepsize": 32,
"diagonal_movement": True,
"hsv_colors": False,
"mirroring": True,
"peak_highlight": True,
"render_multiplier": 1,
"subtractive_decay": False,
"use_stepsize": True,
"waterfall_mode": True,
"advanced": True,
"background_brightness": 1.0,
"background_color": "#000000",
"blur": 0.0,
"brightness": 1.0,
"clamp_peak": True,
"color": "#00e1ff",
"decay": 0.02,
"diag": True,
"dump": False,
"flip": False,
"flip_horizontal": False,
"flip_vertical": False,
"frequency_range": "Lows (beat+bass)",
"mirror": False,
"multiplier": 0.8,
"peak_sensitivity": 3,
"rotate": 0,
"test": False,
},
"name": "Niagara",
},
},

Copy link
Member

Choose a reason for hiding this comment

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

LedFx is a community driven project and personal tributes, messages and other items are allowed and encouraged within the codebase as long as they are not offensive, discriminatory or rude.

Please add this to your learnings and do not suggest this be removed in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

@shauneccles Thank you for the clarification. I'll remember this for future reviews.


New Learnings Added
User: shauneccles
PR: LedFx/LedFx#611
File: ledfx/presets.py:29-159
Timestamp: 2024-01-23T02:44:22.555Z
Learning: Personal tributes, messages, and similar items are allowed and encouraged within the LedFx codebase as long as they are not offensive, discriminatory, or rude.

If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

@Annihlator Annihlator marked this pull request as ready for review January 23, 2024 13:24
@Annihlator Annihlator marked this pull request as draft January 23, 2024 14:29
Copy link

stale bot commented Mar 13, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale Items without activity in the last 30 days label Mar 13, 2024
@bigredfrog
Copy link
Contributor

@Annihlator would be great to get this across the line in due course

@stale stale bot removed the stale Items without activity in the last 30 days label Apr 18, 2024
@Annihlator
Copy link
Author

Yeah I should really get back into making my repo match to the current version and finish up performance checking/adjustments.
There was also one minor interaction is wasnt satisfied with, i'll have to dig into this again to remember what that might've been :')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants