Dangerous Prototypes

In development => Project logs => Topic started by: Markus Gritsch on January 16, 2012, 02:18:05 pm

Title: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 16, 2012, 02:18:05 pm
Hi,

being inspired by another project of ChaN [1] I decided to build my own music box.  The theory is described in detail on ChaN's page, so I won't repeat it here.  Instead of an ATtiny, mine uses a PIC32 and has therefore enough processing power to play up to 64 notes simultaneously:

[attachment=5]
As a case I used a pair of cheap active speakers for the very competitive price of 3.50 €.  They can be seen here together with the breadboarded circuit:

[attachment=4]
Since I wanted to fit everything inside the speaker-case, the soldered circuit is quite minimalistic:

[attachment=3]
[attachment=2]
Here the inside of the case can be seen without and with my circuit installed:

[attachment=1]
[attachment=0]
A video of the device in action is available on YouTube: http://youtu.be/dt3rpgWyKno (http://youtu.be/dt3rpgWyKno)

Please find the source code attached to the next post, as there seems to be a limit of 6 attachments per posting.

Have fun,
Markus

[1] http://elm-chan.org/works/mxb/report.html (http://elm-chan.org/works/mxb/report.html)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 16, 2012, 02:18:37 pm
As promised, here is the source code.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Sjaak on January 16, 2012, 03:16:31 pm
1337 soldering skills ;)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: ian on January 16, 2012, 04:48:01 pm
Amazing work as always. The source is pretty simple, it looks like most work went into the audio conversion scripts.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 16, 2012, 04:59:19 pm
@Sjaak: Thanks.  It's not close to your QFN soldering skills, but sufficient for this basic stuff :)

@ian: It's always just a matter of getting the numbers right ;)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: sqkybeaver on January 16, 2012, 05:06:39 pm
dedbug lives!
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 16, 2012, 05:20:05 pm
Great! How can write other tunes?
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Sjaak on January 16, 2012, 05:21:25 pm
[quote author="Markus Gritsch"]@Sjaak: Thanks.  It's not close to your QFN soldering skills, but sufficient for this basic stuff :)
[/quote]

Haha also thanks ;)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 16, 2012, 08:53:33 pm
[quote author="Gianni"]Great! How can write other tunes?[/quote]
By taking a look into the source code :)  In the 'dds' folder you can find a script called 'midi2h.py'.  Prepare a nice MIDI file (stripping the percussion track for exampe is a good idea), and use the script to generate the data which you can put into the tune header file.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 16, 2012, 09:32:25 pm
Yes, I'm just looking at it now.. I'm new to python scripting.
I've tried to run midi2h.py with the still_alive.mid tune but the numbers script gave me are very different from those in the source code.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 19, 2012, 08:09:35 pm
I don't understand why the music on my prototype is played slower than the video... Schematic and code are the same...
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: voidptr on January 19, 2012, 08:25:24 pm
@Markus
awsome project !!! 
and it sounds pretty good too !
:-)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 19, 2012, 08:33:07 pm
[quote author="Gianni"]I don't understand why the music on my prototype is played slower than the video... Schematic and code are the same...[/quote]
Is it only slower or also deeper?  How much slower?  Twice as slow?  Are you using the exact same MCU?  Different MCU and different config bits for generating the clock?  Further: are you using the provided MPLAB X project, or have you created your own project? It must be compiled with -O1 to get 64 oscillators. What happens if you reduce to e.g. 32?
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 19, 2012, 08:46:03 pm
Twice as slow, and deeper. yes. I've created a new project using MPLAB IDE 8.80, MCU is the same.
If I use "OSCILLATOR_COUNT 32" works same as yours.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 19, 2012, 08:48:07 pm
Sorry!! Doesn't work exactly the same!!
I've Just put the optimization level to 1 and now works great!
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 19, 2012, 09:12:34 pm
Fine :)  Have fun!
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Gianni on January 19, 2012, 09:50:55 pm
I've understood how to use python script. I've modified it to put values on a file instead of the screen by adding
Code: [Select]
print >>fout 
where fout is a file pointer. With some midi is also useful to reduce the note duration by dividing time, example:
Code: [Select]
print >>fout, '    %s, %s,' % ( int( time )/3, int( pitch ) )
in this case I've reduced 3 times the note duration and the attached tune "Beethoven - For Elisa" sounds good. I've attached the tune and modified script. It would be great to load tunes from a thumbdrive.

