EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: Simon on June 20, 2016, 08:20:29 pm

Title: Generating a sound
Post by: Simon on June 20, 2016, 08:20:29 pm
I've been asked to produce an item that generates a clicking sound you know for example on your camera you press a button and it makes the noise of an old fashion camera. I've been asked for a click. What is the easiest way of producing such sounds? Is it feasible to actually code such a sound in C using a variable frequency PWM followed by a lowpass filter?
Title: Re: Generating a sound
Post by: MK14 on June 20, 2016, 08:33:32 pm
Sounds (excuse the pun), a perfectly viable way of doing it , to me. Lowest end microcontrollers are amazingly cheap these days, even in low volume.

One option would be to record a sound sample (maybe on a PC or something, or using sound editing/synthing software), then play it back using the low cost microcontroller.
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 05:11:43 am
how exactly do I play back a recorded sound, do I use the PCM values in a wave file as the values for PWM ?
Title: Re: Generating a sound
Post by: MK14 on June 21, 2016, 05:25:24 am
Basically, yes. Treating the filtered PWM, as a DAC output.

I think there are libraries you can use (wav/MP3 etc playback), if you want to make a quick prototype. Or you can write your own.

This guy seems to have done it and says a lot about it.
http://www.enide.net/webcms/?page=pcm2pwm (http://www.enide.net/webcms/?page=pcm2pwm)
Title: Re: Generating a sound
Post by: andersm on June 21, 2016, 05:53:28 am
What are the parameters of the finished gadget? Would eg. a voice recorder IC demo board (http://www.digikey.com/product-detail/en/nuvoton-technology-corporation-of-america/I16-COB20/I16-COB20-ND/1228829) do?
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 05:56:02 am
It's a finished product I'd need to produce. It's as simple as, "press button" = "click sound" so either a chip with a prerecorded sound or make up something myself or maybe one of those 10s sound recording chips and let the customer record their own sound.
Title: Re: Generating a sound
Post by: obiwanjacobi on June 21, 2016, 06:14:31 am
Consider that a short click-sound (duration) is an eternity for a MCU. So make it async.
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 06:25:55 am
Yes that is what worries me, what do you mean by async ?
Title: Re: Generating a sound
Post by: Ian.M on June 21, 2016, 06:57:07 am
I'd use a MCU, probably a 14 pin PIC16F1705 part, (with an on-chip OPAMP that could be used for a low pass fiilter), outputting 8 bit PWM with an 8KHz update rate from a ROM array.

Microchip published AN643 back in 1997 that covers the algorithm:-

Description: Adaptive Differential Pulse Code Modulation using the PIC16/17
Date: 8/26/97
Documentation: http://ww1.microchip.com/downloads/en/AppNotes/00643b.pdf (http://ww1.microchip.com/downloads/en/AppNotes/00643b.pdf)
Source Code: http://ww1.microchip.com/downloads/en/AppNotes/00643.zip (http://ww1.microchip.com/downloads/en/AppNotes/00643.zip)

Has C source and the compressor program.  There is a later PIC18 version, but converting old C18 code is fugly + it uses Microchip's MPFS filesystem from the MLA so is *FAR* more heavyweight.  Also the sourcecode for the PIC18 one appears to be AWOL.

Its far from ready to roll, (Bytecraft C, a different PIC family, + external EPROM) but should be convertible.  You would also need a waveform editor that can save mono 8KHz 16bit uncompressed WAV files, and the bin2c utility (https://sourceforge.net/projects/bin2c/) to convert the raw PCM data from the compresser into C source.
 
It takes a bit over 4K/second of audio,  so you should be able to get a 1 second shutter click sample into a  PIC16F1705.

Alternatively if you prefer ATmega328P, here's a fairly similar Arduino based project:
http://highlowtech.org/?p=1963 (http://highlowtech.org/?p=1963)

Edit: changed suggested PIC from PIC12F1840 to PIC16F1705 for double the sample space in a similar package size (if you use QFN).
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 06:59:02 am
I am an AVR man myself ;) I'll look into the arduino project.
Title: Re: Generating a sound
Post by: obiwanjacobi on June 21, 2016, 07:17:48 am
Yes that is what worries me, what do you mean by async ?

Typical C/C++ function calls are synchronous- the caller 'waits' until the function returns. If you call your click-sound function that way, your (main) MCU is frozen for that entire time. An asynchronous call is a fire-and-forget; you trigger the functionality to run (click-sound) but do not stick around for the result or until its finished. That way the overhead for the main-loop is minimal and the main functionality of your product is not hampered by generating the sound.

Getting this to work in software requires careful planning (with respect to intefrence with the main functionality). If you have a timer to spare (with PWM), you could use an interrupt to generate the sound in the background (with respect to the main loop) and with hardware support...
You could also solve this in hardware adding an extra chip to generate the sound (MCU or other)...
Title: Re: Generating a sound
Post by: Psi on June 21, 2016, 07:35:37 am
i've generated 8khz 8bit mono sound from an AVR before with no issues.
Just opened a mono wav file in hex edit and reformatted the bytes into a C struct stored in PROGMEM

One thing i did learn though, record the sound in the sample rate you will play it in (eg 8khz)
Converting between sample rates tends to result in substandard quallity
Title: Re: Generating a sound
Post by: Ian.M on June 21, 2016, 07:52:20 am
You can down-sample to any integer divisor of the original sample rate without much loss of quality other than the reduced bandwidth, provided the original sample has already been low-pass filtered to reduce aliasing.   However if its a non-integer divisor it will sound like s--t unless you start with a very high sample rate.
Title: Re: Generating a sound
Post by: JPortici on June 21, 2016, 09:32:29 am
I'd use a MCU, probably a 14 pin PIC16F1705 part, (with an on-chip OPAMP that could be used for a low pass fiilter), outputting 8 bit PWM with an 8KHz update rate from a ROM array.

Microchip published AN643 back in 1997 that covers the algorithm:-

Description: Adaptive Differential Pulse Code Modulation using the PIC16/17
Date: 8/26/97
Documentation: http://ww1.microchip.com/downloads/en/AppNotes/00643b.pdf (http://ww1.microchip.com/downloads/en/AppNotes/00643b.pdf)
Source Code: http://ww1.microchip.com/downloads/en/AppNotes/00643.zip (http://ww1.microchip.com/downloads/en/AppNotes/00643.zip)

Has C source and the compressor program.  There is a later PIC18 version, but converting old C18 code is fugly + it uses Microchip's MPFS filesystem from the MLA so is *FAR* more heavyweight.  Also the sourcecode for the PIC18 one appears to be AWOL.

Its far from ready to roll, (Bytecraft C, a different PIC family, + external EPROM) but should be convertible.  You would also need a waveform editor that can save mono 8KHz 16bit uncompressed WAV files, and the bin2c utility (https://sourceforge.net/projects/bin2c/) to convert the raw PCM data from the compresser into C source.
 
It takes a bit over 4K/second of audio,  so you should be able to get a 1 second shutter click sample into a  PIC16F1705.

Alternatively if you prefer ATmega328P, here's a fairly similar Arduino based project:
http://highlowtech.org/?p=1963 (http://highlowtech.org/?p=1963)

Edit: changed suggested PIC from PIC12F1840 to PIC16F1705 for double the sample space in a similar package size (if you use QFN).

take a look at the 16f1776, 10 bit dac on board too, i am already using it for a simillar purpose
Title: Re: Generating a sound
Post by: vk6zgo on June 21, 2016, 09:45:05 am
Why would you generate the sound from scratch?

http://www.soundjay.com/camera-sound-effect.html (http://www.soundjay.com/camera-sound-effect.html)
Title: Re: Generating a sound
Post by: Ian.M on June 21, 2016, 10:11:47 am
Take a look at the 16f1776, 10 bit dac on board too, i am already using it for a similar purpose
It doesn't bring any extra memory so its not worth going up to a 28 pin chip unless you need the extra I/Os.  The DAC might make life a little easier, but the AN643 1997 code outputs 32KHz PWM, so its pretty easy to low-pass filter.   It would probably make more sense to go up to a dsPIC or PIC24, as with a max of 512K FLASH in a 28 pin package, one could store two minutes of sampled audio.

Why would you generate the sound from scratch?

http://www.soundjay.com/camera-sound-effect.html (http://www.soundjay.com/camera-sound-effect.html)
So you can legally sell the sound-effect chip.  If you read Soundjay's terms of use, they don't permit you to:
"- use them as a raw material to create sound effects or ringtones that you will sell, distribute or offer for downloading"
Title: Re: Generating a sound
Post by: MarkF on June 21, 2016, 12:14:13 pm
i've generated 8khz 8bit mono sound from an AVR before with no issues.
Just opened a mono wav file in hex edit and reformatted the bytes into a C struct stored in PROGMEM

One thing i did learn though, record the sound in the sample rate you will play it in (eg 8khz)
Converting between sample rates tends to result in substandard quallity
All you need to do is set up an interrupt to output the samples.  Just set the interrupt time for the rate each sound was recorded with.

Why would you generate the sound from scratch?

http://www.soundjay.com/camera-sound-effect.html (http://www.soundjay.com/camera-sound-effect.html)
Why on earth would you do anything else for a simple click.  I would never use a big a-- library for even more complex sounds.  Especially for audio range frequencies.  A small microcontroller with a DAC built-in could easily do the job.
Title: Re: Generating a sound
Post by: Buriedcode on June 21, 2016, 03:49:44 pm
I've made quite a few 'sound generators' on 8-bit (PIC and AVR) and there's a huge variation in complexity open to you, from the 6/8-pin PIC driving a piezo element to external flash and high speed PWM, over sampled with a 4-pole LPF to get fairly decent sound (10-12-bit, 16kHz sample rate, for recognizable music).  To me this sounds like the lower end of a cheap small 8-bit micro, a transistor and a cell phone speaker.

I say first find a clip of the sound you want, preferably a clean one and then decide if you generate it directly or just play it from flash.  SPI flash is pretty cheap these days, and as mentioned some PIC's have internal opamps for <$1 (Ian M mentioned the PIC16F1705, nice little jobs these are!) but the part count starts climbing.  The idea of play sounds from flash has the benefit of being simple to implement,and allows you to play any sound of almost any length you want (limited by size of flash).  The micro only has to periodically grab bytes from memory and update a PWM, which is great if it has to do other things, but seems a waste if that is its only job.  I thnk unless you're playing high quality music, an external DAC is also over kill.

AVR's, specifically the attiny series almost always have PWM capability, and some have a high frequency oscillator, 32/64MHz to drive it, pushing the PWM frequency up and easing the requirement for high pole filters.  Both PIC's and AVR's run fast enough to do fairly complicated maths for generating low sample rate 'sound effects' on the fly, but these would be one-trick ponies and wont' have the versatility of simply 'dumping a wave file in flash'.

So yeah.. can be as simple or as complicated as you want, and I suspect thats why you posted - if there was only a couple of ways to do it you would have done it :)

Would be nice to hear an example of the 'click' sound you want. Piezo's can 'click' nicely given the right waveform, but might not be loud enough.
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 06:44:35 pm
Thank you for your suggestions everybody. It is indeed meant to be a simple as possible and no other functionality would be required other than to produce a sound when a button is pushed. I'm not quite clear on how PCM works. Is a number value giving the duty to a PWM signal representing the volume in that instant? So I would need one PWM cycle at least to represent each sample point of sound?

Yes the attiny 85 has a clock that can run up to 64 MHz for the PWM generator so quite flexible.
Title: Re: Generating a sound
Post by: Ian.M on June 21, 2016, 07:01:17 pm
You'll want to keep the PWM above the audio band, and to prevent objectionable aliasing,  the PWM should be an integer multiple of the sample rate.  So for 8KHz sample rate, the lowest PWM frequency you should use is 24KHz.   It doesn't matter if the PWM duty cycle doesn't go all the way to 100% (as that just reduces the max amplitude a bit), so you can pad the PWM period to exactly match N times the sample rate.
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 08:22:36 pm
I have some more details now what I am to do. I need to reproduce the sound of a clicker you know the sort of thing you hold in your hand and press and release and it goes click click. I'm guessing there is a membrane that his bent which generates a sound pulse. I have just experimented in audacity recording me clicking my fingers and the sound is essentially a peak followed by a decaying oscillation so in reality probably quite simple to hand the program into some C code has with good filtering I should not need to many sample points.
Title: Re: Generating a sound
Post by: MarkF on June 21, 2016, 08:23:55 pm
I don't see the point in fooling around with PWM when a PIC is fast enough to output the raw samples directly.  A pic16f1786 has a 8 bit DAC and a 32 MHz clock which are plenty good enough to generate audio frequencies.  It just needs a transistor to drive a speaker.
Title: Re: Generating a sound
Post by: Simon on June 21, 2016, 08:51:47 pm
That is all very well and good but I'm not familiar with pics and certainly not with the higher end devices.
Title: Re: Generating a sound
Post by: Buriedcode on June 22, 2016, 12:13:29 am
I don't see the point in fooling around with PWM when a PIC is fast enough to output the raw samples directly.  A pic16f1786 has a 8 bit DAC and a 32 MHz clock which are plenty good enough to generate audio frequencies.  It just needs a transistor to drive a speaker.

Good point, but it would probably still need a low pass filter.  Using PWM isn't really 'fooling around', using it as a DAC only requires a low pass filter.  PWM DAC's don't have as good absolute precision as ladder DACs (like the one used in that PIC) but their relative accuracy is just fine - which is what counts for audio.  It uses just one pin, *can* be 10-bit, or higher with some AVR's and is just as easy to use as a DAC.  Its also pretty much device independent as almost all devices across the range have it, thats why it was suggested it.

Also, I don't think I've seen it done but someone must have - using two 'output compare' resisters from a signal timer, giving two 8-bit high speed PWM's, mixed with an opamp with a ratio of 256:1.  One is the coarse, the second is the fine giving potentially 16-bit resolution, at the PWM period of a single 8-bit counter.  16-bit is overkill, and it would never achieve that anyway, but could make for higher quality sound samples and running the PWM on 8-bit rather than 10-bit allows it to run 4 times faster - pushing the PWM frequency above the audio band.

Not hijacking the thread, just thinking outloud here:
Say you have a wav soundclip, sampled at 16kHz @ 16-bit (or just 8-bit!).  For 8-bit PWM running at the sample rate = 16kHz * 256 = 4.096MHz.  Make the PWM rate 4* the sample rate (higher the better really) and that requires 16.384Mhz.  Just use a 16MHz clock and you have a PWM frequency of 16/256 = 62.5kHz, well above the audio band.  The update/sample rate will be 15.625kHz. You have the option of using two PWM's for up to 16-bit samples, or just one for 8-bit.  And the 16kHz sample rate is higher than the 'standard' 8kHz giving more detail for transients.  As mentioned, the PWM frequency should be a multiple of the sample rate so that a whole number of periods fit between updates, in this case - 4.  Some devices will buffer the compare and automatically update the period at the start meaning you don't have to be super accurate in updating it. 

That won't require a particularly complicated filter (two pole passive) and can work on many devices.



Title: Re: Generating a sound
Post by: Someone on June 22, 2016, 02:40:24 am
I have some more details now what I am to do. I need to reproduce the sound of a clicker you know the sort of thing you hold in your hand and press and release and it goes click click. I'm guessing there is a membrane that his bent which generates a sound pulse.
Which can be modelled and reproduced with a few passives and an opamp or transistor, if a click is the only thing needed why complicate it with a micro?
Title: Re: Generating a sound
Post by: Simon on June 22, 2016, 05:31:06 am
I have some more details now what I am to do. I need to reproduce the sound of a clicker you know the sort of thing you hold in your hand and press and release and it goes click click. I'm guessing there is a membrane that his bent which generates a sound pulse.
Which can be modelled and reproduced with a few passives and an opamp or transistor, if a click is the only thing needed why complicate it with a micro?

I was almost thinking that myself. If I use PWM 8 bit is fine I'm also thinking that a low pass filter at the frequency of the few oscilations required would make it much easier as I can just supply the low/high points and let the filter produce the rest.
Title: Re: Generating a sound
Post by: MK14 on June 22, 2016, 06:06:09 am
Here's a single IC (probably very cheap jellybean) click generator + passives.

http://www.discovercircuits.com/DJ-Circuits/click-sound-gen.htm (http://www.discovercircuits.com/DJ-Circuits/click-sound-gen.htm)
Title: Re: Generating a sound
Post by: Simon on June 22, 2016, 06:33:56 am
yes that would work. I'd actually need two clicks to simulate a clicker because you press it and release it and because it's one of those things with a sprung diaphram that flips from one side to the other it clicks when you press and clicks "back" when you release. I suppose if i put a capacitor across the speaker it woud help round the edges off or just sightly low pass filter it and put it through a small amplifier to a speaker.
Title: Re: Generating a sound
Post by: nhw888 on June 22, 2016, 09:41:05 am
Here is a application note about the subject for AVR devices.

https://www.adestotech.com/wp-content/uploads/doc1456.pdf (https://www.adestotech.com/wp-content/uploads/doc1456.pdf)

You can leave the recording part out from the final product, but use it for testing.
Title: Re: Generating a sound
Post by: MK14 on June 22, 2016, 12:13:15 pm
yes that would work. I'd actually need two clicks to simulate a clicker because you press it and release it and because it's one of those things with a sprung diaphram that flips from one side to the other it clicks when you press and clicks "back" when you release. I suppose if i put a capacitor across the speaker it woud help round the edges off or just sightly low pass filter it and put it through a small amplifier to a speaker.

As a rule of thumb, if you want a single/simple sound effect, almost 100% fixed (the customer WON'T change their minds) etc etc. Then a discrete solution (such as what I previously linked to, or what other(s) have mentioned), may be a viable alternative to an MCU.

But if it/its (specifications) might change (especially a lot), needs to be of high quality (even if you think it does NOT need to be, but all this talk of extensive filtering, makes it sound like it needs to be fairly high quality), multiple (different) sound effects, and/or other complications. Then really the MCU based solution, is probably the best way forward.

If there is any kind of quantity involved ?, pics/microchip (although you want to NOT use them), offer a pre-programmed service (at reasonable cost, and not that high volume requirements, when I last looked), which can save hassle, especially for surface mount parts, which are harder to program by hand.

If it is only a ONE-OFF, then the quickest prototype you can come up with, is probably best.

EDIT:
Obviously a discrete solution CAN handle multiple sound effects and/or high quality, with (usually) extra components. But at some point, it makes much more sense to use an MCU, which can handle a huge range of options, with little or no change in hardware or its costs.
Pics are just one type of MCU which could do it. Using the ones you are familiar with is ok, as long as the volumes are not so high and/or costs need to be so low, that it would be problematic.
Title: Re: Generating a sound
Post by: Simon on June 22, 2016, 04:52:34 pm
At the moment I need a prototype in a hurry and to actually come up with some knowledge of what I'm doing in terms of producing this sound. Quality is not paramount as the customer wants a cheap product and volumes will be low I don't think they would order more than 50 at a time.

What I'm thinking is to have a lowpass filter with the same frequency as the PWM so it will in effect resonate and produce a virtually sinusoidal sound. Potentially yes they could change their mind so having a microcontroller is ideal.