• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • Buried in cloud files? We can help with Spring cleaning!

    Whether you use Dropbox, Drive, G-Suite, OneDrive, Gmail, Slack, Notion, or all of the above, Dokkio will organize your files for you. Try Dokkio (from the makers of PBworks) for free today.

  • Dokkio (from the makers of PBworks) was #2 on Product Hunt! Check out what people are saying by clicking here.



Page history last edited by PBworks 14 years, 8 months ago

Standalone AVR Music Player "Sound Bug"


Using the term 'music' liberally here, it will play a squeaky, but recognizable stream of audio, generated from MIDI files.


It's a satisfying little project that is a nice change from the typical beginner embedded controller blinking LED project(s).


You can't get any simpler than this: a piezo buzzer, a power supply (3x1.5 AA), a breadboard, and an AVR (ATmega16, but almost any will do).



You'll also need WinAVR or avr-gcc on Linux. To make new music files, you'll also need Perl and a program such as MIDICSV to convert the files.


This code is lifted from the AvrButterfly originally from Atmel, and as modified and ported by MartinThomas to GCC. He's got tons of info on his page and I've gone back to it many times as a resource.


I've made a few changes. I've extracted out only the essential sound and timer files from the Butterfly source code, and hacked them mercilessly to remove non-essential code, and code I did not understand. Which is a fair amount :-). I've also separated the songs into separate files to make it easy to mix and match songs to include.


Once loaded, wired, and powered up, it will play the selected audio file repeatedly. In this case, Invention #8 by Bach.

I'm still learning how to use the clock prescaler on the ATmega16, so I made life simple and used AVRStudio to adjust the clock down to 1MHz to make it match the prescaled value from AvrButterfly


avrsound.zip contains the files, including the music files.


The modified sound.c automatically plays the indicated songs as indicated in the songs index in main() function. By changing this number you can play a different song. It would be small change to make it play a different song or a song triggered by a button press.


MIDI File Conversion


In order to get access to a large list of music and audio, I made a little program to convert arbitrary MIDI files into the byte stream required for the AVR sound.c file.


invent8.mid is the original MIDI file, available from many sites...


invent8.csv is a CSV (CommaSeparatedFile) file extracted from the MIDI file above using the free Perl program called MIDICSV.


invent8.csv is further converted into a ".h" include file fragment called invent8.h using my free Perl program m2b included in the

avrsound.zip archive.


To use m2b run it as: m2b < inputfile.csv


You'll probably want to give the new song a different name in the newly created include file.


This file can then be incorporated (by hand) into the sound.c. If you add or delete a song, you'll need to edit the Songs array, and change the WHICHSONG index to point to your new song.




The Makefile is set for the ATmega16, and to use avrdude to load the file into your AVR when you "make program". As a beginning AVR programmer, I found it somewhat cryptic to figure out how to port the timer code in sound.c intended for the ATmega169 in the butterfly. To convert between the original ATmega169 code and the ATmega16, I made several changes in sound.c and timer0.c


  • changed references from TIMSK0 to TIMSK
  • changed references from OCR0A to OCR0, and OCIE0A to OCIEOA
  • removed references to timer2
  • changed output port references for OC1A from PORTB (on the '169) to PORTD (on the '16).
  • changed port direction register from DDRB to DDRD (portb to portd)


There does not appear to be an obvious standardized way to write portable code that uses timers, signals, interrupts that I've come across yet, even in C, let along assembler.


The Hardware


  • Put your AVR on a breadboard and connect power and ground appropriately.
  • Connect one end of the speaker (piezo buzzer) to ground and the other to OC1A out. This appears to be inconsistently assigned on various AVRs to one of the data output pins so look for OC1A.


Audio should play right away.


Trouble Shooting


  • Is your AVR running at 1Mhz (or did you figure out how to set the prescaler)?
  • Did you check that you got the right pin for OC1A?
  • Did you set the compile flag MCU in the Makefile for your appropriate AVR processor?
  • Did you ground the speaker?


Apologies in advance for errors/omissions. I found the lack of beginner AVR material a bit of an uphill battle and I'm hoping that by putting some works in progress that have helped me learn I can save someone else a little time. Good luck!


To Be Done


  • Break out audio files into separate compile file (easy)
  • Load it from MMC card
  • Integrate Roman Black's cool 1-bit audio?




contact newsaccount dot h at gmail dot com with questions or comments




Andy N. has generously updated my avrsound file. I've replaced mine with his. My original one is at

avrsound-old.zip if you need it for some reason or want to compare his changes to my original file.





Thanks for taking the time to isolate the sound player from the butterfly, I've found it a helpful intro into making sounds on the AVR.


I just wanted to send you a version of your folder with an AVR studio project file and relevant makefile in order to make it that little bit easier for beginners to use. I've set it up with a m16 as the device in line with your code.


Something that tripped me up when building from AVR Studio is that fact that the -funsigned-chars flag is unchecked by default in AVR Studio, and the tunes either won't play or won't loop in this state(for me at least), so I thought that might be worth mentioning!

I've also changed the SIGNAL(SIG_OUTPUT_COMPARE0) interrupt service routine to ISR(TIMER0_COMP_vect) in line with the latest version of the gcc butterfly port (stops the obsolescence warning at build).


Thanks again for the code.


Best wishes,

Andy N.


James asked if the avrsound can play polyphonic sounds; unfortunately the answer is that it is monophonic.


Sebastiaan had a question about using m2b, I modified the wiki above to indicate how it is used.

Comments (0)

You don't have permission to comment on this page.