[attachment=0]

[attachment=1]
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: colin.i on January 19, 2012, 10:31:03 pm
Nicely done
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Sleepwalker3 on January 20, 2012, 12:33:05 pm
Nice job!  Those speakers sound pretty good for cheapies, how do they sound with normal music?
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: craiglindley on January 20, 2012, 05:28:18 pm
Hello.

I find this project very interesting but I have a few questions. I've not looked at the code in detail yet but am planning to shortly. My questions are:

1. Are the waveforms in the wave tables sin waves? It doesn't sound like it. Are they square waves? If not what?

2. Are the envelopes applied when the midi files are processed or in real time during playback.

3. What are the envelope parameters: attack time?, decay time?

4. Are the envelope parameters the same for all notes?

Thanks for a great project
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: oPossum on January 28, 2012, 05:16:10 pm
Great project. The music box sound is excellent!

I was curious what the waveform and envelope looked like, so I plotted them...

This is the waveform. The last cycle is repeated for sustain.
[attachment=1]

This is the envelope. I wonder if this was calculated or derived from a sample.
[attachment=0]
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on January 28, 2012, 06:04:15 pm
The single sustain cycle is a calculated sinus wave.  The sample count was chosen so that no amplitude step is skipped: sample_rate / ( 256 * math.pi )

The attack waveform was taken from Chan's code and resampled to match the fundamental frequency of the calculated sine wave.

The envelope was also calculated using a decaying exponential function.  The time constant was chosen just to fill 1024 bytes, since single amplitude steps at the beginning would have led to too much bytes to reach 0, and they cannot be heared anyways.

All the details for generating the data can be found in the 'dds' folder.  The file 'dds.py' is your friend.

Have fun,
Markus
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: apolo8 on February 28, 2012, 08:52:55 pm
Wow...!!! Sound is really nice there!!!

First off,sorry for my bad english,I'll try my best...

-Even I'm a loooong time background DP reader,I've just registered over here to let you know How much IMPRESSED you left me with the =Really Good Quality Sound of your Synth=.

Thank you very much for posting!!!
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: apolo8 on March 08, 2012, 01:30:36 pm
Would it be too difficult,instead of playing a melody,play some musical notes? p.e-nine musical notes...for a homemade e-drum or a keyboard...That would be Great if we can change the notes for different instruments!


Un Saludo...
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on March 14, 2012, 08:23:39 am
[quote author="Markus Gritsch"]The single sustain cycle is a calculated sinus wave.  The sample count was chosen so that no amplitude step is skipped: sample_rate / ( 256 * math.pi )

The attack waveform was taken from Chan's code and resampled to match the fundamental frequency of the calculated sine wave.

The envelope was also calculated using a decaying exponential function.  The time constant was chosen just to fill 1024 bytes, since single amplitude steps at the beginning would have led to too much bytes to reach 0, and they cannot be heared anyways.[/quote]
I wonder if you could improve upon the original. It seems that you might have already made some changes. My first impression was that the sustain seems different than a mechanical music box, and I guessed that maybe the decay was linear rather than exponential. But, you can it's exponential, so maybe it just seems that the decay lasts too long. I searched for some recordings of vintage music boxes, and I think the decay is faster. Then again, maybe there are a wide variety of sounds out there.

Great work! I'm just making suggestions in case you want to fine tune this thing.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on March 14, 2012, 09:09:29 am
In nature, virtually nothing decays linearly.  Most things degrade to an exponential rate.  Maybe the time constant of the exponential decay of a real music box is shorter, but then as you said, there are probably many different sounding music boxes out there, and mine has per definition a low damping factor ;)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on March 14, 2012, 12:32:55 pm
Ah, I should have said that I thought the virtual music box might have sounded strange because it had a linear decay. I know that our ear's response to sound intensity is not linear.

