EmbeddedRelated.com
Forums
Memfault Beyond the Launch

ADC + DMA + Sound question

Started by David Rea December 23, 2004
Hi All-

I'm still working on this voice recorder app that you've all heard so
much about by now. I've got every subsystem working at this point -
ADC12, USART0 for PC comm, USART1 for SPI with flash memory, etc. Now
it's time to pull them all together.

I'd like to capture audio at 8KHz, 8 bits per sample. So I'm going to
set up a timer to kick over the ADC in single-conversion mode, then use
DMA to pull the result into SRAM. After 256 samples have been dropped
into RAM, I need to send them out in a page-write via SPI to my flash
chip.

But since I'm working at 8 bits per sample, I need to throw away the 4
least significant bits from each ADC result before the SPI transaction.
Trying to figure out the best way to do this... And as of now I've only
come up with one way:

Actually pull the 12-bit samples as words into SRAM, allocating 2x as
much as I actually need. Then, when 256 samples have been written to
SRAM and I'm ready to do the big SPI dump, do a bigass shift on all the
memory locations, then cast them to chars as I transmit. This leaves me
with a bad taste in my mouth, since:

a) I use up a lot of CPU time doing those shifts
b) I use 256 words of SRAM instead of 256 bytes - yuck!
c) I don't get to have as much fun using DMA into the USART if I shift
the bits immediately before transmission - even if I'm in burst-block
mode.

I'm sorry for the tangent, but having DMA in a microcontroller is just
FREAKIN COOL.

OK back on topic. I'd love to be able to truncate the samples from
inside DMA, but doing a word-to-byte transfer, I actually get the
bottom 8 bits loped off, not the bottom 4 like I need.

Alternately, it'd be spiffy if I could go with an ADC12 ISR, shift the
bits, *then* hand the result off to DMA, but triggering the DMA by
manually raising the ADC12IFG is a no-go.

So what's a guy to do??

Thanks in advance,
Dave


Beginning Microcontrollers with the MSP430

David why on earth are you throwing resolution away. by chopping off the 
lower 4 bits you are losing fine detail. this is absolutely the wrong 
way to do it. What you should do is a 12 to 8 bit log compression, ie 
u-Law or A-law. Thois retains all the fine detail in the low end and 
spreads the compression losses into the high end. Your ear works like 
this. It notices the absence of small detail, but doesn't differentiate 
so finely over large amplitude changes.

David Rea wrote:

> Hi All-
> 
> I'm still working on this voice recorder app that you've all
heard so
> much about by now. I've got every subsystem working at this point -
> ADC12, USART0 for PC comm, USART1 for SPI with flash memory, etc. Now
> it's time to pull them all together.
> 
> I'd like to capture audio at 8KHz, 8 bits per sample. 

Is that 8kHz audio, or 8000 samples per second. there is a big difference.

So I'm going to
> set up a timer to kick over the ADC in
single-conversion mode, then use
> DMA to pull the result into SRAM. After 256 samples have been dropped
> into RAM, I need to send them out in a page-write via SPI to my flash
> chip.
> 
> But since I'm working at 8 bits per sample, I need to throw away the 4
> least significant bits from each ADC result before the SPI transaction.
> Trying to figure out the best way to do this... And as of now I've
only
> come up with one way:
> 
> Actually pull the 12-bit samples as words into SRAM, allocating 2x as
> much as I actually need. Then, when 256 samples have been written to
> SRAM and I'm ready to do the big SPI dump, do a bigass shift on all
the
> memory locations, then cast them to chars as I transmit. This leaves me
> with a bad taste in my mouth, since:
> 
> a) I use up a lot of CPU time doing those shifts

	mov	#TABLEBASE,R5	2 CLOCKS
	MOV	#256,R6		2 CLOCKS
SLOOP:
	MOV	@R6+,R4		2 CLOCKS
	asr 	r4		1 CLOCK
	asr 	r4		1 CLOCK
	asr 	r4		1 CLOCK
	asr 	r4		1 CLOCK
	mov	r4,-2(r6)	4 clock
	DEC 	R6		1 CLOCK
	JNZ	SLOOP		2 CLOCKS	

LOOP TAKES 13 * 256 CLOCKS + 4 =  3332 CLOCK CYCLES

so the only way to achieve this using shifts is to have dual buffers 
methinks, or, more logically, reduce the number of samples taken so that 
the compression can take place in less than 1 sample period

THIS IS STILL WRONG. LOG COMPRESSION WILL SOUND MUCH BETTER.

Al

