Beautifully done! Technically very impressive--an FFT in assembly language, wow--and delivered with a dose of humor. Thanks for sharing your accomplishments. They encourage me to think freely about what can be achieved with skill and creativity.
Let me remind you, somebody out there wrote a spectrum audio analyzer from scratch, for Microcontroller, with a very nice quality and cool animation effect, using assembly.
fantastic job, I know how hard this is, so it's incredible to see it working. I've taken a copy of the code to look through. I'm really impressed and as a design consultant I rarely say that about youtube projects
@@DigitalPhagethank you for sharing the code, I really appreciate it. I've been looking for a fast way of calculating the freq domain for a while and I had been toying with similar ideas so it was great to come across your channel and see that you had it up and running. I plan to port a version of your code onto an ESP32 (240MHz dual core), probably add more bins, then create a spectrograph. My background is in image processing so I hope I can use that for speech recognition. I will make a video of the project and let you know when I post it on my main channel. (I need to finish my BT speakers first before starting this project). I'll give you credit and your channel a link as I think you have done a bloody good job, well done!
Ha! I just spent a couple of hours listening to maths explanations on the fourier domain, come to this video and realise that a graphical equaliser is the exact same thing, just I didn't know it. Nice video!
Of course. You should also be aware this guy is pretty clever to not only retain adequate accuracy doing an FFT approximation, but also minimizing rounding errors working in 8-bit. I think this guy is masochistic. However, I noticed that he wasn't showing that ideal slope associated with square waves, but at least it is preserving the dominant frequencies. Good enough for an audio spectrum analyzer.
Excellent work! Just started to playing around with FFT on Atmega328@16MHz My Project involves a kind of light organ using Adafruit.com NeoPixels in a santa hat! Your project has given some insight to my misunderstanding on how close the bins have to be to the target frequencies to make the lights dance brightly.
VERY GOOD IT IS COOL I found a plate having A and got it working ATmega88 THAT IS ALREADY WITH MY RECORD PROGRAMMER CAN NOT HAVE NOTHING BUT would not have SOME EXAMPLES FOR THAT MICROCONTROLLER CODE AS THESE ADVANCED ENOUGH TO SEE THAT FIGURE AND THE TALENT IS APPRECIATED VERY GOOD OF TRUTH GREETINGS FROM SAN LUIS
Petex90 I wouldn't belittle the effectiveness of C, it's possible to write C code that is 96-7% as fast as assembler, but a good compiler can do better than an average assembly level programmer. The only thing that C might not have as clean is startup code but even there you can choose your own start up.
this is the smoothest and most responsive I have seen for micro board projects, even in 2024. So Im trying to replicate or convert using a audrino 32esp. is this possible?
Thank you. Replicate yes, but not in assembly code. (esp32 family have a number of different CPU core). eps32 run very fast so a High Level language will work. Maybe replicating the flow in arduino could be fruitful. I list the texts in the source code that I took inspiration from, they use C code so that may be more useful.
Hello DigitalPhage tis is a great project I do have one question on will this support a larger 1.3 inch blue oled, I have bad eyes and a bigger display would help and also I love the color blue on these displays. Thank you
Yeh, no problem, the 0.96", 1.3" and 1.5" ,White or Blue, are all vary similar. With small modification to deal with whatever controller it has. (SSD130x)
Thank you. Is that the old 8051 core version? not without complete rewrite and a somewhat faster clock. But MCU's using there 8bit AVR core should only need the ADC interface re-writen.
/* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin-top:0cm; mso-para-margin-right:0cm; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0cm; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-fareast-language:EN-US;} Thank you! The peak-hold was surprising simple to implement and had the spare cycles so yeh why not! But CPU usage hmmm I did setup an experiment to calculate worst case usage but I can’t recall the result (Mainly wanted to confirm I wasn’t dropping any ADC samples). I think it was in the low 90%???, If I feel enthused I may do the tests again and find the truth.
etmax1 Thank you! The peak-hold was surprising simple to implement and had the spare cycles so yeh why not! But CPU usage hmmm I did setup an experiment to calculate worst case usage but I can’t recall the result (Mainly wanted to confirm I wasn’t dropping any ADC samples). I think it was in the low 90%???, If I feel enthused I may do the tests again and find the truth. (Sorry if I posted this twice I think my previous reply disappeared)
It's been a while but as I recall, I chose an 8mhz CPU clock, this resulted in the ADC sampling at 9.6Khz. Nyquist says 9.6Khz/2 = 4.8Khz as actual frequency response. It is an FFT64 so 64bins but only half those are useful so 32bin, of that the first bin is just DC offset and last is not used (forgotten why) so that leaves 30bins, 4.8Khz/30 = 160Hz per bin. This is just a crude calculation. With modern Atmel (now microchip) brains i.e. AVR128DB's with much more capable ADC's this code could be run much faster I assume.
The display & filter board connect to a unit called an "AVR pad" which is basically just a ATMega88 broken out to pins for wires to be plugged in. How its linked in is showed at the start of the ASM file. It's not my schematic but I will ask the owner if I can include it, Let you know when/if its done.
Thanks! Beyond changing the ".include" there should be no difference to compile to a 328P, Newer OLED's? if you mean colour they would probably need more data sent to them to achieve a similar result,I've found anything monochrome all transfer data in a similar way after their initialization. As for Arduino, if you don't care about its boot loader they can be programmed as any otherer Atmel 8bit, to keep the bootloader I imagine should be possible with a bit of work, move the ORG, do something about the interrupt table.
Do you mean SSD1306?, which it is already using. But that OLED does have other interface options such as I2C and Parallel. I prefer SPI as it has less overheads.
+DigitalPhage ok. yes. i have both spi and i2c versions of that oled 😊. would this also run on an atmega8? have a few chips here. what compiler do I use for this asm? sorry but not so well versed with atmel
It should run on Atmega8 but there will need to be a number register references changed first, clock prescaler, interrupt table labels,ADC configuration bit names. I currently use Atmel Studio 7.0 , This was created in a much older version of studio but I just checked and it compiles without error in the latest version.
+UglyRhino An "FFT Guitar Tuner" sounds a good idea to me! But you would have to go somewhat beyond what I've demonstrated here, you would need much higher frequency resolution (more bins) so a processor like an ARM would be a must. (A google search shows a lot of interest in the subject).
But wait, if it takes 2.39ms to produce the FFT results then how can you get into the 7 khz frequency? And I'm not even talking about the amount of clocks necessary to deal with a single calculation. You claim to do 64! It's impossible for your sample rate to be 14 khz since your MCU maxed out already with the 2.39ms (418hz!!!) busy time.
+F0kGggle Ah a sceptic! no problem I respect that :) 1st off 7Khz? In the first line of my description I sate ~9.8Khz sampling. The 7Khz I think you are referring to is the specs for the input filter (-3db ~7khz), 7khz 3db point was chosen to keep any significant roll-off above 5Khz. And the cadence of the program is something like this: 6.5ms to gather 64 samples. 2.39ms to do the FFT. leaving ~4ms to do the Imaginary to Real convertion, Some Averaging, Updating display. Now the thing that I may need to emphasised is the while all this is happening I'm still sampling for the next 64 sample block. So as long as all the calculation and such are done within 6.5ms (And they are) I just have to wait around a bit while the last few sample of the next 64 Byte block arrive. Hope that clarifies it a bit.
+DigitalPhage Cool! Explanation much appreciated. It's more clear now to see the resolution is decided in the processing speed aka frequency span inside the 6.5 ms and that the FFT 2.39 ms only makes the output envelopes suffers in resolution. I believe you will get an attention boost if you go a step further and create a vocoder with an ATmega328PU. The individual envelopes sure are able to manage that not?
+F0kGggle Yeh, I was thinking along the lines of Vocoder or similar as the next step, the extra 1K of SRAM in the ATMega328 would be a must! This got me thinking, assuming the Inverse-FFT runs about same time as the FFT & there was no need to do the Imaginary to Real number conversion, then maybe it could still run at 8Mhz, there’s still the need for a DAC someware in there. Then ignoring my silly limitation of 8Mhz that I like and pushing too the full 20Mhz then the full 15kS/s sampling could easily be achieved with plenty of time to spare, but that’s no fun. Anyhow as for now I have no time to explore this but I still hope to do something more in the near future.
DigitalPhage okay thanks, have you ever tried any other methods for spectrum estimation like welch Bartlett or widrow-hoffman or arma models? Because they will give you better estimate than normal windowed dft.
Beautifully done! Technically very impressive--an FFT in assembly language, wow--and delivered with a dose of humor. Thanks for sharing your accomplishments. They encourage me to think freely about what can be achieved with skill and creativity.
Michiel Kappeyne
Thank you for the kind comments :)
wat is dit mooi gemaakt. knap stukje werk,daar moet je een waterorgel
mee bedienen.dan heb je heel wat bekijks,veel liefs Riek en Sjaak.
Let me remind you, somebody out there wrote a spectrum audio analyzer from scratch, for Microcontroller, with a very nice quality and cool animation effect, using assembly.
fantastic job, I know how hard this is, so it's incredible to see it working. I've taken a copy of the code to look through. I'm really impressed and as a design consultant I rarely say that about youtube projects
Thank you, much appreciated
@@DigitalPhagethank you for sharing the code, I really appreciate it. I've been looking for a fast way of calculating the freq domain for a while and I had been toying with similar ideas so it was great to come across your channel and see that you had it up and running. I plan to port a version of your code onto an ESP32 (240MHz dual core), probably add more bins, then create a spectrograph. My background is in image processing so I hope I can use that for speech recognition. I will make a video of the project and let you know when I post it on my main channel. (I need to finish my BT speakers first before starting this project). I'll give you credit and your channel a link as I think you have done a bloody good job, well done!
I don't know what is better, project, code or music.
Thank you :)
Or the camera quality
Hi, glad to to view this, this spectrum analyzer runs so smoothly...
Thanks, much appreciated.
Nicely done! Duly impressed, thanks for sharing the code...
Ha! I just spent a couple of hours listening to maths explanations on the fourier domain, come to this video and realise that a graphical equaliser is the exact same thing, just I didn't know it. Nice video!
Of course. You should also be aware this guy is pretty clever to not only retain adequate accuracy doing an FFT approximation, but also minimizing rounding errors working in 8-bit. I think this guy is masochistic. However, I noticed that he wasn't showing that ideal slope associated with square waves, but at least it is preserving the dominant frequencies. Good enough for an audio spectrum analyzer.
Extra nicely done!
Being inspired of your work, I wrote similar visualizer, named e-pi-ALTES.
Looks great! Glad to have been inspiration.
This is cool. I'm interested in trying it out myself.
I never heard the techno remix of computer #3 - thank you :D :D :D (RIP France Gall)
Nicely done! Who needs more than 8MHz... Can fly to the moon on less than that.
Excellent work! Just started to playing around with FFT on Atmega328@16MHz My Project involves a kind of light organ using Adafruit.com NeoPixels in a santa hat! Your project has given some insight to my misunderstanding on how close the bins have to be to the target frequencies to make the lights dance brightly.
+Michael Rinkle Thankyou! Sounds a fun project, hope to see the results up on the Tube.
Thanks for you're comment. I've added a link in the comments to the schematics.
do you sell them complete?
I had a lot fun watching this :)
Nice job with FFT and cool display, but for me - OLED is too expensive for hobby projects. N82 display replacement is cheaper, bigger and colorful...
Cool project!
Impressive. Thanks for sharing
VERY GOOD
IT IS COOL
I found a plate having A and got it working ATmega88 THAT IS ALREADY WITH MY RECORD PROGRAMMER CAN NOT HAVE NOTHING BUT would not have SOME EXAMPLES FOR THAT MICROCONTROLLER CODE AS THESE
ADVANCED ENOUGH TO SEE THAT FIGURE AND THE TALENT IS APPRECIATED
VERY GOOD OF TRUTH
GREETINGS FROM SAN LUIS
mmmmm i think there is another micro jajaja. No, it's really nice!! congratulations
incredible!
Genius.
Хорошая работа !
Great video, thanks for the source code! None of that C rubbish here :)
Petex90 A clear mind, excellent!!
Petex90 I wouldn't belittle the effectiveness of C, it's possible to write C code that is 96-7% as fast as assembler, but a good compiler can do better than an average assembly level programmer. The only thing that C might not have as clean is startup code but even there you can choose your own start up.
this is dope
My brain hurts!!
Just gr8!
this is the smoothest and most responsive I have seen for micro board projects, even in 2024. So Im trying to replicate or convert using a audrino 32esp. is this possible?
Thank you. Replicate yes, but not in assembly code. (esp32 family have a number of different CPU core). eps32 run very fast so a High Level language will work. Maybe replicating the flow in arduino could be fruitful. I list the texts in the source code that I took inspiration from, they use C code so that may be more useful.
@@DigitalPhage So you have a Audrino C++ version you can send me a link on?
@@ChristinaLaRagina Sorry no, try googling "Cooley-Tukey arduino code example"
Hello DigitalPhage tis is a great project I do have one question on will this support a larger 1.3 inch blue oled, I have bad eyes and a bigger display would help and also I love the color blue on these displays. Thank you
Yeh, no problem, the 0.96", 1.3" and 1.5" ,White or Blue, are all vary similar. With small modification to deal with whatever controller it has. (SSD130x)
An excellent job. Do you think it would work in an Atmel of the 51 family
Thank you. Is that the old 8051 core version? not without complete rewrite and a somewhat faster clock. But MCU's using there 8bit AVR core should only need the ADC interface re-writen.
Прикольно...
ваще круть. :D
Amazing !! Thanks for sharing :)
Do you think i could use a bigger screen ?
Wow, Excellent! by the way, which is the model of the OLED display?
Thanks! Display is an EastRising ER-OLED 013-1W from buydisplay.com, have purchased many displays from them and happy with there service.
It is really cool!! Can you please show the schematics?
need full schematic
Ok, Updated FFT Schematics.zip to include all schematics
i don't know how to connect pins of OLed display to atmega 88
Can you make me one that change color and fit in double din car dash board?
like the way the peak hold works :-) do you know what your CPU usage rate is?
etmax1
Normal
0
false
false
false
EN-AU
X-NONE
X-NONE
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin-top:0cm;
mso-para-margin-right:0cm;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0cm;
line-height:115%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-fareast-language:EN-US;}
Thank you! The peak-hold was surprising simple to implement and had the spare cycles so yeh why not!
But CPU usage hmmm I did setup an experiment to calculate worst case usage but I can’t recall the result (Mainly wanted to confirm I wasn’t dropping any ADC samples). I think it was in the low 90%???, If I feel enthused I may do the tests again and find the truth.
etmax1 Thank you! The peak-hold was surprising simple to implement and had the spare cycles so yeh why not!
But CPU usage hmmm I did setup an experiment to calculate worst case usage but I can’t recall the result (Mainly wanted to confirm I wasn’t dropping any ADC samples). I think it was in the low 90%???, If I feel enthused I may do the tests again and find the truth.
(Sorry if I posted this twice I think my previous reply disappeared)
What is the sampling frequency ? and What is resolution of frequency bins ?
It's been a while but as I recall, I chose an 8mhz CPU clock, this resulted in the ADC sampling at 9.6Khz. Nyquist says 9.6Khz/2 = 4.8Khz as actual frequency response. It is an FFT64 so 64bins but only half those are useful so 32bin, of that the first bin is just DC offset and last is not used (forgotten why) so that leaves 30bins, 4.8Khz/30 = 160Hz per bin. This is just a crude calculation.
With modern Atmel (now microchip) brains i.e. AVR128DB's with much more capable ADC's this code could be run much faster I assume.
@@DigitalPhage Thank you very much. this has helped me to understand mathematics behind fft.
Can you please show full the schematics?
Many thanks
The display & filter board connect to a unit called an "AVR pad" which is basically just a ATMega88 broken out to pins for wires to be plugged in. How its linked in is showed at the start of the ASM file. It's not my schematic but I will ask the owner if I can include it, Let you know when/if its done.
wtf .. FFT with assembly !
Yep, let assembly be your friend :)
Real nice with real time display. Is the schematics and code can be shared
Thanks! If you asking about accessing and sharing the shematics and source code, yeh sure, links are in the description.
hi. this is very cool. I wonder if this is portable to using newer oleds and an atmega 328p.
or to an arduino?
Thanks!
Beyond changing the ".include" there should be no difference to compile to a 328P, Newer OLED's? if you mean colour they would probably need more data sent to them to achieve a similar result,I've found anything monochrome all transfer data in a similar way after their initialization.
As for Arduino, if you don't care about its boot loader they can be programmed as any otherer Atmel 8bit, to keep the bootloader I imagine
should be possible with a bit of work, move the ORG, do something about the interrupt table.
+DigitalPhage hi. newer oled like serial ss1306.
Do you mean SSD1306?, which it is already using. But that OLED does have other interface options such as I2C and Parallel. I prefer SPI as it has less overheads.
+DigitalPhage ok. yes. i have both spi and i2c versions of that oled 😊. would this also run on an atmega8? have a few chips here.
what compiler do I use for this asm? sorry but not so well versed with atmel
It should run on Atmega8 but there will need to be a number register references changed first, clock prescaler, interrupt table labels,ADC configuration bit names.
I currently use Atmel Studio 7.0 , This was created in a much older version of studio but I just checked and it compiles without error in the latest version.
Great entertainment:)
P
berapa harga mrs?
do you recommend using this technique to build a guitar tuner?
+UglyRhino An "FFT Guitar Tuner" sounds a good idea to me! But you would have to go somewhat beyond what I've demonstrated here, you would need much higher frequency resolution (more bins) so a processor like an ARM would be a must. (A google search shows a lot of interest in the subject).
i know the video is 7yo .. but do u by any chance have an alternative for the 3rd link(3)?
its not working
Thanks for pointing that out. Link should be working now.
@@DigitalPhage awesome
膜拜大神啊!
Do u want to sell the code??
But wait, if it takes 2.39ms to produce the FFT results then how can you get into the 7 khz frequency? And I'm not even talking about the amount of clocks necessary to deal with a single calculation. You claim to do 64! It's impossible for your sample rate to be 14 khz since your MCU maxed out already with the 2.39ms (418hz!!!) busy time.
+F0kGggle Ah a sceptic! no problem I respect that :)
1st off 7Khz? In the first line of my description I sate ~9.8Khz sampling. The 7Khz I think you are referring to is the specs for the input filter (-3db ~7khz),
7khz 3db point was chosen to keep any significant roll-off above 5Khz.
And the cadence of the program is something like this:
6.5ms to gather 64 samples.
2.39ms to do the FFT.
leaving ~4ms to do the Imaginary to Real convertion, Some Averaging, Updating display.
Now the thing that I may need to emphasised is the while all this is happening I'm still sampling for the next 64 sample block.
So as long as all the calculation and such are done within 6.5ms (And they are) I just have to wait around a bit while the last few sample of the next 64 Byte block arrive.
Hope that clarifies it a bit.
+DigitalPhage Cool! Explanation much appreciated. It's more clear now to see the resolution is decided in the processing speed aka frequency span inside the 6.5 ms and that the FFT 2.39 ms only makes the output envelopes suffers in resolution. I believe you will get an attention boost if you go a step further and create a vocoder with an ATmega328PU. The individual envelopes sure are able to manage that not?
+F0kGggle Yeh, I was thinking along the lines of Vocoder or similar as the next step, the extra 1K of SRAM in the ATMega328 would be a must! This got me thinking, assuming the Inverse-FFT runs about same time as the FFT & there was no need to do the Imaginary to Real number conversion, then maybe it could still run at 8Mhz, there’s still the need for a DAC someware in there.
Then ignoring my silly limitation of 8Mhz that I like and pushing too the full 20Mhz then the full 15kS/s sampling could easily be achieved with plenty of time to spare, but that’s no fun.
Anyhow as for now I have no time to explore this but I still hope to do something more in the near future.
whats the song at 2.13 ? :)
Ah yes, The song playing between 1:51-2:25. A chance find off a mid 90's Promo VHS tape "B.I.O.S - Der Computer Nr.3".
You used Hamming window?
No, just he default square window(I think that’s what it’s called), there would be no spare time to do anything more in this implementation.
DigitalPhage okay thanks, have you ever tried any other methods for spectrum estimation like welch Bartlett or widrow-hoffman or arma models?
Because they will give you better estimate than normal windowed dft.
Code.?
Linked in the description
c++?
No, assembly.
wow
нормас