Originally, the only (non-debug) way to make an LFO calculate its value
was to associate it with a playing synthesizer.
This posed a problem for LFOs that had "power on values" other than 0,
and where the value was used other than to internally drive a note
property.
Now, an initial, possibly non-zero value is calculated at object
construction time:
```py
>>> l = synthio.LFO(offset = 1)
>>> l.value
1.0
```
Note that this happens just once at construction; it does not happen when
updating LFO properties:
```py
>>> l.offset = 2
>>> l.value
1.0
```
This can perform arbitrary channel mixing between two images.
Alpha blend & maximum functions are demonstrated in the test.
However, it should make most of the usual photo editing blends
possible. (for dissolve, fill a mask bitmap with random values,
which may be expensive to do from circuitpython code; we can
specifically accelerate it if we need to)
The get, set and del item methods didn't correctly lookup the value
from the parent native instance because the functions took the type
from the instance.
Fixes#8758
morph9 is a form of morph which performs 9 different convolutions,
like a version of mix where each coefficient is a (2n+1)x(2n+1) matrix.
Most use cases are covered by morph-then-mix, but some advanced operations
may be more efficient to implement via morph9.
This allows operations between channels in an image. It can be used for
the following use cases:
* Conversion to B&W or sepia
* Adding color casts
* Mixing or swapping arbitrary channels
* Inverting or scaling arbitrary channels
bitmapfilter.morph is taken from openmv's imlib.
It is substantially faster than blur/sharpen implemented in ulab,
by up to 10x. It also avoids making many allocations.
This function in standard Python is a building block for custom REPLs:
```python
from codeop import compile_command
print("Repl in (Circuit-)Python")
ns = {}
PS1="<<< "
PS2=",,, "
command = ""
while True:
line = input(PS2 if command else PS1)
if command:
command = command + "\n" + line
else:
command = line
try:
if (code := compile_command(command)):
command = ""
exec(code, ns)
except Exception as e:
command = ""
print(e)
```