| Author |
Message |
|
|
Posted: May 24, 2006 - 06:52 AM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
Hello, I'm brand new to MCUs as well as to ADC/DAC, so please excuse my ignorance. I need to build a system which records speech, delays it a short amount of time (max. 500ms, probably closer to the range of 50ms - 125ms) and plays it back. It needs to do all of this at once, meaning the recording must continue while the delayed playback occurs.
I found a quite similar project in app note 335, and it seems rather simple and straightforward to me. I am sure I can figure out how to write the code I need based on the example code, but I am wondering if the MEGA8535 has enough internal memory so I can dispense with the flash RAM?
Since the data can be ignored/erased as soon as it is played back, I would imagine I only need enough memory to store, at maximum, 500ms of soujnd data. Yet I wonder if the buffering the flash RAM does might be a key part of ensuring fast enough operation? I also wonder if the internal memory of the MEGA8535 is fast enough to perform the task I would ask of it. I also wonder if I am missing other problems or issues because of my inexperience in MCU work, I just don't know.
If anyone has any thoughts or wisdom they might want to share, I would be quite appreciative. Again, please excuse my lack of knowledge.
Thanks,
Seth |
|
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 07:30 AM |
|


Joined: Aug 04, 2003
Posts: 873
|
|
| The Mega8535 has 8kb's of memory, so it really depends on the data/bit rate you're sampling at. I'm going to asume 8bits as you can't expect much more out of the ADC. I'll also asume approximatly an 8khz sampling rate (the exact rate will depend on your clock rate) So just given those rough numbers you'll have enough sram to buffer 1 second of audio. You'd use a generic ring buffer with a 2 byte index. As long as your sampling and playback routines were synchronized all you'd have to do is change the index the playback routine uses. Considering you're really only adding an offset to the playback and a single increment instruction for the memory index the overhead should be minimally higher than simply playing back. |
_________________ -Curiosity may have killed the cat
-But that's why they have nine lives
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 10:01 AM |
|


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Another idea would be to go with something like AVR335 but instead of AT45 Dataflash (relatively long access especially for erase/write and also write cycle life limit problems) use an FRAM from Ramtron (www.ramtron.com) instead but doing something very similar otherwise.
I think Sceadwian may have been a bit confused between the resources in an 8535. It may well have 8K of program flash but it only has 512 bytes of SRAM for audio buffering use which will not be enough for a 500ms delay. However the 8535 does have the SPI which would be the obvious way to connect to an FRAM chip - http://www.ramtron.com/doc/Products/non ... t.asp?ID=5
Cliff |
_________________
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 05:07 PM |
|


Joined: Sep 04, 2002
Posts: 13373
Location: Orlando Florida
|
|
| Doesnt one of the new megas have 8k of ram? Some dev boards have an external 32k ram. (progressive resources?) |
|
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 06:26 PM |
|


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Yup http://www.atmel.com/dyn/products/param ... tion=DESC# says 640, 1281, 2561, 2560, 1280
Wonder what's cheaper - a large AVR or a small one with external FRAM (especially when you can order FRAM samples for free if this is just a one off project)
Cliff |
_________________
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 06:29 PM |
|


Joined: Sep 20, 2003
Posts: 2726
Location: Surrey, England
|
|
| Surely external SRAM is all that's needed. |
|
|
| |
|
|
|
|
|
Posted: May 24, 2006 - 09:22 PM |
|


Joined: Sep 04, 2002
Posts: 13373
Location: Orlando Florida
|
|
| I wish we could win a prize if we guess the application. A Talk Radio curse preventer delay? no... those are 6 seconds.... A CB radio echo mic? I give up! Did I guess it? |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 02:04 AM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
I am building a DAF (delayed auditory feedback) device which is used to help treat stuttering. I am building them to donate to a Speech Pathologist who works with stutterers, so cost is a factor and I hope to be able to build and giveaway 10 or so.
When I made the commitment I thought that this would be reasonably easy to do without a microcontroller, and so I figured all I needed to learn was ADC/DAC. Frankly I feel like I am in somewhat over my head, but then I guess thats how I learned most of the stuff I know.
For failing to guess correctly you win the prize of offering me free advice on this project.  |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 03:13 AM |
|


Joined: Feb 19, 2001
Posts: 18830
Location: Wisconsin USA
|
|
Well, at least it isn't an overdue assignment as is many times on this board. And a laudable effort; I suspect that you will get as much help as you need.
OK, so you only need speech frequency range, not full audiophile range. That should make the task simpler. If absolute best quality isn't a major criterion, then lower bit resolutions can be made. Is stereo a requirement?
Let's see--max time is half a second. Speech could be sampled at 10-15 kHz and get halfway decent results--that is within the comfort range of an AVR onboard ADC. 10000 samples/second is 5000 samples for 500 ms. If 8 bits are stored for each sample then 5kB is needed; about double that for more bits or faster.
I guess I'd start with a Mega64. Overkill, but has ADC and external SRAM interface and add 32kB of external SRAM. Then a simple circular buffer, adjusting the depth for the delay needed. And an appropriate DAC going into a simple audio amp.
One could also put an audio codec in front of the AVR and use something like the Mega8515.
An interesting project. Is the last $$ important? Is this to be worn constantly, or like a therapy device? In other words, does it need to be battery powered with belt clip attachement, or a tabletop device?
Where is Sonos when we need him?
Lee |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:10 PM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
Stereo is not an issue, I figured on using one of those cell phone earpieces to supply the mic and a single channel of audio to one ear so that other peoples speech would still be audible. It would not need to be worn constantly, but it would need to be worn a significant amount of time each day (several hours) to reenforce the non-stuttering behavior enough to be useful. I figured battery powered on the belt would work best. I'm not 100% sure what you mean by "the last $$", if you mean the money for batteries to make the device last longer, then yes. The therapist I am donating these to works in some pretty poor school districts, and this is basically an alternative to the commercial units which the families cannot afford. If you mean the cost of the units I thought that around 10 - 20 dollars a unit would be somewhat reasonable (I have tons of small parts, so resistors, diodes, caps, common transistors, etc. are not part of the cost I figured), but I am willing to live with a per unit cost of up to 50 dollars based on making about 10.
For the circular buffer, if I understand the concept, I would essentially be using the data access speed of the MCU to determine delay time? For instance if it takes 1 cycle to write and read a block of memory, and each cycle takes 50ms, I would have a buffer size of 10 blocks and would read a block and then write directly over it. So I would continuously be reading from the oldest block in memory and then overwriting it. Am I hitting the idea?
Thanks all!
EDIT:
It just occured to me, do ADCs expect line level input or can they accept mic level? If it needs to be line level would you use an opamp or just use transistors? Is the ADC going to expect a true AC signal? It would be cheap and easy to use an LM386 as my output amplifier (I have several lying around and they hook up super easy), do you think it would work in this application? |
Last edited by qtc3 on May 25, 2006 - 01:24 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:23 PM |
|


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia
|
|
A circular buffer (aka as a "ring buffer") is a buffer designed to continuously store and read buffered data in a FIFO (First in, First out) format. You need to know the size of the buffer, and since you have a fixed number of samples, you can calculate the buffer's depth.
Ringbuffers work via a large array, and two pointers - and "out" pointer and an "in" pointer. Each time data is added to the array as pointed to by the "in" pointer the "in" pointer is increased by one location. Once the end of the array is reached the "in" pointer is reset to the start of the array. This means that data can be continuously buffered in a circular manner (essentially you're warping the buffer so that it wraps around in a circle, hence the name). The "out" pointer does the same thing, except you read from the buffer at the location pointed to by the out buffer.
What you end up with is the ability to BufferByte(x); continuously so long as the in pointer never starts overwriting data that the out pointer has read. I made a rather dodgy C demonstration library when I first learnt the concept, and it's avaliable here which you can check out to see a code implementation.
Pity i've no experience with digital audio, i'd love to help out such a noble cause. I'll have to think up my own ideas for my next project .
- Dean  |
_________________
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:30 PM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
| So as an analogy: I have something like a NASCAR track, and two race cars driving around it. The front race car is always writing new data to the track and the race car behind it is always reading that data. They keep going around and around and continuously writing and readind data. I decide how far apart the race cars should be based on how long the delay I need is. Am I getting it? |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:35 PM |
|


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia
|
|
Yes, and you can increase the racetrack size so that the distance can be greater (increase the total buffer size). The cars can travel at any speed you want (read/write at any speed) so long as the read car is always behind the write car.
Good analogy, I might make it into a tutorial for the tutorials section tomorrow night...
- Dean  |
_________________
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:35 PM |
|


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
qtc3 wrote:
Am I getting it?
Exactly.
You are going to need pre-amplification of the Mic output to get it up to the 0V..5V, 0V..3.3V, 0V..2.56V or whatever it is that you setup the AVR's ADC to measure against. The 335 app note has a circuit for such amplification I think.
Cliff |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:49 PM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
| I looked at the C library and I have a question: In StoreBuffByte if the buffer is full I encounter an error, but since this is a ring buffer wont I run into a full buffer each time I wrap back to the beginning? Or does the BuffElements variable determine if the buffer is full? |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:54 PM |
|


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia
|
|
Yes, BuffElements determines when the buffer is full. Because the in and out pointers are being incremented at different times, you could end up half-way into the buffer space and have no bytes in the buffer, because you've read them all out. Extending your metaphor, despite your cars being half way round your NASCAR racetrack the two cars are only a meter apart, and so have a full racetrack's distance to go. What matters is the distance between the cars, not the distance around the track.
I'll be able to write more about this (I'm thinking of making a proper tutorial, probably unnessesary but I like writing tutorials ) tomorrow evening after school - it's very late here. Good night everyone!
- Dean  |
_________________
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 01:57 PM |
|

Joined: Apr 15, 2004
Posts: 9
|
|
[quote="clawson"]The 335 app note has a circuit for such amplification I think.
Cliff[/quote]
Yep, I forgot that. Can I just use the same basic audio parts of that circuit regardless of which AT MCU I use, or do I need to be concerned with the different chips having different expectations on I/O? |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 02:20 PM |
|


Joined: Apr 25, 2006
Posts: 2036
Location: Germany
|
|
It might be possible to get it done without external RAM. It
really depends on quality needed. Perhaps one can use
speech compression !
Look at this final-project of ee476 LAB:
http://instruct1.cit.cornell.edu/course ... /index.htm
They did ADPCM compression on an AVR, I think they provide wave-files to
listen to. Its perhaps not the easiest way for an AVR beginner but if AVRFREAKS help ?
It may also be possible to use CVSD compression, I always wanted to test it some time, perhaps time has come now. CVSD is a old simple "compression" technique used in telekommunication speech applications.
Should be possible with an AVR ! Perhaps someone has already done it.
I think a simple R/2R ladder-DAC will be good enough as DAC.
If size and number of components is an issue, software may help.
Do you want to design a PCB ? |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 02:27 PM |
|


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
abcminiuser wrote:
Because the in and out pointers are being incremented at different times, you could end up half-way into the buffer space and have no bytes in the buffer, because you've read them all out.
But this shouldn't happen should it? What qtc3 is going to do is start ADCing the input and storing it into the buffer until there is ~500ms buffered and then start playout from the other end of the buffer AT THE SAME RATE! While there could be the odd byte of "jitter" between bytes going in and bytes going out - the in and out pointers should never get anywhere near each other because it'd mean that the in/out processes where happening at different rates - but this would mean the played speech was either playing too fast or two slow. If 10KHz sample rate then the pointers should always be about 5K apart for a 500ms delay as long as record/playback are at the same rate.
Cliff |
|
|
| |
|
|
|
|
|
Posted: May 25, 2006 - 02:34 PM |
|


Joined: Jul 18, 2005
Posts: 33138
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
ossi wrote:
They did ADPCM compression on an AVR, I think they provide wave-files to listen to.
My own sound record / playback application also uses ADPCM but that is a red-herring in this case. You do not want to waste CPU time doing ADPCM (and losing a slight amount of audio quality). The reason for ADPCM is when you are recording to hold the speech/music in flash permanently and because of the 4:1 compression ratio it means you can get that much more recorded sound into that much less flash (or get away with using a smaller flash chip than intended). While the use of ADPCM in this application might reduce the buffer requirement from 5K to 1.25K the fact is you are almost certainly going to need an added external RAM buffer anyway so there's no point in worrying about sound compression / decompression.
Oh and as for DAC - you don't really need to use external R-2R to implement a DAC for this - a PWM output passed through an RC filter is just fine for speech playback (works just great in my application)
Cliff |
|
|
| |
|
|
|
|
|