> b) I use 256 words of SRAM instead of 256 bytes -
yuck!
> c) I don't get to have as much fun using DMA into the USART if I shift
> the bits immediately before transmission - even if I'm in burst-block
> mode.
> 
> I'm sorry for the tangent, but having DMA in a microcontroller is just
> FREAKIN COOL.
> 
> OK back on topic. I'd love to be able to truncate the samples from
> inside DMA, but doing a word-to-byte transfer, I actually get the
> bottom 8 bits loped off, not the bottom 4 like I need.
> 
> Alternately, it'd be spiffy if I could go with an ADC12 ISR, shift the
> bits, *then* hand the result off to DMA, but triggering the DMA by
> manually raising the ADC12IFG is a no-go.
> 
> So what's a guy to do??
> 
> Thanks in advance,
> Dave
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 


David,

maybe you can use the hw-multiplication unit together with DMA (just a idea,
did not have a closer look at it yet). But it is a 16 bit controller, do not
bother, do it in 16 bits - is as same as fast as 8 bits. (This kind of data
processing was one reason, why TI decided to make the MSP430 a 16 bit one).

You should not need any RAM, just shuffle it from ADC directly to SPI.
This can be done in background from the DMA (you need CPU intervention only
at the sector borders).

M.

On Thu, Dec 23, 2004 at 05:28:02PM +1030, onestone
wrote:
> 
> David why on earth are you throwing resolution away. by chopping off the 
> lower 4 bits you are losing fine detail. this is absolutely the wrong 
> way to do it. What you should do is a 12 to 8 bit log compression, ie 
> u-Law or A-law. Thois retains all the fine detail in the low end and 
> spreads the compression losses into the high end. Your ear works like 
> this. It notices the absence of small detail, but doesn't
differentiate 
> so finely over large amplitude changes.
> 
> David Rea wrote:
> 
> > Hi All-
> > 
> > I'm still working on this voice recorder app that you've all
heard so
> > much about by now. I've got every subsystem working at this point
-
> > ADC12, USART0 for PC comm, USART1 for SPI with flash memory, etc. Now
> > it's time to pull them all together.
> > 
> > I'd like to capture audio at 8KHz, 8 bits per sample. 
> 
> Is that 8kHz audio, or 8000 samples per second. there is a big difference.
> 
> So I'm going to
> > set up a timer to kick over the ADC in single-conversion mode, then
use
> > DMA to pull the result into SRAM. After 256 samples have been dropped
> > into RAM, I need to send them out in a page-write via SPI to my flash
> > chip.
> > 
> > But since I'm working at 8 bits per sample, I need to throw away
the 4
> > least significant bits from each ADC result before the SPI
transaction.
> > Trying to figure out the best way to do this... And as of now
I've only
> > come up with one way:
> > 
> > Actually pull the 12-bit samples as words into SRAM, allocating 2x as
> > much as I actually need. Then, when 256 samples have been written to
> > SRAM and I'm ready to do the big SPI dump, do a bigass shift on
all the
> > memory locations, then cast them to chars as I transmit. This leaves
me
> > with a bad taste in my mouth, since:
> > 
> > a) I use up a lot of CPU time doing those shifts
> 
> 	mov	#TABLEBASE,R5	2 CLOCKS
> 	MOV	#256,R6		2 CLOCKS
> SLOOP:
> 	MOV	@R6+,R4		2 CLOCKS
> 	asr 	r4		1 CLOCK
> 	asr 	r4		1 CLOCK
> 	asr 	r4		1 CLOCK
> 	asr 	r4		1 CLOCK
> 	mov	r4,-2(r6)	4 clock
> 	DEC 	R6		1 CLOCK
> 	JNZ	SLOOP		2 CLOCKS	
> 
> LOOP TAKES 13 * 256 CLOCKS + 4 =  3332 CLOCK CYCLES
> 
> so the only way to achieve this using shifts is to have dual buffers 
> methinks, or, more logically, reduce the number of samples taken so that 
> the compression can take place in less than 1 sample period
> 
> THIS IS STILL WRONG. LOG COMPRESSION WILL SOUND MUCH BETTER.
> 
> Al
> 
> > b) I use 256 words of SRAM instead of 256 bytes - yuck!
> > c) I don't get to have as much fun using DMA into the USART if I
shift
> > the bits immediately before transmission - even if I'm in
burst-block
> > mode.
> > 
> > I'm sorry for the tangent, but having DMA in a microcontroller is
just
> > FREAKIN COOL.
> > 
> > OK back on topic. I'd love to be able to truncate the samples
from
> > inside DMA, but doing a word-to-byte transfer, I actually get the
> > bottom 8 bits loped off, not the bottom 4 like I need.
> > 
> > Alternately, it'd be spiffy if I could go with an ADC12 ISR,
shift the
> > bits, *then* hand the result off to DMA, but triggering the DMA by
> > manually raising the ADC12IFG is a no-go.
> > 
> > So what's a guy to do??
> > 
> > Thanks in advance,
> > Dave
> > 
> > 
> > 
> > 
> > .
> > 
> >  
> > Yahoo! Groups Links
> > 
> > 
> > 
> >  
> > 
> > 
> > 
> > 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
        Matthias

