Music by PWM on AVR

Discussion in 'The Projects Forum' started by John McMahon, Dec 26, 2011.

  1. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    I intend to use PWM on an AVR microcontroller to create musical notes. Each note would not be just a pure tone, but a mixture of several frequencies. For each note, the code would initially see the frequencies to be mixed and their relative amplitudes, then create a table of bytes. In response to inputs, bytes for the various notes would be streamed to the PWM output. Is this possible, or is there a better way to accomplish this? I’m new to AVR and C (my experience is with C#).

    John McMahon
    Honolulu Hawaii
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    Which AVR chip are you planning on using? You can generate single musical notes using PWM. It will be a bit more difficult to combine notes of different frequencies unless you use multiple PWM outputs. It will also be difficult to control the relative amplitudes without using additional resources or circuitry.
     
  3. Wendy

    Moderator

    Mar 24, 2008
    20,766
    2,536
    I do not know this for certain, but I suspect you can use an AVR to record with, and output the recording. It will require lots of memory (not so much by modern standards). I am under the impression this describes many MP3 player designs.
     
  4. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    The ATtiny26 is mentioned in Atmel’s application note at http://www.atmel.com/dyn/resources/prod_documents/doc2542.pdf, but any chip with one or more PWM outputs and enough memory would do, as far as I know. I think some chips have multiple PWM outputs, but I want to stay under 40 pins so that I can use my STK200.

    The app note describes using a table to provide the instantaneous values to use for the sine wave, but of course the table could provide values for any wave shape, including multiple combined audio sine waves. The chip would fill the table first, based on the audio frequencies it’s told to mix. Only a short sample (which would be repeated for playback) would be needed.

    Would the table be in the form of an array? I'm new at C, and don’t know of any other way in C to create what Atmel’s app note refers to as a “table”.

    I don’t intend to record sounds, but just produce them using lookup tables.
     
  5. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    A look-up table is an array.

    It would be helpful if you described fully what you are trying to accomplish.
    Are you trying to play a musical tune one note at a time, midi style?
    Or do you want to play polyphonic music, i.e. notes as well as chords?
    Why do you want to generate sine waves?
     
  6. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    If you are trying to make a "Birthday card tune" with a piezo, it is pretty straightforward.

    If you are trying to synthesize strings and a range of percussion instruments, then you need true samples to mix, as they cannot be realistically re-created without sampling.
     
  7. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    Have a look at Roman Black's BTc sound compression algorithm:
    http://www.romanblack.com/BTc_alg.htm

    and his BTc sound encoder:
    http://www.romanblack.com/picsound.htm

    The sound quality is not great, but unless you have lots of memory and a good bit of computing power, it'll be difficult to get any kind of decent sound quality.

    The first computer game I bought that had sound (voices) and music was "Galaxy Invasion" by Big Five Software, released in 1980. It was impressive that it made sound, as the TRS-80 Model I didn't even have a speaker! :eek: They got it to make sounds by switching current to an internal relay on and off; the relay was there to control a cassette tape deck which programs and data were saved to and loaded from.
    A bit about the game: http://www.trs-80.org/galaxy-invasion/

    Speaking of using non-speaker devices for producing sounds/music, you will probably find this YouTube video highly entertaining:
    http://www.youtube.com/watch?v=Nrp1PALeWCI&feature=related

    And the Imperial March: http://www.youtube.com/watch?v=qWkUFxItWmU&feature=related

    A seasonal medley: http://www.youtube.com/watch?v=LAgYrTGfFVE&feature=list_related&playnext=1&list=SP36C5EBE91FEA5146
    Well worth a listen.

    This one is not to be missed! http://www.youtube.com/watch?v=dmoDLyiQYKw&feature=related
     
    Last edited: Jan 3, 2012
  8. Wendy

    Moderator

    Mar 24, 2008
    20,766
    2,536
    Interesting, I still have my TRS80 with the expanded BASIC package and 16K of RAM. Do you? I used to use an AM radio next to the old machine for sound effects. (AM splatter)

    I have read more than one place that extra RAM could be added to a lot of those chips. It may be needed here.
     
  9. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    I did, up until a year ago. I donated it to a technical college here.
    I had three 5-1/4 floppies and a ton of disks for them.
    I had a Lobo Drives expansion interface, and ran the LDOS operating system. I couldn't run TRSDOS or DrDOS with the LDOS expansion interface, but that was OK with me - LDOS was like a Cadillac operating system anyway.

    I also gave away my TRS-80 Model 4P. Hadn't used either of them for years.
     
  10. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    That's very interesting about the floppy music.

    I’m trying to create a 6-output polyphonic instrument (similar to a 6-string instrument, where each string could play one of numerous possible notes). Each output would be produced on its own PWM port. The six outputs would be mixed by some resistors and an op amp before going to the audio amp and the speaker.

    It doesn’t need to sound realistic, and it won’t. But I also don’t want pure tones (a simple sine wave), and so I’d like each note to include some harmonics.

    There’ll be numerous notes to produce, and so there’ll be numerous lookup tables.

    So there’ll be 6-note chords. Touch sensors will detect when each “string” is played, and there’ll be other means to know which notes to play.
     
  11. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    It would be difficult to produce sine waves with harmonics for timbre using PWM. A more likely solution is to do everything digitally using a faster MCU such as a DSP chip, summing all notes and harmonics and outputting to a single DAC. There are special DSP or ARM chips that are designed specifically for sound processing. For high quality sound, you want to be able to generate DAC points at 40kHz rate. This means that you have 25us to do all your processing. This is doable with a DSP but might be pushing a simpler MCU.

    If you want to proceed with a simpler AVR MCU, I don't think PWM is the proper approach. I am not aware of any MCU that has as many as 6 PWM outputs. The simplest solution I can think of is to use 6 outputs in simple toggle mode and sum the 6 using resistors and an opamp as you originally planned. Here you are limited to simple square wave outputs and you have no control over amplitudes. I bet that the sound would not be too bad. It would be a fun project and you can learn a lot from it.
     
    Last edited: Jan 4, 2012
  12. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    I shall bow down to that sort of creativity. Awesome.
     
  13. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    DSP’s are beyond what I have time for, unfortunately.

    I think an ATtiny can handle this (or rather, 6 ATtiny’s can). If I correctly understand Atmel’s app note (http://www.atmel.com/dyn/resources/prod_documents/doc2542.pdf), an ATtiny can process points from a lookup table and put them to a PWM port quickly enough to create a sine wave of an even higher pitch than we can hear. To mix various frequencies, the heavy duty processing time is in creating the lookup table, which is done in advance, not when it’s playing music.

    The lookup table could for instance contain all the points for a single wave that’s a composite of 440 Hz, 880 Hz, 1320 Hz, and 1760Hz sine waves, perhaps with the most amplitude on the 440 Hz. Then the ATtiny could produce that sound with as little processing as it would use to produce a single-frequency sine wave. Within the audio range, it doesn’t care how complex the waveform is.

    There need to be 12 lookup tables, for the 12 notes in an octave. Notes in the other octaves can be obtained by varying the prescaler.

    One ATtiny would be one “string”. It could play any note and would have its own attack/decay times. The 6 ATtiny PWM filtered outputs would be mixed by an op amp. Together, they create the chord.

    Do you know of any reason why this wouldn’t work?
     
  14. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    I question most of what you have said.

    1) I would not use 6 ATtinys. I would choose a single MCU with enough speed and resources to get the job done. It does not have to be a DSP. There are some fairly fast MCUs (80MHz clocks or higher) on the market today.

    2) I question why you wish to use PWM. To do so to generate a sine wave would require a fast processor and a very effective low pass filter to remove the PWM clock signal.

    3) I question why you wish to produce a sine wave. If you wish to keep it simple and get things working quickly a square wave would work. However, if you do not like the sound of a square wave and would prefer a signal with more pleasant tonal qualities you can use a lookup table of an arbitrary waveform. You do not need to store an entire cycle. A quarter cycle consisting of 10 samples would do. A complete cycle would require only about 40 samples.

    4) You do not need 12 lookup tables. One table would work. All notes in the scale in any octave can be generated from the single wave table.

    5) Two difficulties will be how to generate multiple notes and how to control amplitudes. The only solution I can think of is to use an internal or external DAC. One would have to either do the math or experiment to determine how much processor speed is required to generate the output on the fly.

    6) Instead of a DAC or PWM, one can use delta-modulation.
     
    John McMahon likes this.
  15. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    A lot of the unpleasantness of a square wave can be removed by running it through a series 100uH inductor with a 0.47uF cap to ground. It won't attenuate the signal too much, but will make the output more pleasant.
     
  16. PaulEE

    Member

    Dec 23, 2011
    423
    32
    As far as time, I could see why you'd use six separate chips...
    1) One per "string"
    2) Exact code on each, most likely more simple than the code that would be on a more powerful chip
    3) By breaking the function of the powerful chip up into six separate ones, you can fine-tune each chip to do something slightly different if need be
    4) Buying a bunch of cheap chips might be cheaper than one big powerful one..?

    I hate to go back to the stone age but can't help myself...I've seen Johnson Counters and resistors used to create crude sine waves. The resistors coming off each of the flip-flop outputs are summed together and outputted through an op-amp. In this way, the overall impedance of the output changes, depending upon how many outputs are "high" or "low". This translates into different output voltages. If you only want crude sine waves anyway, this might be a quick, cheap, effective way to do your project. However, if you want to make a complete six-string guitar with all frets, you'd have to devise a way to adjust the clock frequency...if you want cleaner output, you could add filtering.

    http://www.physics.udel.edu/~nowak/phys645/Basic_CMOS_Circuits.htm

    ...gives an example of what I mean.
     
    Last edited: Jan 6, 2012
  17. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    MrChips, you do well to question most of what I said, since I’m very inexperienced with microcontrollers. I appreciate your time in answering my questions. I want to hear about all the problems before I get too far into this. Nevertheless:
    1) This is my spare time project, not my occupation. I chose AVR over PIC and ARM, and need to stick with it. I’m confident there are microcontrollers that would do this better than an ATtiny. I might not use an ATtiny, but will use an AVR. If an AVR microcontroller won’t do it, that’s the end of this project.

    2) I want to use PWM because PWM can easily produce complex waveforms. It can do it with minimal processing power, according to http://www.atmel.com/dyn/resources/prod_documents/doc2542.pdf. Because of the large difference between the PWM’s output frequency and the audio frequency, a very simple RC filter is sufficient. I might try an active filter to see if it makes any noticeable difference.

    3) I don’t actually want a pure sine wave. But audio tones consist of the addition of the sine waves of multiple frequencies. You can create any waveform (even square waves and triangle waves) by adding together the correct sine waves.

    4) That’s great news that I only need one lookup table for all of the notes.

    5) Generating multiple notes is no problem because the 6 notes are created completely independently on 6 microcontrollers. The amplitude (for attack and decay) can be controlled by multiplying the lookup table value by some factor.

    6) I hadn’t heard of delta modulation before. I looked it up, and it appears to be a complex variant of PWM used for recording, transmitting, and playing back. But it’s still PWM.
    thatoneguy, thanks for the suggestion. Yes, I could filter a square wave. However I think PWM provides much better control over the resulting waveform.

    PaulEE, you’re absolutely correct that splitting it out into one “string” per chip greatly simplifies this in the ways that you mentioned. Regarding using more crude devices: I actually designed a complete circuit to accomplish this by using CMOS gates and other chips plus some analog circuitry. The end result was relatively crude, and I didn’t want to spend hours breadboarding and soldering. I’m better at programming, and so was glad when I found out about AVR microcontrollers.
     
  18. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    It's not a trivial application; simultaneous generation of 6 separate tones each playing its own correct freq "note" and each with a wavetable PWM waveform.

    Even in many commercial apps (synths etc) from the old days of 8bit processors they would use one tone generator per tone, so each one only needs to play one correct note and one correct waveform.

    On the other hand, maybe I misunderstand you and you want to record a "chord" consisting of multiple notes to a wavetable, then just play that ONE sound using PWM? That would be much easier at a beginner level, but of course limits each sound to a fixed number of notes of fixed relative volumes, that all start and stop together. (Like the sound of playing chords using single keys of a keyboard).
     
  19. John McMahon

    Thread Starter New Member

    Dec 22, 2011
    7
    0
    One microcontroller only creates one note. That note consists of multiple frequencies, resulting from what’s in the lookup table. The lookup table is created in advance; no such processing occurs while the notes are playing. This doesn’t make the chord – it’s just some frequency plus several harmonic frequencies for a single note.

    There are 6 identical independent microcontrollers, each playing whatever note they’re told (by another microprocessor) to play. So they could play a C, an E, and a G, plus the same notes in another octave, for a C major chord.

    Does this clarify anything or is this what you already understood I meant?

    I’m definitely at the beginner level, but other than the difficulty of creating the lookup table, this seems like this is a reasonably straightforward use of a PWM port. Is that correct?

    I’m not trying to replicate the tone quality of any particular instrument, so that cuts out a lot of work. I just don’t want it to be pure tones. In creating the lookup table, I’ll probably play around with mixing various frequencies of various amplitudes, to see what sounds reasonably good.
     
  20. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    That clarifies everything very nicely thank you John.

    So basically one micro is playing a "note" which is really a recording of a complex note, recorded and placed in a wavetable or generated in a spreadsheet and copied into a table.

    Assuming you had the table contents already generated, all that is really required is that the micro play one table entry to the PWM module every X period, where X period of course determines the "note". So if the table has 128 entries, and the note is A 440Hz, then you need to send the next table entry to the PWM module every 440*128 or 56320Hz.

    To generate the accurate note table frequency at 56320Hz you can use code examples seen here (check down the page)
    http://www.romanblack.com/one_sec.htm
    the examples let you generate any desired freq (each note) from whatever xtal your AVR uses.

    To generate the wavetable you can use a spreadsheet like Excel that can make waveforms and sum waveforms together etc.

    Or you can just put number values in a text file and use this free PC software;
    http://www.romanblack.com/wavmak.htm
    which generates a 44.1kHz wave file based on your number values, and you can then listen to the wave file in Windows etc.

    There is also this free PC software;
    http://www.romanblack.com/picsound.htm
    that lets you load and display and listen to wave files, and will re-sample them from any frequency to any other frequency. It also will export the sound data as raw binary data (that you can then put in a table in your AVR).
     
    John McMahon likes this.
Loading...