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
Implement pixel buffer for accurate getPixelColor() #820
Comments
Hi, |
What we are trying to achieve? Moving pixels down the strip. Basically ‘inject’ a specific pixel of specific color are brightness and then with time move that pixel. (Similar to what ‘fire’ does)
… On Apr 1, 2020, at 5:39 PM, Aircoookie ***@***.***> wrote:
Hi,
unfortunately this is a side effect of using NeoPixelBrightnessBus without an extra buffer. The color is scaled for brightness adjustment. getPixelColor() can then not perfectly reconstruct the set color. We have no other options though, as the extra buffer would cost too much memory.
What would you like to implement? There may be a solution without relying on getPixelColor()
—
You are receiving this because you authored the thread.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKF3O7SWY2FBE4FWWKTRKO7DVANCNFSM4LZRBWLQ).
|
I just added a sound/noise reactive fire routine as sound 11. This could be used for the 8266 as well, since I am not using any FFT functions here, only one of the fft sliders.
Updated and pushed
… On Apr 1, 2020, at 5:39 PM, Aircoookie ***@***.***> wrote:
Hi,
unfortunately this is a side effect of using NeoPixelBrightnessBus without an extra buffer. The color is scaled for brightness adjustment. getPixelColor() can then not perfectly reconstruct the set color. We have no other options though, as the extra buffer would cost too much memory.
What would you like to implement? There may be a solution without relying on getPixelColor()
—
You are receiving this because you authored the thread.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKF3O7SWY2FBE4FWWKTRKO7DVANCNFSM4LZRBWLQ).
|
@apleschu how does the ESP8266 get input for sound/noise? Do you have a github link to the pushed source? |
@huggy-d1 Yes, we have a published source. Currently waiting if aircookie wants to merge or if we have to continue to maintain our own branch. The public code is at: https://github.com/atuline/WLED Please note that 8266 is limited to simple audio functions. In order to run more comples audio functions (FFT) we need an ESP32 so that we have the second core to run the FFT without slowing down WLED. |
Ok, in that case our best bet is probably using |
@aircookie do you mean SEGENV.data? |
I looked into that before. I may still be a little bit in a bind here, I need storage that survives between the executions of the audio routine. Fire does not seem to do that. SEGMENT.allocate() could work if I am able to allocate the storage area outside the audio function where I can determine whether the function is audio or not. Thus far I was unable to find line/switch statement where the jump off point into the effects is.
Anybody able to point me to that?
… On Apr 2, 2020, at 6:10 PM, Aircoookie ***@***.***> wrote:
Ok, in that case our best bet is probably using segment.data, a dynamically allocated auxiliary array. You can have a look at the Fire2012 method to see how it is used :)
—
You are receiving this because you were mentioned.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKAIUCSU3EKHJF3KYRDRKULQDANCNFSM4LZRBWLQ).
|
Hmm, I'll have to look into that SEGENV.data method for moving values instead of getPixelColor(). In the meantime, I wrote a little helper routine that will set pixel colours based on the the palette, but if the SEGMENT.palette == 0, then set it based on a SEGCOLOR(0) scaled down (err, blended with black) with a volume level. That way, I can also support the 'w' channel. |
SEGMENT.data unfortunately is not a solution to the problem that setColor(getColor()) changes the color of the pixel more and more to the red.
SEGMENT.data as I understand it is a pointer to data that you can allocate. And in allocating the memory storage is memset to 0. The problems in this approach is in order to reliably move contact from one pixel to the next we need to be able to access the underlying data structures and be able to manipulate the color values.
Is there any other chance to get access to the underlying LED structures, similar to leds[I] with FastLED?
… On Apr 5, 2020, at 1:57 PM, Andrew Tuline ***@***.***> wrote:
Hmm, I'll have to look into that SEGENV.data method for moving values instead of getPixelColor().
In the meantime, I wrote a little helper routine that will set pixel colours based on the the palette, but if the SEGMENT.palette == 0, then set it based on a SEGCOLOR(0) scaled down (err, blended with black) with a volume level. That way, I can also support the 'w' channel.
—
You are receiving this because you were mentioned.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKHFFQNMDFGQOEDQYPDRLDIA7ANCNFSM4LZRBWLQ).
|
@apleschu There is,
uint16_t WS2812FX::mode_soundstream()
{
uint16_t dataSize = 4 * SEGLEN;
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
uint32_t* colors = reinterpret_cast<uint32_t*>(SEGENV.data);
//...
for (int i = SEGLEN - 1; i > SEGLEN/2; i--) {
oldColor = colors[i-1];
setPixelColor(i, color);
colors[i] = color; Hope this helps! (although if you are working with palettes it would be better to just save the palette index (and brightness if needed) and call the palette function again rather than storing the entire color, it halves the amount of required data memory allocation, and the more is allocated, the more likely stability issues may arise) Thank you for the awesome work! I just received my MAX9814 today and will try out your code tomorrow. |
Thank you! I am fighting with my computer right now that has decided to develop problem while we are under stay at home, so I had to order a new one. It might be a week before I get to test that
I was under the impression that SEGENV.allocateData(dataSize) also does a memset(0), which would clear the array every time before the audio function is called.
… On Apr 5, 2020, at 4:57 PM, Aircoookie ***@***.***> wrote:
***@***.***(https://github.com/apleschu) There is, bus->GetPixels(), but it doesn't help since the underlying LED structures already contain the values scaled to brightness (you will notice that the color degration issue doesn't happen with the max. brightness 255) and there is just no way to get the color originally used in setPixelColor() losslessly without an extra buffer.
SEGENV.data can act as exactly such a buffer without consuming the memory on other effects that don't need it. You allocate the memory you need (maximum of 2048 bytes on 8266, quadruple that on ESP32) and you can cast it to any data structure you like. 1D fireworks for example, uses a Spark object to store light particles. For colors, you could do something like this:
uint16_t
WS2812FX::mode_soundstream
()
{
uint16_t
dataSize =
4
* SEGLEN;
if
(!SEGENV.
allocateData
(dataSize))
return
mode_static
();
//
allocation failed
uint32_t
* colors =
reinterpret_cast
<
uint32_t
*>(SEGENV.
data
);
//
...
for
(
int
i = SEGLEN -
1
; i > SEGLEN/
2
; i--) {
oldColor = colors[i-
1
];
setPixelColor
(i, color);
colors[i] = color;
Hope this helps! (although if you are working with palettes it would be better to just save the palette index (and brightness if needed) and call the palette function again rather than storing the entire color, it halves the amount of required data memory allocation, and the more is allocated, the more likely stability issues may arise)
Thank you for the awesome work! I just received my MAX9814 today and will try out your code tomorrow.
—
You are receiving this because you were mentioned.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKDQBWJPIV7IJX5Y2LLRLD5E7ANCNFSM4LZRBWLQ).
|
Oh, that sucks! Hope you'll have a working setup soon and maybe even get your PC to work again. Also stay healthy!
|
Ah, perfect! That helps in my thought process, because I was asking myself how I can use that if it’s initialized every time. I’ll give that a try if you do t beat me to it.
Andreas Pleschutznig
719-992-4125
…On Sun, Apr 5, 2020 at 6:38 PM, Aircoookie ***@***.***> wrote:
Oh, that sucks! Hope you'll have a working setup soon and maybe even get your PC to work again. Also stay healthy!
SEGENV.allocateData(dataSize) does do a memset(0), but only if the supplied dataSize (should stay the same unless segment parameters like SEGLEN change) or the effect mode itself changes. So it is good for storing general purpose data between function calls of the currently running effect :)
—
You are receiving this because you were mentioned.
Reply to this email directly, [view it on GitHub](#820 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AA7TGKDGXZX7AKT2DHV3CZDRLEI6BANCNFSM4LZRBWLQ).
|
Changing this bug report to a feature request for fixing the underlying problem. |
Implemented in 0.14. |
The following code moves the pixels down the line, but as it gets to the end it also gets more and more red, even though there is nothing in the code that should do that.
SOMETHING in the getPixelColor/SetPixelColor is not 100% transparent.
for (int i = SEGLEN - 1; i > SEGLEN/2; i--) { // Move to the right.
setPixelColor(i,getPixelColor(i-1));
}
The text was updated successfully, but these errors were encountered: