ff-ad9833: Added Für Elise Demo

I added this tune to the demo-melodies.fs file:

Für Elise (first half) played with ff-ad9833 code

My apologies to the Beethoven fans as I had to do some violence to the tune in order to make it monophonic and to fit it inside the 3 octaves provided by my code. I also had to apply some filtering to the recording to try to remove background noise in my apartment.

Here is the tune in source code:

create furelise-p1
d_16th ne  o5 == d_16th nd# o5 == d_16th ne  o5 == d_16th nd# o5 ==
d_16th ne  o5 == d_16th nb  o5 == d_16th nd  o5 == d_16th nc  o5 == 
d_8th  na  o5 == d_16th nr  nr == d_16th nc  o4 == d_16th ne  o4 ==
d_16th na  o5 == d_8th  nb  o5 == d_16th nr  nr == d_16th ne  o4 ==
d_16th ng# o4 == d_16th nb  o5 == d_8th  nc  o5 == d_16th nr  nr ==
d_16th ne  o4 == d_16th ne  o5 == d_16th nd# o5 == d_16th ne  o5 ==
d_16th nd# o5 == d_16th ne  o5 == d_16th nb  o5 == d_16th nd  o5 ==
d_16th nc  o5 == d_8th  na  o5 == d_16th nr  nr == d_16th nc  o4 ==
d_16th ne  o4 == d_16th na  o5 == d_8th  nb  o5 == d_16th nr  nr ==
d_16th ne  o4 == d_16th nc  o5 == d_16th nb  o5 == end-score

create furelise-p2 d_quarter na o5 == end-score

create furelise-p3
d_8th  na o5 == d_16th nr nr == d_16th nb o5 == d_16th nc o5 ==
d_16th nd o5 == end-score

create furelise-p4
d_dt-8th ne  o5 == d_16th ng  o4 == d_16th nf  o5 == d_16th ne  o5 ==
d_dt-8th nd  o5 == d_16th nf  o4 == d_16th ne  o5 == d_16th nd  o5 ==
d_dt-8th nc  o5 == d_16th ne  o4 == d_16th nd  o5 == d_16th nc  o5 ==
d_16th   nb  o5 == d_16th ne  o4 == d_16th ne  o5 == d_16th ne  o4 ==
d_16th   ne  o5 == d_16th ne  o4 == d_16th ne  o5 == d_16th ne  o4 ==
d_16th   ne  o5 == d_16th ne  o5 == d_16th ne  o6 == d_16th nf# o4 ==
d_16th   ng  o4 == d_16th nd# o5 == d_16th ne  o5 == d_16th nf# o4 ==
d_16th   ng  o4 == d_16th nd# o5 == d_16th ne  o5 == d_16th nd# o5 ==
d_16th   ne  o5 == d_16th nd# o5 == d_16th ne  o5 == d_16th nb  o5 ==
d_16th   nd  o5 == d_16th nc  o5 == d_16th na  o5 == d_16th ne  o4 ==
d_16th   na  o4 == d_16th nc  o4 == d_16th ne  o4 == d_16th na  o5 ==
d_16th   nb  o5 == d_16th ne  o4 == d_16th ng# o4 == d_16th ne  o4 ==
d_16th   ng# o4 == d_16th nb  o5 == d_16th nc  o5 == d_16th ne  o4 ==
d_16th   na  o4 == d_16th ne  o4 == d_16th ne  o5 == d_16th nd# o5 ==
d_16th   ne  o5 == d_16th nd# o5 == d_16th ne  o5 == d_16th nb  o5 ==
d_16th   nd  o5 == d_16th nc  o5 == d_16th na  o5 == d_16th ne  o4 ==
d_16th   na  o4 == d_16th nc  o4 == d_16th ne  o4 == d_16th na  o5 ==
d_16th   nb  o5 == d_16th ne  o4 == d_16th ng# o4 == d_16th ne  o4 ==
d_16th   nc  o5 == d_16th nb  o5 == end-score

create furelise-p5 d_dt-quarter na o5 == end-score

That occupied 326 bytes of memory, which was the score bytes along with the bytes needed for the word headers (furelise-p1, etc.) It was divided into five parts to save memory, since some of the parts are repeated.

Free software source code and documentation are available here:

https://codeberg.org/infrared/ff-ad9833

ff-ad9833 project: musical notes and melody system implemented

ad9833-based audio module

I added two modules to my ff-ad9833: one called notes which handles playing music and rest notes, and another called score which provides a convenient way to lay out a melody of notes in memory and to play them at an arbitrary tempo. My first simple demo is the “Are You Sleeping” tune:

I defined some Forth words such that it is fairly natural to lay out the notes in a memory block. This is what “Are You Sleeping” looks like in Forth code:

flash

create rusleeping
d_quarter nc o5 == d_quarter nd o5 == d_quarter ne o5 == d_quarter nc o5 ==
d_quarter nc o5 == d_quarter nd o5 == d_quarter ne o5 == d_quarter nc o5 ==
d_quarter ne o5 == d_quarter nf o5 == d_half    ng o5 ==
d_quarter ne o5 == d_quarter nf o5 == d_half    ng o5 ==
d_8th     ng o5 == d_8th     na o6 == d_8th     ng o5 == d_8th     nf o5 ==
d_quarter ne o5 == d_quarter nc o5 ==
d_8th     ng o5 == d_8th     na o6 == d_8th     ng o5 == d_8th     nf o5 ==
d_quarter ne o5 == d_quarter nc o5 ==
d_quarter nc o5 == d_quarter ng o4 == d_half    nc o5 ==
d_quarter nc o5 == d_quarter ng o4 == d_half    nc o5 ==
d_half    nc o5 == d_half    nr nr == d_half    ng o4 == d_half    nr nr ==
d_whole   nc o5 == d_8th     nc o5 == end-score

ram

Each note, including duration, pitch, and octave, is packed automatically into one 16-bit memory cell, so that not a lot of memory is used.

This music system is not really sophisticated enough to use for something like a video game console, since the ad9833 does not have ADSR envelopes or anything like that. But perhaps it would be useful for something like a simple toy, or part of the interface of some appliance.

It has been a lot of fun coding these modules, as well as writing the comment documentation. I developed my own source code documentation standard for the project to keep the code documentation clean and organized.

I learned in the process about the reuse software, which has a nifty reuse lint command which helped me in placing proper licensing and copyright documentation in all my code files. Most free software coders I have come across think very little, if at all, about proper code licensing details. But it is important to make the licensing clear, and clear on all files in the project, so as to make it easier for others to reuse, modify, and share the code with confidence.

While this component of the project is nearly complete, I had thoughts of adding one more demo tune — something longer and more sophisticated. As far as the ff-ad9833 project itself, I had thoughts of adding one more module for generating Audio FSK data communication capabilities. Like, for amateur radio RTTY.

The code for the ff-ad9833 project is available to download from this repository:

https://codeberg.org/infrared/ff-ad9833

In the picture at the top of this post, the audio module is being powered by the Arudino UNO 5V VCC pin. However, it is better instead to power the audio module from a separate 5V power supply (at least 3W). You can then tie the DGND pin on the audio module to a GND pin on the UNO, and also tie the other GND pin on the UNO to the ground or negative lead on the 5V power supply. In my experiments, this resulted in more stable audio module operation, as well as cleaner sound at the higher volume levels.

I think, if I were redesigning my audio module, I might also utilize a diode to prevent current from rushing back from the audio module into the UNO. I’m not quite sure if that is really necessary, but it seems like a good idea.