Would it be possible to make the decay variable?
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on March 14, 2012, 12:44:49 pm
Sure. The envelope table is precalculated, so just change the time constant in line 1939 of dds.py.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on March 16, 2012, 09:57:06 am
I searched for some random music box videos on YouTube, and IMO some of them have a relatively long sustain period.  For example if you listen to this one http://www.youtube.com/watch?v=OiRvvJjzXs4 (http://www.youtube.com/watch?v=OiRvvJjzXs4) at position 0:30, you can hear about 4 seconds of sustain -- about the same time I choose in my code.

I agree, that such a long sustain time creates a bit of a "smeared" sound.  I have attached two versions of "Linus & Lucy" played with my music box code, one with the long sustain setting (dds_env7.mp3), and one with a shorter one (dds_env6.mp3).  The files are zipped because .mp3 is not allowed as an extension by this board.  The bitrate is also only 64 kbit/s to get below the maximum file size of 1 MB.  Enjoy :)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on April 17, 2012, 12:16:50 pm
I don't know if it's relevant, but the music box only has one "oscillator" per pitch, so if a specific note starts again while it is still sustained, then the existing sound should be replaced/restarted. I haven't looked at your code to see whether you're accounting for this, but it might affect the accuracy of the sound in a subtle way.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on April 17, 2012, 12:23:42 pm
Yes, you are right.  I also thought about this, and the current implementation does not accout for this, i.e. triggering a new note of the same pitch will get another envelope on a new oscillator running.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on April 17, 2012, 12:26:55 pm
Now that I listen again to your original build, the sustain doesn't seem wrong any more. Maybe that's because this time I listened to the real thing in your link, but last time I listened to some very different acoustichanical music boxes with much shorter sustain.

What I'm hearing now is that the tines sound more wooden than metal, both old and new code. I'm not sure what you could do to make them sound more metallic - perhaps it's merely that the sample rate is too low for the higher overtones of a metal tine. I suppose there might also be some part of the algorithm that imparts a wooden or metallic timbre. I do know that there are digital audio synthesizers with separate algorithms for wood, metal, glass, and nylon. I just don't know whether the core code changes or if it is merely a few parameter values that change between each of these sounds.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on April 17, 2012, 12:29:53 pm
[quote author="Markus Gritsch"]Yes, you are right.  I also thought about this, and the current implementation does not accout for this, i.e. triggering a new note of the same pitch will get another envelope on a new oscillator running.[/quote]
I assume that you have a finite number of oscillators, and that a new note starts by picking an oscillator before making any changes. In other words, if more notes are sounding than there are oscillators, then something has to be dropped (the oldest note?). If that is the case, then you could modify that section of code to compare the pitch and pick a running oscillator if the pitch is the same. Of course, if you're really fancy then you could have one oscillator per note, like a real music box, but I bet that would require too much cpu (or too much optimization in assembly!).

EDIT: I see that you have 64 notes (or only 32 if not optimized by the compiler). I don't have the patience to count precisely, but there might be 72 tines on the latest music box link you provided. Since most synthesizers have some intelligence in the voice allocation algorithm, it might be worth a little extra effort to try a few changes.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on April 17, 2012, 12:43:01 pm
The sustain-part of the waveform is a pure sine wave, without any over-tones.  Surprisingly this approximation sounds *quite* like a music box tone.  Of course it could be improved by using more sample-memory and include several real samples for different pitch-ranges.  However, my task here was not to rebuild a professional sounding sampler, but to have some minimalistic implementation which sounds good enough.

In the original posting I already wrote that 64 oscillators are used.  With this amount of potentially simultaneous playing notes the oldest ones have already ended their sustain-envelope before they get reused by more recent notes.  This is true for both example tunes.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on April 19, 2012, 04:07:36 am
[quote author="Markus Gritsch"]The sustain-part of the waveform is a pure sine wave, without any over-tones.  Surprisingly this approximation sounds *quite* like a music box tone.  Of course it could be improved by using more sample-memory and include several real samples for different pitch-ranges.  However, my task here was not to rebuild a professional sounding sampler, but to have some minimalistic implementation which sounds good enough.[/quote]
My favorite hobby is sound synthesis, so forgive me for being so detailed. The sine sustain is perfect, most harmonics have died by the time the attack is done.

