Welcome to the CircuitPython Show. I'm your host, Paul Cutler.
This episode, I'm joined by Cooper Dalrymple, Jeff Epler, Mark Komus,
and Tod Kurt for a panel discussion on the new audio effects recently added to CircuitPython.
Welcome, everyone, to the show!
Hello! Hey, Paul.
Mark, back in September, you proposed adding audio effects to CircuitPython.
What inspired you to add the audio effects?
something on my mind for quite a while after the initial synthio release that Jeff had put out,
when I was trying to add drum effects in. And I found YouTube was a really good source of
seeing how other people use synths to make drum effects, other types of synth effects, pianos,
keyboards, basses, whatever.
But where I hit a stumbling block for most of them was that I couldn't add
things like reverb.
The filters were in and they work great, but like reverb, little echoes, little
things that would make it sound better.
So it was in the back of my head to do something with that.
And then I just had some time, was looking for something to work on.
So eventually that's how I ended up starting on it.
A little bit of a big thing to bite off, but you've been kind of working up to it, I think, over time with CircuitPython.
Yeah, I first started doing audio stuff with Audio Mixer, I believe, and bringing that to the RP2040 at the time.
Something else with Raspberry Pi, but I can't remember what it was for audio now.
I have a quick question for you, Mark.
You mentioned the drum sounds using synthio, generating those.
Did you put out a gist for that about a year or two ago?
- Yes I did.
- I think I might have copied some of that.
Stole your homework.
- Yeah, yeah, everyone has been using that.
- Yeah, yeah, you were like mixing three different voices
I think, the decays, it was really good.
- I found it in many different people's projects
and they're like, hey look, I made a little
CircuitPython drum machine and I'm like, hmm,
there's no samples here, how is he doing it?
- Yeah, I think I credit it to my,
I think I credit it in the source code.
But still, that was incredible.
That's really awesome to hear because that's what I was hoping with anything I
put out. And I've seen a couple of projects that had drum effects that I was
like, wait, that sounds like what I made, but I've never looked into it further
than that.
Wow.
I've seen that commonly on like older, older systems.
The sound of one voice is just kind of not as exciting as you'd like it to be.
And so you double up or triple up voices.
And I have to give credit to TodBot for that.
You were mixing multiple voices and detuning them slightly
to get a cooler sound.
And then when I started doing the drum effects,
I was like, hey, wait, that can work for this as well.
I can mix two or three or four voices
to get something that sounds more noise-like and not
a sine wave from synth-like.
Yeah.
When you made that, did you look at, I don't know,
like a TR-808 or something, some other analog drum machine
to see how they did it to build that sound?
Or were you just kind of playing it off?
I googled a bunch of YouTube videos of various people
making drum sounds on synths.
I can't even remember what videos they were at this point.
And then had to adapt them for CircuitPython.
As I said, we didn't really have audio effects at the time
outside of basic filters and then multiple samples
at the same time.
So it ended up being sort of a hybrid of what I saw online
and what I was able to play with myself.
Yeah, adding adding the the delays, you mentioned having like voice detuning,
like having multiple voices where they're where they're detuned to make a fatter,
you know, more interesting sound.
But like you can get the same effect in a lot of ways
just by using a delay at much lower CPU cost.
And so for like if you're playing a chord, say.
And so I'm so happy that we have this audio effects and audio delays
packages now because it's kind of cruise control for cool.
You can make almost any sound sound a little bit better when you add a little bit of delay to it.
That's interesting.
For those that might not be aware of the new audio effects, what are some example effects that are now available in CircuitPython?
The first one I put in was an echo, which is really a delay.
I put it in because I didn't know what else to do to make sure things were working.
I don't have the knowledge that everyone else on this panel does about synths and musical knowledge.
But it's something that you can quickly and easily test.
I can play a note, I can wait half a second
and see if I've heard the note back to myself again.
So it became really good for debugging and troubleshooting
and learning to pick something simple where you're not
trying to troubleshoot your effect on top of figuring out
how to do effects to start with.
Yeah, I think I can touch on that a little bit as well,
if that's OK.
First of all, I'm the new kid on the block here.
I've only been contributing for about half a year or more
to CircuitPython.
Name's Cooper, I guess.
And I come from a musical background,
and a lot of guitar, piano, stuff like that.
And I think what a good place to base this selection of effects
that we eventually choose is in guitar effects.
I'm sure many of the listeners here
are familiar to some degree with effects pedals for guitars,
which are ubiquitous nowadays with guitar players
since the '60s with Jimi Hendrix and all that,
fuzzes, etc. I think some of our selection, it may be a little bit more utilitarian in
usage but kind of takes some of its, I guess, DNA from guitar pedals. So, the other effects
that we've developed beyond delay, which was a great start, of course, to set this up,
the whole pathway and how these effects are made. Since then, we have filter, I believe,
which is in a different module, audio filters.
And then recently just got merged is distortion,
which actually covers a couple of bases.
I think that filter one especially,
it's probably the easiest one.
I think it was easier than the echo effect to create
because it was using the biquad system
that you developed, Jeff, with synthio
and then hence the block biquad system, which is super cool.
But with that, you can build a multitude of effects,
things like wahs, EQs, just basic filters, low pass,
and stuff like that.
Yeah, totally.
Because one of the things that--
I don't know who it was that set up the initial audio
system for CircuitPython, but it kind of
was informed by how pedals work, and that they have
got an input and an output.
And if you want to hook things together,
you just hook the output of one to the input of the other,
and you keep going.
And that's how all the new audio delays and audio effects
have been set up as well.
So you can just start plugging things up
and see what they do.
And every module or every function has these knobs.
And Jumper made these cool LFO automated knob turning
functions that you can just plug into the various knobs
of the filter and the delay and all that kind of stuff.
So you can do the wahs and distortions and dynamic stuff.
It's really fun.
- Yeah, I mean, when I was creating synthio,
I did a lot of reading about synths.
I'm more of a music enjoyer.
I'm a little bit of a vocal musician,
but I don't know the instruments.
I don't know synths, and I got the opportunity to work on synthio.
And there was a lot of reading, and I learned about something like LFOs, and I would try
to create a structure that would allow it to be expanded and elaborated upon.
And I think in some respects I've succeeded, because now we have audio filters, and they're
reusing these other things like the LFOs that existed already in ways that repurpose them
and increase what they do.
And Tod, I don't know if you said what an LFO was.
What is an LFO?
LFO, it's from the Spanish LFO.
No, it's a low frequency oscillator in synthesizers for reasons back in the misty times, people
divided up oscillators into two kind of classes where there's oscillators that made noise
and there's oscillators that are really slow, basically at sort of human knob turning rates.
And so instead of you sitting there with your hand on the filter knob going "wob wob wob",
you can instead have a low frequency oscillator essentially turn that knob for you and do
the "wob wob wob" without you having to do it.
In practice, a lot of oscillators can be both, but for code reasons, like with SynthIO, there's
a nice efficiency you can do by having oscillators that are only updated at a lower rate.
You can save some CPU instead of having them be full audio rate oscillators.
So yeah, so we have in synthio, Jeff made real audio oscillators that can be arbitrary
waves and then we've got the low frequency oscillators that update, I think up to around
50 or 60 hertz.
I've never really tested what the upper range is on how fast they can go.
Well, it's 256 samples, isn't it?
So depending on your sample rate, I think it's faster than 50 times per second.
I have to do some calculation here.
The whole LFO system and the block input system work amazing.
Like that was one of the first things I ran into when I started the draft PR for audio
effects was people saying you need to add in this feature.
You need to let people change the delay and the mix level and everything based on these
LFOs.
And it was so simple to add in.
Yeah, a great example is that is within the audio mixer. We
recently added support for block input on the level. And one of
the one of the original, you know, audio effects, you know,
it's in like amps and stuff from like the 50s is tremolo, right,
which is where you just increase and decrease the volume, like
sweeping that knob. And now you can do that very easily using
synthio LFOs and stuff. So that's pretty cool.
That's cool. I'd not I'd not really noticed that in the PR.
That was in like the last two weeks, I think.
Oh, that's awesome.
The other bonus with a lot of this stuff
now being in Audio Mixer and all these audio effects
is we realized they don't have to be just for the synth.
The synth was what inspired me and what I think Cooper
and myself spent a lot of our time in.
But then we realized raw sample and WAV files
and any other audio files played through Circuit Python,
we can add these effects to.
So now you could have an MP3 playing.
And if you want to add an effect to it, you can.
You could put the filters on it.
You could put an echo for some reason.
I'm not sure why, but--
I'm looking forward to Halloween.
I have a feeling there's some spooky sounds
that could be put in there.
Definitely that.
Yeah, although just like an equalizer style
control over your MP3 playback is something people have
requested, and I think that's possible now.
I think we have the pieces, and somebody should put them
together and let us know if it works.
Paul, did you suggest that?
Because I hadn't actually thought about that until I saw that question.
That was actually a question that Tod Bott came up with was, could
we see someone adding bass and treble controls to MP3 playback like an 80s boombox?
If you hear me, Jeff, poking you in the future to clean up that PR there for,
was it shelf and everything?
I would love to get to that.
You know, I just have a lot of other priorities
in my work right now, and some of you have probably heard
I'm planning on stepping back from Adafruit this April,
gonna take a vacation and do some other stuff.
But, you know, when I'm back in the right kind of space
and not as much focused on Adafruit priorities
as stuff that feels cool to me,
I hope that's one of the things I'll come back and pick up.
But it may be a while, so you might also pick that up
and see if you can get it over the finish line.
'Cause I think-- - That'd be great.
- I think you could, I think you could do it.
It's mostly just edits onto the existing filter system, right?
So it was like I changed the way that stuff was calculated and that's all in.
And I think it may have been a matter of being out of space
on some of the boards when I added in all the other goodies.
And yeah, that's not the fun part.
The fun part is the coding, not making sure that it still works on
on a board that, you know, you wouldn't recommend to a person for a new project.
Yeah. Right. Yeah.
That's actually a great point about also why I got into this is the
RP-2350 came out and it had built-in floating point
and so much of what's involved in the effects
is floating point math. So when it was just like audio mixer
and playing an mp3 or playing the synth that was enough to play on most chip sets
but now we've got this chip with both space
RAM and storage wise, as well as the processing power to actually power this.
So now it's possible to put it through multiple effects at once.
I've tried five or ten at once and was able to play successfully.
It's not until you sort of get to a bit bigger than that where it starts to have
issues, but compared to what you could before, it's a lot more.
In that chain, did you happen to use the distortion overdrive effect?
I have not tried that one yet.
That's the one I'm really nervous about.
There's a lot of floating point going on.
It really is a game changer.
Uh, when I was working on synthio, I was very much thinking about the RP2040
kind of as the, as the target system.
Cause we were looking at making the RP2040 prop maker feather.
I think the product ended up being called.
And so that was a good reason to take time to look at synth.
And that didn't have the floating point unit.
So I was reading all this like 1990s.
Here's how we do all of the math for synthesizing
without using floating point, just using integers.
So there's a lot of code in there that
treats a 16-bit integer with a virtual decimal point
after the third bit and crazy stuff like that.
And now if we say, oh, well, we're
going to have a floating point unit, a lot of that stuff
becomes much simpler than I made it.
but we want to keep like the main part of synthio
still working on all the microcontrollers,
but it's really neat in these distortion,
which specific one was it that you're talking about?
Say the name again.
- The overdrive.
- The overdrive.
- For listeners, there's multiple modes
of the distortion effect, and that's one of them.
- Yeah, I remember I was reviewing this pull request.
Thank you for your patience waiting for me
to review that pull request.
And I'm like, it looks like you're calling a trig function
for every sample.
are you sure that's gonna work?
Because I was just in this mode of thinking
with 1990s constraints or with two years ago
microcontroller constraints, and we can do a lot more now.
And I'm glad that y'all kind of breached that frontier
and said, I'm gonna see what happens if I call exponent
or whatever that function was, trig, I don't know.
Every sample.
- I would love to use integer math for all of that,
But besides the bit crush effect,
and that one actually avoids all the floating point
and just use basic integer bit-wise functions.
Besides that, it is very difficult to do a distortion effect
without integer, or floating point math.
- Just because you need that larger range of values
than is convenient to represent.
- The functions themselves,
I think the only other way to do it
would be to use a lookup table of some sort.
then your space becomes your constraint,
which is always in demand.
Definitely.
Yeah, it's amazing how the things that we kind of got
for free in the analog world of like, oh, if you make
your recording to tape a little hot,
or if you turn up the gain too high on your guitar amp,
it distorts.
Something really interesting happens.
Yeah, it sounds cool.
It doesn't sound gross.
Whereas when you distort, over gain on a digital system,
it just clips and sounds harsh and terrible.
And when you try to model that really soft distortion that
happens in the analog realm, you start
calling exponential functions because it's
a really weird nonlinear output.
So yeah, trig function for sample.
Sorry.
Sorry, Jeff.
If it works, it's great.
It's just I'm telling you what my first reaction was.
No, totally, totally.
Yeah, I'm more in your realm because I
started doing synth stuff with Arduino 8-bit.
Yeah, you can't you can't.
Mozzie, am I right?
The other thing I noticed right away, too, is we went from 22
kilohertz on most of our samples to 48 kilohertz stereo, and it
was handling it and it was handling it with a fairly large
effect workload on top of that. And if you try that on an RP
2040, it'll do it a little bit, but not for very long.
So is it fair to say that you really do need an RP-2350 to make most of these effects work?
If you really want to take advantage of them, but if you want to use one or two, depending on the effect and depending on your sample rate, the 2040 will work.
and I haven't actually tried it on other microcontrollers either.
Right now, it's port limited to the Raspberry Pi family,
but in theory, I know
there is somebody who's working on getting audio for the Espressif family,
and I don't see why it wouldn't work on there either.
>> Yeah, that was an interesting development.
Somebody popped up on GitHub with a pull request and said,
"I added analog audio to ESP32,
and I think ESP32 S2.
And this is something that Limor had had me look at
like two years ago, and I looked around and I said,
I don't think I'm up to this.
I don't see how it would work.
And now that the code's written,
it looks really straightforward.
So it's just one of those things
where somebody else takes a look at it
and they had some piece of knowledge that I didn't have
or some piece of experience.
And now everybody's gonna be able to use this functionality
in CircuitPython and do audio on more boards.
So I'm really excited about that,
that little bit of functionality.
- The ESP32 also is a very, very nice chip set
for having native floating point, all that kind of stuff.
- I think it's plenty fast.
- I wanted to say that it had floating point,
but I wasn't sure.
So thanks for that confidence, Tod.
- I think right now, if anyone listening
wants to play with these things,
definitely RP2350 is kind of the most tested system
out there. (laughs)
some of the delays stuff to a custom build of our RP2040
'cause it's turned off for RP2040
just 'cause it doesn't always work.
And it does work, but man, I really wish
there was some sort of modular system for these core modules
so that we wouldn't have to go through that dance of like,
oh, I added this new function in the core
and now the CircuitPython build won't fit on a Trinky
or the CutiePy M0 or something.
I know that's impossible,
but it's something that I've been dreaming for years for CircuitPython.
So we were talking about guitar effects earlier.
Do you see the ability for someone to actually build a guitar pedal using these
audio effects?
Are you ready for this?
Here is a guitar pedal.
And this audio listeners, this is not going to make any sense.
I'll describe it in a second.
So, uh, it's beautiful.
And sorry to take over here.
No, no.
This is something which I actually I
didn't think I was going to do at
first. When I was first working
on these effects, I was really
thinking about synthesizers and I
have used it, the delay, especially
on some of my synthesizers.
But then as soon as I started
playing around with it, I was like,
wait a second, this would work
really well on a guitar pedal, you
know, and controls and like you're
not doing too much else in a guitar
pedal except for just processing
those effects and, you know, pulling
knobs and stuff.
And so I started doing the research, figuring out how to build them.
Of course, what I ended up building is definitely a prototype and I need some
revisions, but what I did is I took and it's actually an RP 2040 right now.
It's an RP 2040 zero, I believe, manufactured by WaveShare,
just because the form factor worked nice for this because they lost my RP 2350
zeros in shipment, which I'm really upset about.
But I know, I know.
But it's that combined with an audio codec, which once again, for listeners,
An audio codec is essentially an input/output/analog system
that your microcontroller can talk to
and manage those analog pathways
without having to use independent chips for input/output,
which is a lot more digital in a ways.
So what I really liked about this chip that I chose,
which is the WM8960, which I wrote a library for
for CircuitPython a couple months ago,
is that you can actually mix the analog input
with that output.
So for a lot of effects--
- Oh, so it can pass through what's coming in?
And, oh. - Yeah.
And it sounds pretty clean.
I actually designed this with a true bypass,
which if you're not familiar with,
it's pretty much, it just takes your guitar
totally out of the pedal
and just passes straight through to the amp.
I designed that with it thinking that there'd be noise,
digital interference and stuff,
but it actually sounds pretty clean,
so I think in a future revision,
I'll change that around to just rely on that codec.
But yeah, in that regard,
You can take that audio into the codec,
have those samples come in over I2S as an input,
and then process whatever you need for it,
and then output it back again on the same bus
over I2S into the codec, and then mix that process,
like say if you're doing a filter or something,
mix that with the original signal as you need
as the user decides, and then, it sounds really good.
I was actually very surprised.
I do have a confession to make,
Because right now CircuitPython does not support
bi-directional I2S input and output.
I've worked to add that support.
- Have you done sins to get this to work?
Did you sin?
(laughing)
You did something bad.
- Say that again.
- Have you committed sins to make this work?
- I have a sin, okay.
So I have a pending draft PR that adds bi-directional I2S,
but it's very shaky and I'm kind of,
I probably shouldn't use this language,
but I'm a bit in DMA hell with that right now,
where it's just, you're dropping buffers
and all this kind of stuff and it sounds bad.
It does work though, surprisingly.
So I would love for someone else
to help me on that at some point,
but what I ended up doing is actually,
my sin is I ended up going to Arduino.
And I've actually been working on the Arduino Pico library
to add that support in, which unfortunately was a lot,
well, I guess fortunately,
was a lot easier than to do in CircuitPython.
So I have this RP2040 running through that
and I'm building a library to manage the pedal
and have all these effects processed
and have a very simple interface for changing the audio.
So you pretty much, kind of like Mozzie,
it's actually very similar to Mozzie,
where you have a control loop and an audio loop
and you just separate your processing and it does it all.
Even utilizing both cores of the Pico, it's pretty cool.
And so I've been able to do distortion, delay, filters.
I stole your biquads, Jeff, I'm sorry.
No, you're absolutely welcome to them
because they're open source and that's one of the reasons.
And you know, I'm not judging.
I think it's great when you use the environment
that's good for you.
I mean, we're here to talk about CircuitPython,
but it's important to acknowledge
there are other environments out there
and they've got a lot of strengths
that we don't always have.
And maybe we'll get there by studying them
or maybe we won't and for something,
another environment will always be better.
But yeah, no shade for using Arduino, absolutely not.
- Yeah, it's also really good when you wanna think through
an algorithm that would have to be written in C
and like, oh, I'm gonna just like punk this out
either in Pico SDK or in Arduino or whatever,
see if it actually makes sense
before going through all the trouble
of making all the CircuitPython bindings
to the C code that's underneath.
So yeah, go Arduino to prototype with.
- However, I think CircuitPython,
if all that worked as I wanted it to work,
I think it would be a better platform in a lot of ways
because next thing you know,
you have to do the display management.
All the synth IO, 'cause one thing I would love to do
is be able to take a guitar and use a tuning process,
read what note you're playing,
and then play it through synth IO.
Like, that would be incredible,
but now that I'm on Arduino, I'm like,
oh, well now I have to figure out
how to get all the synthesis working,
or it'd be so much easier in CircuitPython.
Right. Yeah.
Just the once all that core code, that fast code that has to be written in C
is done, if you can bolt the parts together in CircuitPython
and express in a hopefully simple way, I want this thing up here
to control that thing down there.
I think that is where CircuitPython has a big advantage.
Oh, yeah, definitely.
Yeah, I've found that so much like when I was working on the drum effects,
I could iterate through there blazingly fast.
I was just in the REPL trying,
"Okay, let's try these three things."
No, "Okay, let's change the filter,
the low-pass filter, the high-pass filter."
It made it so much quicker.
Again, nothing against Arduino, I've used it a ton.
But if I had to build,
compile, upload, and test it for all those,
I'd still be working on those effects
if I hadn't just dropped them and given up.
>> Yeah, it's almost like a live coding environment
because you can be there on the REPL and actually
create a synthesizer just by typing in real time.
Yeah, it's amazingly fast and you can just play, you can record
something through MIDI tracks or just... I've had lots of test files which are
just a bunch of notes from some song that I put into test and then
listen to it right away and be like, "not quite right, I need to adjust this,
oh this is better." It becomes a really quick
iterative process to come up with what you want.
So Cooper's been working on a prototype for a guitar pedal.
Do any of you have any other projects in the back of your head
that you want to try with these effects now that they're available in CircuitPython?
Yeah, I mean, I've got a I've got a little what I've been calling
the PicoTouch synth that I've been sitting on for about a year,
and I think I'm going to make a custom build of CircuitPython
that includes some of the delay functions just to get fatter sound.
the ever infinite quest for like a fatter synth sound.
But that'll be in my Tindy store.
It was in my Tindy store for a while,
but I had to turn off my Tindy store
because of all the fires that have been happening around me.
(laughs)
- You mentioned custom build,
is that because it's on RP2040?
- Exactly that, yeah.
- Ah, okay.
- Yeah, 'cause the RP2350 doesn't do cap touch yet
because of the problem with their pins.
So, (laughs)
yeah, it has to be cap touch,
has to be RB2040 and thus has to be a custom build.
Yeah.
Well, and that being one thing I was looking at before I got
busy and unfortunately had to take some time away
from working on it was a chorus effect.
So not just the delay, which is really a delay,
but just a slightly different type.
So the chorus effect just, for those that are listening,
will break up a note and slightly delay it one two three four five whatever many times
but over a small time frame so you get all the waves instead of being in harmony together I guess
or lined up or slightly out of phase and just comes up with that richer fatter sound so that's
on my plate one of the things that I still want to work on and I mentioned earlier was one of the
things that I thought of with effects is a reverb sound.
Yes.
I think it'll just make things sound better. And I've I've
looked at the code. I vaguely know what I'm doing to put it
in. But it's just a matter of getting the time and patience to
put it in and get it working. That one, again, the 2350 really
shines because of the additional memory and storage because
Especially the memory on that one
If you need to record a hundred two hundred milliseconds of 48 kilohertz audio that starts eating a lot of RAM really fast
Yeah, so are you getting into PS RAM territory there or is that fitting in the 512?
K for the what you're thinking about I think it fits in the 512
I've had the audio delays up to a second and I think we kept them at a second on purpose
Otherwise you'll start running into RAM limitations.
I haven't tried it with PS RAM yet.
I don't think I've got a 2350 with PS RAM, but I can solve that problem easily enough.
Quicker than I can write reverbs.
[laughter]
Alright, so the reason why reverb will be important for a whole different class of people than us who want to make synthesizers and stuff,
Is it once we have the ability to do a guitar pedal like audio in then audio out?
Plus reverb plus circuit Python can already do displays and play mp3s
We can now make a circuit Python powered karaoke machine
Some time this year, yeah, I'm gonna I'm gonna try to sell John Parker in this idea once once all the pieces come together
That would be an amazing project to see
You know what I think is really important for us to work on
Soonish or some one of us. I know Tod you have your synth IO tricks
Repository, which I'm sure all of us have referred to at some point. I know I have
I think we are due for an audio effects tricks at some point
Because you mentioned the the chorus mark
I've actually been able to do that to a degree,
but probably needs some refinement.
And if we had some centralized repository of stuff
like that, examples people to use, I think that'd be great.
That's one thing that I wish I've had time to work on
is an intro guide for using audio effects,
because at this point, there isn't.
There is sample code that a bunch of us have put out there,
but there isn't actually a guide on doing it.
And the second is an intro guide on how to make your own audio effects.
Cooper, you've been amazing and I can't say this like this.
I was always hoping somebody would jump in and build on what I started.
And you've done a whole bunch more work that I couldn't have been off on my own.
And then between everyone here, it's great.
And the community is great to bounce ideas off of.
So you're not just working in that little silo by yourself, wondering if
anyone is paying attention to what you're doing.
Like even hearing from Tod tonight
that he's seen my drum effects all over the place.
That feels amazing to hear.
And this whole project has brought
in so many different people that I didn't expect
to hear from to start with.
I think CircuitPython, it's able to cater
to a lot of different groups of makers.
But I think, especially once we really
hash out this audio effects, get the live input working,
all that kind of stuff, I think it just
adds a whole other category of makers,
a whole other community to this project that can utilize these resources.
And that's just really cool.
You know?
Well, that's a great place to wrap it up.
I want to thank each of you for your time, Cooper, Mark, Tod, and Jeff.
I really appreciate you making time to come on the show.
Thanks so much.
Oh, thanks for having me.
Thanks for the invite.
And Cooper was good to meet you face to face.
I know.
Hey, anytime you want to hit me up, I'm I'm around.
All right.
Lovely to see y'all.
Thank you for listening to the CircuitPython Show.
A special thank you to Cooper, Jeff, Mark, and Tod
for joining the show and sharing their experience
in building the new audio effects in CircuitPython.
For show notes and transcripts,
visit www.circuitpythonshow.com.
Until next time, stay positive.