Quoting onestone <onestone@ones...>:

> David why on earth are you throwing resolution
away. by chopping off
> the
> lower 4 bits you are losing fine detail. this is absolutely the wrong
> way to do it. What you should do is a 12 to 8 bit log compression, ie
> u-Law or A-law. Thois retains all the fine detail in the low end and
> spreads the compression losses into the high end. Your ear works like
> this. It notices the absence of small detail, but doesn't
> differentiate
> so finely over large amplitude changes.

OK, sounds good. [pun intended]

Now where to begin... I'll head over to the university library today
(gotta love alumni library cards) and see what I can find for
references on those codecs...

Anyone have any hints on MSP430 implementation??

Dave


ITU_T G.711 is what you need.

Spencer

>-----Original Message-----
>From: David Rea [mailto:dave@dave...] 
>Sent: 23 December 2004 14:01
>To: msp430@msp4...
>Subject: Re: [msp430] ADC + DMA + Sound question
>
>
>
>Quoting onestone <onestone@ones...>:
>
>> David why on earth are you throwing resolution away. by chopping off 
>> the lower 4 bits you are losing fine detail. this is absolutely the 
>> wrong way to do it. What you should do is a 12 to 8 bit log 
>> compression, ie u-Law or A-law. Thois retains all the fine detail in 
>> the low end and spreads the compression losses into the high 
>end. Your 
>> ear works like this. It notices the absence of small detail, but 
>> doesn't differentiate
>> so finely over large amplitude changes.
>
>OK, sounds good. [pun intended]
>
>Now where to begin... I'll head over to the university library 
>today (gotta love alumni library cards) and see what I can 
>find for references on those codecs...
>
>Anyone have any hints on MSP430 implementation??
>
>Dave
>
>
>
>------------------------ Yahoo! Groups Sponsor 
>--------------------~--> 
>Make a clean sweep of pop-up ads. Yahoo! Companion Toolbar.
>Now with Pop-Up Blocker. Get it for free! 
>http://us.click.yahoo.com/L5YrjA/eSIIAA/yQLSAA/CFFolB/TM
>---------------------------
>-----~-> 
>
>.
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>



Quoting David Rea <dave@dave...>:

> Now where to begin... I'll head over to the
university library today
> (gotta love alumni library cards) and see what I can find for
> references on those codecs...
>
> Anyone have any hints on MSP430 implementation??

I downloaded ITU-T G.711, which (as several other documents I found
predicted) very cryptic and difficult to decipher. I found this nice
doc from Cypress that explains the theory (and the math!) behind
mu-law.

http://www.cypressmicro.com/support/appnotes/an2095.pdf

Just thought I'd post it in case anyone wants to add it to their
bookmarks.

Best Regards & Happy Holidays,
Dave


Fastest is a reverse binary search. If that is unclear I'll explain,
if 
it isn't my apologies for lessons in egg sucking.

Create a table of 256 word entries, assuming you have the memory, but 
this is easy. Each entry represents the highest (or lowest) 12 bit 
reading that encodes to the given A/u-law value. Start in the middle and 
do a convebntional binary search. using registers I estimate this takes 
under 12 cycles.

murray.newcastle.edu.au/users/staff/eemf/ELEC351/SProjects/hall/html/theorya.html

is a link to the A-law formulas. SPRA349 gives a TMS320 implementation.

Al

David Rea wrote:

> Quoting onestone <onestone@ones...>:
> 
> 
>>David why on earth are you throwing resolution away. by chopping off
>>the
>>lower 4 bits you are losing fine detail. this is absolutely the wrong
>>way to do it. What you should do is a 12 to 8 bit log compression, ie
>>u-Law or A-law. Thois retains all the fine detail in the low end and
>>spreads the compression losses into the high end. Your ear works like
>>this. It notices the absence of small detail, but doesn't
>>differentiate
>>so finely over large amplitude changes.
> 
> 
> OK, sounds good. [pun intended]
> 
> Now where to begin... I'll head over to the university library today
> (gotta love alumni library cards) and see what I can find for
> references on those codecs...
> 
> Anyone have any hints on MSP430 implementation??
> 
> Dave
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 



Memfault Beyond the Launch