Go Down

Topic: Amiga MOD Player on Arduino Uno (Read 2 times) previous topic - next topic

JarkkoL

Turned my 8-bit resistor DAC into a 4-channel Amiga MOD player during the weekend. It's been awhile I wrote my last MOD player :D More details in the Youtube description.

http://www.youtube.com/watch?v=zSQ0eHjO4sk

fungus

Cool!

Maybe you can do it without the resistor-DAC: http://www.atmel.com/Images/doc2542.pdf

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

JarkkoL

Yes, you would need to add capacitor for low-pass filtering though. I'm not quite sure what PWM signal at 16MHz would do to the frequency response though, i.e. is it enough to be able to render close to ~20KHz signals with reasonable accuracy. That would be an interesting experiment though!

cr0sh

Will you be sharing the source/schematics/etc for this later? Seems pretty neat!

Have you seen this guy's stuff (not Arduino):

http://www.linusakesson.net/scene/craft/

...even so, an ATMega88 is not too far off in specs from a 328 - so in theory, one could port such code over...
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

JarkkoL

I don't have the schematics, but the player is pushing the audio data to Arduino Uno pins 0-7, and blinking the LED's in pins 8-11.

In the attachment is the code for both MOD player and converter. Converter can be a bit tricky to get to compile since I coded it using the library I have built over the years, which you would have to download & compile, so I also added an exe you can use if you are on Windows platform. There are 3 example tunes in the player though which you can try. The uncommented tune is the one in the video.

mod_player::mix_buffer_batch() is the function doing the heavy lifting of mixing the channels together, and GCC doesn't seem to be doing very good job optimizing the C++ code. It should be fairly easy to write the code in asm for much better performance, which would allow using more channels and higher sampling frequency. Also the mod_player::timer_interrupt() seems to be pretty poor and writing it in asm should also help. I liked to keep the code in C++ so far to keep it more portable, but if someone likes to write optimized asm version for Uno, that would be great (:

martin_bg

Impressive!
You sent me back to 1994 for a minute :)

Lakes

Portable Amiga Mod Player! :D

I still have a collection of my fav amiga mods stored away in the depths of this hard drive somewhere. :)

fungus


Yes, you would need to add capacitor for low-pass filtering though. I'm not quite sure what PWM signal at 16MHz would do to the frequency response though, i.e. is it enough to be able to render close to ~20KHz signals with reasonable accuracy. That would be an interesting experiment though!


Oh, I just saw paper is only for 'Tinys. You can't run the Atmega328 timers at 64MHz like you can on a Tiny.


No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

#8
Jul 29, 2013, 10:13 pm Last Edit: Jul 29, 2013, 10:16 pm by PetriH Reason: 1
Well done Jarkko! Ace stuff as usual.

I have something in the works too... wait for it! ;-)

p.s. wouldn't you need to have a capacitor after the DAC to center the audio signal around zero level? Something I've been wondering for a while when doing audio out...


JarkkoL

#9
Jul 30, 2013, 06:50 pm Last Edit: Jul 30, 2013, 06:54 pm by JarkkoL Reason: 1
Hey Petri, didn't know you are toying with Arduino as well. Can't wait to see what you are working on! (:

To my understanding line-in voltage is DC not AC. People use caps after DAC for low-pass filtering though. I tried 1uF, .1uF and .01uF caps but didn't really hear any difference, though could be I did something wrong. Having an oscilloscope would help (:

#10
Jul 30, 2013, 09:12 pm Last Edit: Jul 30, 2013, 09:14 pm by PetriH Reason: 1
At least according to Wikipedia http://en.wikipedia.org/wiki/Line_level
"The line level signal is an alternating current signal without a DC offset, meaning that its voltage varies with respect to signal ground from the peak amplitude (for example +1.5 V) to the equivalent negative voltage (-1.5 V)."

btw. did you try the cap in series or between line out and gnd? When removing the bias the cap is placed in series while in the RC low-pass filter the cap is placed across out and gnd. I think having both caps would improve audio quality (at least when inspeced with an oscilloscope!).

This tutorial has some nice oscilloscope pictures showing the difference with and without caps:
http://www.instructables.com/id/Arduino-Audio-Output/?ALLSTEPS

And yeah, I've been planning to buy an oscilloscope for a while too :)

JarkkoL

Thanks, that's a good article! I had the cap between line out & gnd for low-pass filter. Didn't know you could use a cap for offsetting as well.

JarkkoL

#12
Aug 12, 2013, 06:40 pm Last Edit: Aug 13, 2013, 02:30 am by JarkkoL Reason: 1
Did some improvements to the music player:

Now it's able to play this 12 channel tune @ 37KHz due to some hand written assembly code and changing the way channels are mixed. Good AVR asm learning exercise (:

JarkkoL

Now the player supports also XM and IT formats, has instrument volume envelope support, and better compression of pattern data. I ported it to Teensy3 as well but the resistor DAC performs quite poorly on it, so I think I'll need proper DAC for it


Go Up