The hardware chiptune project
by kryo
Download:
- kryo-hardware_chiptune (Original zipped release, DivX, 18.5 MB)
- Linus Akesson - The hardware chiptune project song (Recorded MP3, 1.5 MB)
- hardwarechiptune-cad (Schematic, EPS source code, 8.6 kB)
- hardwarechiptune-cad (Schematic, PDF, 31.9 kB)
- hardwarechiptune-tracker (Tracker with source code, docs and song data, 26.0 kB)
- hardwarechiptune-src (AVR source code, 10.5 kB)
Normally, when you create a chiptune, you start with an existing chip (such as the SID chip or the YM2149) and write a tune for it. We decided to start from scratch, and create a chip and a tune.
It all started at St. Lars Meeting III, an oldschool demo party held in Lund. Yarrick, flex and I were there. I had gotten the idea for the project on the day before the party, so things were a bit spontaneous, and we had to make do with whatever components I had laying around.
In the beginning, we used a homebrewn AVR programmer, which I had built as part of a course in mechatronics. flex valiantly supplied the USB-to-serial adapter. However, at one point we started experimenting with the so called fuse bits of the AVR, basically trying to make the processor run at 8 MHz instead of the default 1 MHz. When we did this, the AVR programmer stopped working.
Luckily, I had brought some spare microcontrollers, but we knew that we'd eventually need those 8 MHz anyway. So we called Laban on the telephone, and asked him to bring his STK500 (a commercial AVR programmer). In order to use it, we realized that we needed some software, so Yarrick downloaded avrdude, using his mobile phone as an internet gateway. (Did I mention it was an oldschool party?)
We wrote all the sound-reproducing software at the St. Lars meeting. One particularly interesting bug that kept us wondering was the fact that when we tried to multiply two integers on a particular source code line in the interrupt routine, all sorts of weird things would occur. If we commented out the multiplication, things would work. However, there were other multiplications in the interrupt routine that did work. The "weird things" were that, for instance, we wrote a constant to an output port at startup, and never wrote to that port anywhere else in the program; but when we un-commented the multiplication in the interrupt routine, that output port emitted a quite different signal.
This confused us to no end, until we looked at the generated machine code and started counting the clock cycles. Apparently, the multiplication was the final straw that caused the interrupt routine to run for too long. Before the interrupt routine would finish, another interrupt would occur, causing a new frame to be pushed onto the stack. The stack would fill up and the new stack frames would overwrite RAM and eventually the I/O registers.
This meant that we would have to rewrite the interrupt routine in assembly language.
Once we had the software up and running, we had to compose a chiptune. I had been experimenting with chip trackers before, so I re-used some code, and hooked it up to the sound routine, which was quickly ported from the AVR.
Unfortunately the party was very noisy, and we were sitting just below a loudspeaker, so it was quite impossible to compose anything. Since I lived nearby, and had recently had a cold, I was sleeping at home. So, this night I went home, got some sleep, and wrote the chiptune in the morning.
Sadly, when I got back, the party was already over. There were several people left, but the lights were on. I asked the crew if we could stay for an hour or so, and see if we could get it to work (which would have been nice, because then we would have completed the whole project in just one weekend). We were allowed to stay, but alas, the chiptune that I had written was too large to fit into the 8 KB of flash ROM together with all the code. This was such a setback that we had to give up.
I brought it all home, and ordered a few new components (in particular, a resistor ladder, so that we wouldn't have to use discrete resistors for the D/A conversion). flex and I also discussed various ways of compressing the song data.
Eventually, we managed to cram it all into 8 KB. We couldn't use any standard compression algorithms, since we were so low on RAM (i.e. there was no room for the unpacked data). Instead, we devised a solution involving variable bit-length data structures and lots of bit shifting. We also removed one of the command tracks; as you can see in the tracker screenshot, every note can be followed by two effect commands. To save space, we removed support for the second command, and edited the tune to cope with this new limitation.
At this point we had decided to bring the project to Birdie 17, and participate in the wild compo.
The time had come to move the project from the solderless protoboard. The technique of using schematics printed on paper, glued to a veroboard, is part of the rapid prototyping method taught in the mechatronics course. I wrote the schematics in PostScript, using a set of functions that I had designed during that course.
We ended up with a 5th place in the Birdie wild compo. That's actually good, given that it was a non-technical audience. The winning entries featured humour and/or singing girls, of course. =)
Here's the Pouët page for the chiptune project.
Posted Saturday 30-Jun-2007 11:04
Discuss this page
Disclaimer: I am not responsible for what people (other than myself) write in the forums. Please report any abuse, such as insults, slander, spam and illegal material, and I will take appropriate actions. Don't feed the trolls.
Jag tar inget ansvar för det som skrivs i forumet, förutom mina egna inlägg. Vänligen rapportera alla inlägg som bryter mot reglerna, så ska jag se vad jag kan göra. Som regelbrott räknas till exempel förolämpningar, förtal, spam och olagligt material. Mata inte trålarna.
Wed 6-Feb-2008 22:15
Mon 7-Apr-2008 05:57
Jeronimo, from Brazil
www.blogdoje.com.br
Mon 7-Apr-2008 10:32
One small hint for prototyping boards. The vertical "bridges" are looking a bit messy (i know, its a prototype).
Before using silver wire: Unroll 1 Meter of wire, attach it to a fixed object, grab the other end (with a gripper) and pull it hardly. Now you have very straight silver wire which looks quite nice :)
Thx for the idea of gluing the layout onto the board, i will give it a try....
kiu
Fri 25-Apr-2008 12:18
i mean, could u tell me what i need to build it?
like the components?
Mon 28-Apr-2008 00:53
Fri 2-May-2008 17:20
What diode did you use? I just started to order all the parts needed ;-)
Can i use any standard diode at the 9V power source?
Tue 6-May-2008 21:06
Wed 7-May-2008 21:41
http://youtube.com/watch?v=tuvwfJhWyik
Mon 19-May-2008 16:22
Mon 16-Jun-2008 18:41
Sun 3-Aug-2008 22:37
Sat 20-Sep-2008 03:07
could you provide any help? i'm more assembly coder than c one :(
Sat 20-Sep-2008 05:22
instead pdcurses for win32, there is pdcurses for SDL library which works as it should (win32 version needs LINES and COLUMS as system envirotment variables, and works only if run from command prompt)
anyway...
MakeFile:
LDFLAGS=-lpdcurses -lmingw32 -lSDLmain -lSDL -mwindows
main.c:
if(argc != 2) {
fprintf(stderr, "usage: %s <filename>\n", argv[0]);
}
...
if(SDL_OpenAudio(&requested, &obtained) == -1) {
fprintf(stderr, "SDL_OpenAudio");
}
and <err.h> (main.c, gui.c) is no longer needed
hope it will be of some use for someone...
Fri 7-Nov-2008 01:51
Wed 19-Nov-2008 16:37
Fri 19-Dec-2008 00:06
http://galway.c64.org/~sid/Kryo_Chiptune.sid
Thanks for the great inspiration!
Tue 27-Jan-2009 10:19
Wed 11-Feb-2009 07:12
Wed 11-Mar-2009 05:50
Sun 5-Apr-2009 01:51
Thierry C.
Wed 8-Apr-2009 19:53
Fri 8-May-2009 14:03
(project adapted on ATMega8, with a PWM with low-pass filter based "DAC").
Thierry C.
Fri 3-Jul-2009 03:54
Some other variations: using 9 colors of c64 video to create sound (with loud buzzing from vsync!), using sp of CIA (8bit autoshift register) to create stereo pwm dac (I never saw anyone else do this, they were always hooking up parallel dac0808).
One could make an exact sid replacement in microcontroller.
I always wanted to make a portable music toy to capture/compose musical ideas on the go .. like coffeeshop. Inspriation hits at odd times, sometimes upon waking.
Mon 3-Aug-2009 06:32
Sun 20-Sep-2009 22:34
Or some clear samples of it, I think this sounds gorgeous.
Apart from your technical genius you're a magnificent composer.
Good work.
Linus Åkesson
Sat 26-Sep-2009 19:05
Or some clear samples of it, I think this sounds gorgeous.
Apart from your technical genius you're a magnificent composer.
Good work.
Thank you very much!
If somebody would like to make a .mod or .xm cover, feel free to! For details, have a look at the original song, which is available in the tracker source code archive (in a special format that can be loaded into the tracker).
ijruiz@hotmail.com
Fri 9-Oct-2009 13:35
Wed 9-Dec-2009 02:17
at first i have to say: Great project and awsome tune!
I started to bulid one here at home but something is weird.
The controller seemed to run much to slow, so i switched to 8 mhz via ckdiv8 - now the contoller seems to run much faster... too fast... the tune is done in about 2 seconds...
Which fuse config did you use?
Greetz,
Retrobot0r
Wed 9-Dec-2009 20:41
at first i have to say: Great project and awsome tune!
I started to bulid one here at home but something is weird.
The controller seemed to run much to slow, so i switched to 8 mhz via ckdiv8 - now the contoller seems to run much faster... too fast... the tune is done in about 2 seconds...
Which fuse config did you use?
Greetz,
Retrobot0r
Got it. my compiler had produced some crazy stuff...
Sat 19-Dec-2009 23:34
at first i have to say: Great project and awsome tune!
I started to bulid one here at home but something is weird.
The controller seemed to run much to slow, so i switched to 8 mhz via ckdiv8 - now the contoller seems to run much faster... too fast... the tune is done in about 2 seconds...
Which fuse config did you use?
Greetz,
Retrobot0r
Got it. my compiler had produced some crazy stuff...
What was your fix? I'm still out of luck here.
Tried with CKDIV/8 and without.
Mon 21-Dec-2009 16:48
Tried with CKDIV/8 and without.
Fixed it by myself. The compiler optimization produced crazy stuff. Bad results with -O2 but compiling with -O1 has worked great for me.
Mon 21-Dec-2009 17:29
+++ gui.c 2009-12-21 17:23:46.000000000 +0100
@@ -625,16 +625,16 @@
case '>':
if(octave < 8) octave++;
break;
- case '[':
+ case KEY_PPAGE:
if(currinstr > 1) currinstr--;
break;
- case ']':
+ case KEY_NPAGE:
if(currinstr < 255) currinstr++;
break;
- case '{':
+ case KEY_HOME:
if(currtrack > 1) currtrack--;
break;
- case '}':
+ case KEY_END:
if(currtrack < 255) currtrack++;
break;
case '`':
This makes it a lot easier (at least for me).
You can change the current track with HOME and END keys
and change the instrument with PageUp and PageDown.
Hope that's okay for you, linus.
Great project - by the way. I've already started making tunes for your
platform.
Mon 21-Dec-2009 23:40
Linus Åkesson
Tue 5-Jan-2010 21:42
Oh, I guess it's more or less public domain. I like getting credit, but I won't try to enforce it legally.
By the way, under Swedish law there is no way for an author to release a work to the public domain, so you'll have to trust me. Copyright snafu. =)
Thu 14-Jan-2010 17:05
nice project but how to add own files (.wav,.mp3,pcm) can be added in it
Mon 25-Jan-2010 02:26
Linus Åkesson
Thu 28-Jan-2010 16:10
Thank you! No, there's no particular reason, but I haven't made any devices to play existing file formats. I'm sure it's doable, though. IIRC there's an AVR based MOD player and a Propeller based MIDI player around, and probably lots of similar projects.
Sat 30-Jan-2010 21:39
It uses the same microproccesor that you used for this project
Wed 3-Feb-2010 20:04
Now, I´m just an electronics technician apprentice but I hope I will be able to build this in the future *.*
Jesus its great!
Greetings
Chris
Mon 22-Mar-2010 09:54
Or some clear samples of it, I think this sounds gorgeous.
Apart from your technical genius you're a magnificent composer.
Good work.
or contact me via mynick_on_gmail, so i can send U final version or just patterns (this second one could be good to make remixes).
Linus Åkesson
Tue 23-Mar-2010 07:15
Or some clear samples of it, I think this sounds gorgeous.
Apart from your technical genius you're a magnificent composer.
Good work.
or contact me via mynick_on_gmail, so i can send U final version or just patterns (this second one could be good to make remixes).
Great cover! Rock on!
Wed 14-Apr-2010 20:58
i'm currently trying to do a simple replica of your project(on PC), but i have problems with callback. do you know books or web-pages where it's explained(how to make interrupt also).
many thanks.
Linus Åkesson
Sat 24-Apr-2010 18:55
i'm currently trying to do a simple replica of your project(on PC), but i have problems with callback. do you know books or web-pages where it's explained(how to make interrupt also).
many thanks.
If you are programming a PC application, you don't have to worry about interrupts. That's where a callback function becomes useful. You'd use a library such as libSDL, and provide a pointer to one of your own functions. This function will then get called back whenever new audio samples are needed. Please refer to SDL audio tutorials.
Mon 10-May-2010 20:25
Linus Åkesson
Thu 13-May-2010 15:32
By writing PCM samples directly to the port. The port pins are then connected to an R-2R ladder DAC.
Wed 2-Jun-2010 20:52
Just tried to build the Hardware Chiptune and flashed the atmega88 with the hexfile containing the tune.
My only problem is that some pins from the PortD just contain a signal sounding like fast random notes in the range of 10khz and above. Maybe it's a faulty atmega88 now caused by an accidental short between the input of the 7805 and PD7? Anyway I will get another atmega88 within the next few days to try out :)
Keep up your fantastic work!
Fri 4-Jun-2010 14:25
Linus Åkesson
Sun 6-Jun-2010 13:37
This sounds like a hardware problem, such as an accidental short between signals. It's also possible that it's caused by interference from a nearby AC signal, although if you're using a 7805 I don't see where the interference would come from. Also, if there's a break somewhere in the DAC ladder (e.g. faulty connection to ground), it could start to behave as an antenna and pick up interference.
Tue 8-Jun-2010 17:32
lft wrote:
This sounds like a hardware problem, such as an accidental short between signals. It's also possible that it's caused by interference from a nearby AC signal, although if you're using a 7805 I don't see where the interference would come from. Also, if there's a break somewhere in the DAC ladder (e.g. faulty connection to ground), it could start to behave as an antenna and pick up interference.I solved the problem, the resistor ladder I used was no R-2R one, now it works as ecpected :)
Fri 23-Jul-2010 09:27
-Primis
Sat 24-Jul-2010 18:34
-Primis
it's not a specific component you make it using a series of resistors ...
http://en.wikipedia.org/wiki/Resistor_ladder but it's easier to use the PWM trick mentioned earlier at least less parts. http://www.k9spud.com/traxmod/pwmdac.php
Tue 11-Jan-2011 03:59
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265488118
tested it and seems to work.
Excellent code linus :)
Sat 29-Jan-2011 14:58
Wed 9-Feb-2011 18:47
Mon 7-Nov-2011 12:17
Is there any difference between the ATmega88/168 that should be taken into account when working on this?
Thu 10-Nov-2011 01:51
i am not sure, but i think it's easier to generate a triangle wave with a DAC.
Sun 4-Dec-2011 13:30
Sun 25-Dec-2011 15:40
Sat 31-Dec-2011 21:39
I was trying to compile your project, but got stuck on the file exported.s.
How do I get the tracker to export that file?
Thanks,
Tobias
Sat 31-Dec-2011 21:44
For everyone else, its the % key :)
Great project,
Tobias
Mon 27-Feb-2012 08:48
Mon 27-Feb-2012 13:17
I'm currently studying your code and I can't figure out where does this "50 HZ" come from ?
"void playroutine() { // called at 50 Hz"
The routine runs in the main loop
"for(;;) {
while(!timetoplay);
timetoplay--;
playroutine();
}"
Please explain why is it triggered at 50 HZ ?
Thu 15-Mar-2012 19:04
Sun 20-May-2012 02:35
Sun 27-May-2012 10:32
I am currently working on a software synth of my own, but I kind of got caught up on mixing the different channels. How exactly do you mix them? Do you just calculate the average of all channels or just add them together?
Thanks for your help
Sat 14-Jul-2012 15:09
AMS
Fri 19-Oct-2012 00:39
Now the million dollar question...it looks like the Atemga controller I used (http://www.mouser.com/Search/ProductDetail.aspx?R=ATMEGA88PA-PUvirtualkey55650000virtualkey556-ATMEGA88PA-PU) is not supported directly by AVRDude? Any ideas on what might be required to get this working?
Mon 31-Dec-2012 08:05
--
Project is great :)
Wed 9-Jan-2013 05:45
Thu 17-Jan-2013 00:33
Riccardo
Max Porshnev
Thu 17-Jan-2013 06:44
Riccardo wrote:
Can you make a page where you explain the different kinds of waveformsSun 12-May-2013 11:33
The Hardware Chiptune Project is a work of Genuis!
I love your work and your website; I do hope you make other tunes with a similar orchestration in terms of the waveforms used. I hope to build something like this myself when I get the time. You're an inspiration!
Wed 17-Jul-2013 01:57
mporshnev wrote:
Riccardo wrote:
Can you make a page where you explain the different kinds of waveformsWed 26-Mar-2014 16:54
Kind regards
Dennis
Thu 4-Sep-2014 11:55
Oh, you got an old-school party in the non-US
That must be soo better than out dubsteps.
Wed 31-Dec-2014 00:14
bassdrum: the start frequency seems to be too low. so your bend-delta actually causes the frequency to go below zero and reverses the bend effect (so it goes upwards). I suspect that you originally meant to use an absolute tone in the instrument instead of a relative!
snaredrum: same stuff going on here... change note in instrument to be absolute instead of relative?
well - fact is that you build amazing stuff. Thanks for the inspiration!
Mon 13-Jul-2015 12:32
I tryied some programs (itunes,winhex,sox) but i have no success. Please help me! Thanks...
Max Porshnev
Wed 15-Jul-2015 10:27
I tryied some programs (itunes,winhex,sox) but i have no success. Please help me! Thanks...
Sun 8-Nov-2015 10:29
Tue 26-Apr-2016 14:58
Don't know if you still read postings here, but anyhow:
The tracker fills the SDL audiobuffer using the audiocb callback, which in turn calls the interrupthandler() routine. Given the current audio settings (16KHz / AUDIO_U8 / 1 channel) the interrupthandler gets 16K calls / second. The interrupthandler in turn calls the playroutine() method once every 180th call (callbackwait counter). To me this translates to an update frequency of about 89Hz for the tracker, not 50Hz as stated in the code. Am I all wrong or is the 50Hz comment in the source code wrong?
Thank you very much for these inspiring projects!!!
Fri 12-Apr-2019 06:42
Mon 14-Sep-2020 09:08
Wed 26-Apr-2023 14:52
just casually wrote an amazing tune in the morning, sure. This whole project is mind blowing to me