Page 1 of 2

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

Posted: Fri Apr 14, 2017 9:50 am
by johnsonyin
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);
}
}
}
}

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

Posted: Fri Apr 14, 2017 12:53 pm
by mon2
Review this project to get started:

http://www.xcore.com/viewtopic.php?t=5452

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

Posted: Sat Apr 15, 2017 9:50 am
by johnsonyin
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 ?

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

Posted: Sat Apr 15, 2017 9:54 am
by johnsonyin
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);
}

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

Posted: Tue Apr 18, 2017 9:00 am
by johnsonyin
Anyone else can give more messages about this topic, thanks!

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

Posted: Tue Apr 18, 2017 9:39 am
by infiniteimprobability
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.

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

Posted: Tue Apr 18, 2017 11:16 am
by johnsonyin
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 ?

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

Posted: Tue Apr 18, 2017 12:45 pm
by infiniteimprobability

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

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

Posted: Thu Apr 20, 2017 8:52 am
by johnsonyin
thanks,infiniteimprobability

where can we get input audio volume data ? is it samplesIn_1[ ] ?

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

Posted: Thu Apr 20, 2017 9:07 am
by infiniteimprobability
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;
            }