how to extract audio volume level meter from audio stream ( PC(host) to Xmos device) ?

If you have a simple question and just want an answer.
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

how to extract audio volume level meter from audio stream ( PC(host) to Xmos device) ?

Postby johnsonyin » Fri Apr 14, 2017 9:50 am

Dear all
we are preparing for a project with xmos xu216 chip, a frontpanel will be used display audio volume. where can we extract audio volume level meter data? How to get them?

Do volsIn[ ] and volsOut[ ] use to save audio level meter data? Would you please give me some suggestions? thanks in advance!

int AudioClassRequests_2( )
{
/* Feature Units */
case FU_USBOUT:
case FU_USBIN:

/* Inspect Control Selector (CS) */
switch(sp.wValue >> 8)
{
case FU_VOLUME_CONTROL:

if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D)
{
/* Expect OUT here (with volume) */
if((result = XUD_GetBuffer(ep0_out, buffer, datalength)) != XUD_RES_OKAY)
{
return result;
}

if(unitID == FU_USBOUT)
{
if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT)
{
volsOut[ sp.wValue&0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8);
updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl );
return XUD_DoSetRequestStatus(ep0_in);
}
}
else
{
if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN)
{
volsIn[ sp.wValue&0xff ]= buffer[0] | (((int) (signed char) buffer[1]) << 8);
updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl );
return XUD_DoSetRequestStatus(ep0_in);
}
}
}
}
User avatar
mon2
XCore Expert
Posts: 664
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Postby mon2 » Fri Apr 14, 2017 12:53 pm

Review this project to get started:

http://www.xcore.com/viewtopic.php?t=5452
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

Postby johnsonyin » Sat Apr 15, 2017 9:50 am

Thanks for you information, mon2

int left = (int)samples_out[0];
int right = (int)samples_out[1];

you mean that samples_out[0] and samples_out[1] are left and right audio volume value. Is it right ?
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

Postby johnsonyin » Sat Apr 15, 2017 9:54 am

one more thing, what means? the following code, thanks!

if (timeafter(t_now, t_trig)){
unsigned mac_h, mac_l;
{mac_h, mac_l} = lmul(left_vu, MUL_PWR_100_DIV_2P32, 0, 0);
left_vu = mac_h;
{mac_h, mac_l} = lmul(right_vu, MUL_PWR_100_DIV_2P32, 0, 0);
right_vu = mac_h;
t_trig = t_now + (DECAY_TIME_UNIT_MS * 1000 * DECAY_TIME_CONSTANT_MS);
}
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

Postby johnsonyin » Tue Apr 18, 2017 9:00 am

Anyone else can give more messages about this topic, thanks!
User avatar
infiniteimprobability
XCore Expert
Posts: 801
Joined: Thu May 27, 2010 10:08 am
Contact:

Postby infiniteimprobability » Tue Apr 18, 2017 9:39 am

which bit is unclear?

When a timer reaches a certain value it calculates the next value of the decayed peak value. The defines are in there to set the rate at which the exponential decay occurs.

Take a look at the place where the defies are (see below). Hopefully this explains it.

Code: Select all

#define DECAY_TIME_CONSTANT_MS      300    //How many milliseconds to decay to 0.368
#define MUL_PWR_100_DIV_2P32        4252200097  //Value to multiple by (followed by div 2^32) 100 times
                                                //to get to 0.368 (ie. the time constant). Makes maths easy!
#define DECAY_TIME_UNIT_MS          1     //How often to do the delay calc. Can be anything > longest sample period


The decay is done using the built-in function for the MACS which is the fastest way to do a signed multiply. See xs1.h for the prototype of this.
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

Postby johnsonyin » Tue Apr 18, 2017 11:16 am

Hi infiniteimprobability

Thanks for your reply and messages,

i still have the following puzzled questions, would you please explain them, thanks again!

In README.txt of vu.zip, you wrote :