I think that the only reason the tines sound "wooden" is that the low frequencies are under-sampled. The higher notes sound very metallic to me, and quite good.

Quote
In the original posting I already wrote that 64 oscillators are used.  With this amount of potentially simultaneous playing notes the oldest ones have already ended their sustain-envelope before they get reused by more recent notes.  This is true for both example tunes.
Not to be too picky, but have you confirmed this? It seems that you could analyze the MIDI file to see how many simultaneous notes are playing. That would be very easy without considering the sustained notes, and maybe not even that difficult if you calculated the end of the note based on duration. Then again, you could just alter your firmware to turn on an LED any time a note is started on an oscillator that hasn't finished sustain, and that would be definitive.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on April 19, 2012, 08:02:54 am
[quote author="rsdio"]Not to be too picky, but have you confirmed this?[/quote]

Having everything I say being questioned it getting a bit tiresome.  Of course I have tested how many oscillators were necessary to not cut off any sustain region.  Otherwise I would not say so.

May I suggest that you please take a look at the source code the next time before raising another speculation?  It's everything there.  For example in dds/dds.py line 1951 and 1976 the testing for truncation is done.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: rsdio on April 19, 2012, 07:27:07 pm
[quote author="Markus Gritsch"][quote author="rsdio"]Not to be too picky, but have you confirmed this?[/quote]
Having everything I say being questioned it getting a bit tiresome.  Of course I have tested how many oscillators were necessary to not cut off any sustain region.  Otherwise I would not say so.

May I suggest that you please take a look at the source code the next time before raising another speculation?  It's everything there.  For example in dds/dds.py line 1951 and 1976 the testing for truncation is done.[/quote]
I tried to apologize in advance for all of the questions, but I guess I did not make that clear.

My involvement with this project is at a very high level, and I don't really have the time to read the source code for every interesting project out there. That much work would feel like a code review, which would be a significant endeavor. I had hoped that we could discuss this at a high level and that you would be interested in the discussion. You always have the option of ignoring me :-)

Having not seen the source, I made the assumption that the music file was separate from the source code. In other words, I didn't think that it would be possible to count to number of simultaneous notes in the "song" based on the source code alone. I figured something like a MIDI file was being used. At any rate, I would not easily be able to analyze the polyphony based on source code, whereas it would be more likely to find an existing tool that would read a MIDI file.

Primarily, though, I thought you were at least somewhat interested in figuring out why the sound is slightly off. On the one hand, you say you're not worried about perfect quality - which is certainly fine - but at the same time it seems like there might be the possibility to discover an easy way to improve the quality without a lot of effort. Based on what I hear, if you could somehow increase the sample rate of the lower notes, then I think they'd sound as good as the higher notes. But admittedly that might require a change to the algorithm. Again, the high frequencies sound very realistic (to my ears) when compared to a mechanical music box.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on April 19, 2012, 08:47:08 pm
[quote author="rsdio"]
Primarily, though, I thought you were at least somewhat interested in figuring out why the sound is slightly off.
[/quote]

That's because
A. The sustain part of a real music box is certainly no pure sine wave, but does contain overtones to some degree.
B. When picking a metal-pin in a real music box, all the other pins get excitet a bit due to mechanical and acoustic coupling.  Similar to the stings of guitar or in a piano.
C. A real music box has a resonant-body.

None of the above stuff is taken care of, so it will certainly not sound like a real music box which never was my intention anyways.  I did it the other way round: I tried how this extremely short pick-sound attack-waveform together with the pure sine-wave sustain part sounded, and it was surprisingly similar to a music box.  Maybe I shouldn't have included the term music box in the title of this posting ;)

[quote author="rsdio"]
Based on what I hear, if you could somehow increase the sample rate of the lower notes, then I think they'd sound as good as the higher notes.[/quote]

All notes are sampled at the same sample rate.  This is how DDS works.  In fact the lower notes are an even more perfect sine wave than the higher ones, for which fewer samples from the basic waveform can be taken to achieve the higher frequency.  Maybe you perceive the higher notes more metallic due to more missing sample values from the sine wave.  Who knows.

