CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

DSPIC volume control

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

DSPIC volume control
PostPosted: Fri Dec 04, 2009 5:36 am     Reply with quote

Hi all,

I have a project that plays back wav files stored in a microSD though the dspic audio dac.

Is there a way to control the volume in software so as to avoid the external trimmer?
yerpa



Joined: 19 Feb 2004
Posts: 58
Location: Wisconsin

View user's profile Send private message Visit poster's website

PostPosted: Fri Dec 04, 2009 10:34 am     Reply with quote

Before you output your sample to the DAC, multiply it by a number between zero and one. If the multiplier is near zero, the volume will be near zero, too. If the multiplier equals one, you get your full volume sample thru the DAC.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Mon Dec 07, 2009 12:36 am     Reply with quote

Thanks for the reply!

I do not get this. Between 0 and 1 there is only 0 and 1. So how can I be near 0 or near 1? Also keep in mind that my wav is signed, I read 2 bytes from the sd card and then make a 16 bit word that feeds the dac.
I guess that I should multiply the resulting 16bit word. Right?
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Mon Dec 07, 2009 1:35 am     Reply with quote

Multiply 16bit word with value between 0 and 1 means do it in float. You could also divide the value (same thing). Wink
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Dec 07, 2009 11:10 am     Reply with quote

Multiply by a byte from 0 to 255, then shift right 4 bits. The result is to get volume from 0 to 16X. No floats, no real divide.
_________________
The search for better is endless. Instead simply find very good and get the job done.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Tue Dec 08, 2009 12:22 am     Reply with quote

OK, thanks for this. I will try it today! As about the first method, multiply with 0.5 for example, it takes up too much time of the cpu and I have to increase the clock to catch up with the sample rate.

I will try Multiply by a byte from 0 to 255, then shift right 4 bits and let you know. Thanks everybody!
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 1:27 am     Reply with quote

Hi!

The multiply and shift method gives me distortion!
Below you can see a short version of the audio code:
Code:

int8 low_byte,high_byte;
int16 audio;

low_byte=spi_read(255);   //read low byte from SD card   
high_byte=spi_read(255);  //read high byte from SD card

audio=make16(high_byte,low_byte);  // combine the 2 bytes to make 16bit word
   
while(bit_test(DAC1STAT,9));  // wait for dac fifo to empty
DAC1LDAT=audio;               // feed the dac

Please give me ideas for adjusting the volume.

Thanks.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 3:22 am     Reply with quote

Quote:
The multiply and shift method gives me distortion!
It's most likely a problem of your implementation. The data has to be converted to int32 to multiply without overflow.
Also *255/16 can only give correct results for input magnitudes < 1/16 of full scale. Usually, a digital volume control
doesn't involve a gain > 1.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 4:05 am     Reply with quote

FvmM you are right.

I found it.

DAC1LDAT=(audio/100)*desired_volume

First I divide so the result fits in 16bits.

This way I have 100 steps of volume Smile
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 6:19 am     Reply with quote

Quote:
First I divide so the result fits in 16bits.
An you reduce 16 Bit CD quality to poor 9 bit Sad

The above suggested right shift (if applied correctly, with int32 intermediate result) is almost
keeping the sound quality and most likely introduces less computational effort than a divide operation.
If you are required to use a decimal percent factor, there are still ways to avoid a divide. You should particularly
consider, that dsPIC does fast multiply.
Code:
output = (int16)(((int32)input*655*n)>>16); { n = 0..100}
can be a possible replacement. With CCS compilers, the correct implementation of int16/int32
conversion should be checked thoroughly, there are many oddities, but it's basically O.K. with PCD, I think.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 7:36 am     Reply with quote

I tried this:

output = (int16)(((int32)input*655*n)>>16); { n = 0..100}

It works perfectly! Can you please explain the syntax of this?
And why *655?

Thanks
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Dec 10, 2009 7:55 am     Reply with quote

The input is extended to int32 to allow succeding multiply without overflow. The basic idea is to replace /100 by *655/65536 (actually /100.05), where /65536 can be replaced by >>16 (shift right 16) respectively using the high word of an int32 structure.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group