Finally, in audio.xc in sc_usb_audio, insert the following:
At the top of the file:
#include "vu_calc_inline.h"
At line number ~690, add the function call to VU calculation:
~~~~~~~~~~~~~~~~~~~~~snip~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef CODEC_MASTER /* Clock out the LR Clock, the DAC data and Clock in the next sample into ADC */
doI2SClocks(divide);
#endif
//Inline the VU calculation algo

vu_calc(samplesOut);

#ifdef
ADAT_TX TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1);
#endif


In other words, samplesOut[0] and samplesOut[1] in audio.xc are used to save audio volume value, Is it right?

what difference between left and left_vu in vu_calc( ) ?

what function is the below code ?

if (timeafter(t_now, t_trig)){
unsigned mac_h, mac_l;
{mac_h, mac_l} = lmul(left_vu, MUL_PWR_100_DIV_2P32, 0, 0);
left_vu = mac_h;
{mac_h, mac_l} = lmul(right_vu, MUL_PWR_100_DIV_2P32, 0, 0);
right_vu = mac_h;
t_trig = t_now + (DECAY_TIME_UNIT_MS * 1000 * DECAY_TIME_CONSTANT_MS);
}

one more thing, when i change windows audio volume, i find volsOut[ sp.wValue&0xff ] in int AudioClassRequests_2( ) will be changed, but volsOut no change while changing player volume, why ?
User avatar
infiniteimprobability
XCore Expert
Posts: 801
Joined: Thu May 27, 2010 10:08 am
Contact:

Postby infiniteimprobability » Tue Apr 18, 2017 12:45 pm

Code: Select all

In other words, samplesOut[0] and samplesOut[1] in audio.xc are used to save audio volume value, Is it right?

Not the volume scaling factor - they contain the actual sample value.

Code: Select all

what difference between left and left_vu in vu_calc( ) ?

Looks like left is only sent to xscope, so it debug only. You may delete it.

what function is the below code ?

Peak hold with decay

one more thing, when i change windows audio volume, i find volsOut[ sp.wValue&0xff ] in int AudioClassRequests_2( ) will be changed, but volsOut no change while changing player volume, why ?

Not sure, but for most cases (where mixer is not enabled) volumes are handled via shared memory variables "multOut" which are picked up in decouple.xc. This is where digital volume control is normally applied
johnsonyin
Member++
Posts: 16
Joined: Thu Nov 10, 2016 2:33 am

Postby johnsonyin » Thu Apr 20, 2017 8:52 am

thanks,infiniteimprobability

where can we get input audio volume data ? is it samplesIn_1[ ] ?
User avatar
infiniteimprobability
XCore Expert
Posts: 801
Joined: Thu May 27, 2010 10:08 am
Contact:

Postby infiniteimprobability » Thu Apr 20, 2017 9:07 am

Depends on wether you want the decibel volume value sent by the host or the calculated mutliplier which is used to scale the samples. Take a look in audiorequests.xc in the section that handles the FeatureUnit (volume) control requests:

Code: Select all

case FU_USBOUT:
            {
                /* Calc multipliers with 29 fractional bits from a db value with 8 fractional bits */
                /* 0x8000 is a special value representing -inf (i.e. mute) */
                unsigned master_vol = volsOut[0] == 0x8000 ? 0 : db_to_mult(volsOut[0], 8, 29);
                unsigned vol = volsOut[channel] == 0x8000 ? 0 : db_to_mult(volsOut[channel], 8, 29);

                x = longMul(master_vol, vol, 29) * !mutesOut[0] * !mutesOut[channel];

#ifdef OUT_VOLUME_IN_MIXER
                if (!isnull(c_mix_ctl))
                {
                    outuint(c_mix_ctl, SET_MIX_OUT_VOL);
                    outuint(c_mix_ctl, channel-1);
                    outuint(c_mix_ctl, x);
                    outct(c_mix_ctl, XS1_CT_END);
                }
#else
                asm("stw %0, %1[%2]"::"r"(x),"r"(p_multOut),"r"(channel-1));
#endif
                break;
            }

Return to “Q&A”

Who is online

Users browsing this forum: No registered users and 1 guest