For more information read the Wikipedia entry about DDS or try to understand the source code.  Here you have it, I suggested it again ;)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: BrianGriffin on April 30, 2012, 11:07:50 am
Dear Markus,

I like the port of that project to the PIC32. It's amazing. Keep it up.

If you put it in a wooden box and that magnetic plastic ballerina inside, you can actually fool someone that this is the real thing! :)
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Nogginboink on May 12, 2012, 12:14:05 am
I realize this thread is a bit old, but I'm trying to understand the code and how this project works. For the functionality you get out of it, the project is remarkably simple, both in hardware and in software. I'm quite impressed.

Is the PWM module simply being used as a crude DAC? I'm used to seeing an RC low-pass filter on the output of the PWM when this is done; does this circuit simply do away with the filter? Or is the PWM being used for some other purpose entirely?

Second question: what's the math behind the TICKS_LIMIT definition? I expected to see a regular interrupt in which the oscillators are updated, but it's done entirely within the while(true){} loop inside main(). Did instruction counting come into play here? Does TICKS_LIMIT have to change when OSCILLATOR_COUNT changes?

I'm going to see if I have any PIC32 parts on my workbench when I get home and if so, play with this. This is a really slick project and I want to understand how the darned thing works.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: Markus Gritsch on May 13, 2012, 09:16:09 pm
[quote author="Nogginboink"]
Is the PWM module simply being used as a crude DAC? I'm used to seeing an RC low-pass filter on the output of the PWM when this is done; does this circuit simply do away with the filter?
[/quote]
Yes, the PWM is used as a DAC.  Since the speaker itself has a cutoff frequency, and the PWM frequency of 39062 Hz is way above this frequency, there is no need for a RC filter.

[quote author="Nogginboink"]
Second question: what's the math behind the TICKS_LIMIT definition? I expected to see a regular interrupt in which the oscillators are updated, but it's done entirely within the while(true){} loop inside main(). Did instruction counting come into play here? Does TICKS_LIMIT have to change when OSCILLATOR_COUNT changes?
[/quote]
No instruction counting.  The loop over all oscillators has to be finished before the next sample must be written to the PWM register.  So if OSCILLATOR_COUNT is reduced, nothing has to be changed.  If it is increased, the sample rate must be reduced.  After every PWM update, a tick counter is increased.  TICKS_LIMIT is there to advance to the next time event of the midi file.
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: ondeugd on June 21, 2013, 10:10:38 am
It's an old post but I'm trying to get some answers anyway.
Too cool a project to give up now :-)!

Your code is explicitely disabling jtag (JTAGEN = off in DEVCFG0).
My programmer is using the jtag interface, so I only could get the code in the pic by changing the hex to have JTAGEN = on. the jtag pins have nothing to do with the pins that are used by your code, so I assumed this would be allright.

Wired the whole thing like shown in the schematic, and attached my oscilloscope to pin 26, but the thing just doesn''t seem to be doing anything however.

Tried to find out from the datasheets etc if the enabling of the jtag interface is messing up the working of your code, but can't find anything. I'm not the best pic programmer by far though, only had some leds blinking on the pic32 till now, so I might be missing something...

So could you please shed a little light on this? Any chance my changed JTAGEN setting is messing my thing up?
And to be clear: just hooking up the battery should get the thing running wouldn't it?
Title: Re: Music Box / Wavetable Synthesizer / DDS
Post by: yerpa58 on June 24, 2013, 09:29:50 pm
to ondeudg,

I recently built a version of this project, too.  I'm using a PICkit3 to program.  I tried turning JTAG=ON in the code, and it still ran just fine.  My board only runs at 40 MHz, though, probably due to the wrong kind of capacitor on pin 20.  To make it run, I had to change the FPLLODIV = DIV_1 line to be FPLLODIV = DIV_2, and also changed OSCILLATOR_COUNT from 64 down to 32.

I also had to use compiler optimization level 1 or higher to get good fidelity.

Then it ran, one octave lower and half speed, but still a very cool project.