Separate 4 channels one by one issue

New to XMOS and XCore? Get started here.
Bayanaa
Active Member
Posts: 33
Joined: Fri Feb 07, 2014 3:03 pm

Separate 4 channels one by one issue

Post by Bayanaa »

Hello there I am using xmos dj kit. I got 4 audio input channels. Now I want to separate them one by one and want to process on each channels, individually.

I guess audio signals come to here

audio(c_mix_out, null,null, c_adc);

but I have no idea how to separate each channels. I am new to xmos and xc programming.


Anyone pls share or guide me for writing its code in xc or c?


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

You can fit some a little bit of DSP in the decouple and audio cores, but it's safer to put the DSP in it's own processing core - you'll not have to worry about affecting the timing of other functions (such as I2S and buffer management) or breaking the ref design (as long as you keep to your MIPS budget). You will need to ensure MIDI and SPDIF are off, so you have a spare core to do this on the U6/U8.

There is an app note to do this here https://www.xmos.com/download/public/Ad ... n(1.0).pdf

We are in the process of updating this as there is an update to the source. So ensure you replace what's in the app note by this (if it isn't updated already - note check for underflow flag):

Code: Select all

  void dsp ( chanend c_aud_in, 
             chanend c_aud_out, 
             in port p_button_a, 
             in port p_button_b) {
     /* One larger for an "off" channel for mixer sources" */
    int samples[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1];
  
    timer ta, tb;
    unsigned time_a, time_b;
    unsigned button_a_val = 0, button_a_active = 1;
    unsigned biquad_offset = 0, button_b_active = 1, button_b_val = 0;
    unsigned bass_filter = 10;
    biquadState bs[NUM_USB_CHAN_OUT];
  
    // 20 is the central value (approx no-eq).
    // As values tend to the extremes, distortion will become more prevalent.
    // The spread of available values is defined in the Makefile where
    // the filter coefficients are set.
    // If a smaller coefficient array is used, these values will need to be adjusted.
    initBiquads(bs[0], 20);
    initBiquads(bs[1], 20);
    set_port_inv (p_button_a);
    set_port_inv (p_button_b);
    // zero samples buffer.
    for (int i=0;i<NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT;i++)
      {
        samples[i] = 0;
      }

    while(1){ //Implements channel protocol between decouple and audio cores
        inuint(c_audio);                    //Get sample request from audio
        outuint(c_decouple, 0);             //Send sample request to decouple
        if(testct(c_decouple)){             //Test for sample frequency change .
            command = inct(c_decouple);     //Get the CT and command - See commands.h
            value = inuint(c_decouple);     // Get command value from decouple core - normally SR value
            outct (c_audio, command);       //Send control token to audio (SR change)
            outuint (c_audio, value);       //Now send value to audio
            chkct (c_audio, XS1_CT_END);    //wait for handshake
            outct (c_decouple, XS1_CT_END); //Forward handshake to decouple
        }

        else{  // Normal audio loop
            underflow = inuint(c_decouple);   // Get confirmation from decouple indicating we're ready
            outuint (c_audio, underflow);     // Pass it on to audio

            if (!underflow) giveSamplesToDevice (c_audio, samples); //Only send audio if not in underflow
            getSamplesFromDevice (c_audio, samples);//Always get input samples from device and send to audio
            giveSamplesToHost (c_decouple, samples);//Always send samples to decouple
            if (!underflow) getSamplesFromHost (c_decouple, samples, bs);//Only get samples from decouple if no underflow
        }
      }
    }
  
      // The section below demonstrates how a user interface can
      // be used to change the EQ settings on the fly using the A and B buttons
      // on the L1 reference board.
  
      // Sample the buttons values with a timeout for debounce.
      // Button A changes the Bass shelf filter through 3 settings (cut, normal, boost)
      p_button_a :> button_a_val;
      if (button_a_val && button_a_active) {
        bass_filter = bs[0].desiredDb[0];
        bass_filter += 10;
        if (bass_filter > 30) {
          bass_filter = 10;
        }
        bs[0].desiredDb[0] = bass_filter;
        bs[1].desiredDb[0] = bass_filter;
        ta:>time_a;
        button_a_active = 0;
      }
  
      // Button B iterates over the 4 DSP presets
      // B will clear any changes made with button A.
      p_button_b :> button_b_val;
      if (button_b_val && button_b_active) {
        biquad_offset ++;
        biquad_offset &= 3;
        change_dsp(bs[0], biquad_offset);
        change_dsp(bs[1], biquad_offset);
        tb:>time_b;
        button_b_active = 0;
      }

::

      // 0.5s timeout on button press for B, 0.3s on A
      // Holding the buttons down will then iterate over the possible settings with this time period
      // between changes.
      select {
      case (button_b_active == 0 ) => tb when timerafter (time_b + 50000000) :> int _:
        button_b_active = 1;
        break;
      case (button_a_active == 0 ) => ta when timerafter (time_a + 30000000) :> int _:
        button_a_active = 1;
        break;
      default:
        break;
      }
    }
  }


Please note a bit of modification will be needed (this app note assumes you are using the L1 ref design) because there are no buttons on the DJ kit.

You can see from the code that the audio data will reside in the first NUM_USB_CHAN_OUT values of this array:

Code: Select all

int samples [ NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1];
Bayanaa
Active Member
Posts: 33
Joined: Fri Feb 07, 2014 3:03 pm

Post by Bayanaa »

Pls explain to more detail about applying dsp.

Also I cannot see any dsp function inside the sc_dsp_example.
Last edited by Bayanaa on Wed Mar 12, 2014 3:58 am, edited 1 time in total.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Pls explain to more detail about applying dsp.
Did you read the app note about applying dsp to the USB Audio ref design? This is 95% of what you need I think.. I'm happy to answer specific questions about the app note, but I would only be repeating what was written in there if I explained it in this thread.

The DSP is contained in our githib repo sc_dsp_filters here https://github.com/xcore/sc_dsp_filters, as explained on page 5.
Bayanaa
Active Member
Posts: 33
Joined: Fri Feb 07, 2014 3:03 pm

Post by Bayanaa »

From where did you get this code (dsp function)? I used it. Something like below:

Code: Select all

/* Decouple core */
        on tile[0]:
        {
//        	printstr("1st step is done\n");
        	set_thread_fast_mode_on();

            decouple(c_mix_out, null
#ifdef IAP
                , c_iap
#endif
            );
        }
        on tile[AUDIO_IO_CORE]:
        {
        	unsigned sampFreq = DEFAULT_FREQ;
//         printstr("2nd step is done\n");
         set_thread_fast_mode_on();
         dsp(c_mix_out,mix_out);
        }
        /* Audio I/O (pars additional S/PDIF TX thread) */ 
        on tile[AUDIO_IO_CORE]:
        {
//        	printstr("3rd step is done\n");
        	set_thread_fast_mode_on();
            audio(mix_out, null, null, c_adc);
        }
But problem is I cannot hear the audio. If I dont use the dsp function (only using decouper and audio function) I can listen sounds through computer.

Something wrong is inside dsp.
I also referred :http://www.iit.upcomillas.es/pfc/resume ... 1a2576.pdf
It also does not work.
I hope you have an idea or suggestion.
mmar
Experienced Member
Posts: 122
Joined: Fri Jul 05, 2013 5:55 pm

Post by mmar »

Hi,
you wrote about manipulate 4 in separately, but you need understand flow of audio data.

4 INS is in ADC converted to i2s and over audio function transfered to USB as PC audio source.
DSP maybe aplied to this way, but in demos is dsp aplied to outputs not inputs.

This input is secondary job of audio thread, primary is get data from USB over channel mix_out
and play it to DAC hardware i2s.

audio(mix_out, null, null, c_adc);
mix_out ... data to DAC
c_adc ... data from ADC

For understand see deliver function in audio.xc file.
Bayanaa
Active Member
Posts: 33
Joined: Fri Feb 07, 2014 3:03 pm

Post by Bayanaa »

@ infiniteimprobability

Adding-DSP-to-the-USB-Audio-2.0-L1-Reference-Design(1.0) is I think old
Adding-DSP-to-the-USB-Audio-2.0-L1-Reference-Design(1.1) is later, But in the source code part

Code: Select all

void dsp(chanend c_aud_in, chanend c_aud_out)
...

while (1)
	{
		unsigned x;
		inuint(c_audio); 
		outuint(c_decouple,0);
	if  (testct(c_aud_in))
	{ ...}
c_aud_in and c_aud_out is not used inside the while statement , instead c_audio and c_decouple are used. Of course I changed c_audio to c_aud_out..
this reference is not polite or it is nothing help for others.


I have another question.
Is there any change needed in decouple and audio function?

because even I apply dsp between decouple and audio nothing is happening.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Dear Bayanaa,
good spot - you are right. It's a typo - my apologies.

c_aud_in = c_decouple
and
c_aud_out = c_audio

I'll get it updated and re-issue.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

I have another question.
Is there any change needed in decouple and audio function?

because even I apply dsp between decouple and audio nothing is happening.
No - there should be no change needed. It's the whole point of putting the DSP task in between these two tasks - they should remain the same (no ref design code change or API change).

When you say you get no audio - does the device enumerate and can you see it/change sample rate etc from the host?
If you break the chain from decouple to audio it tends to be fatal for the whole device. So if it is still coming up as a USB audio device but just no audio, it's possible something is wrong with the DSP bit - I would recommend trying bypassing DSP calls in getSamplesFromHost(chanend c, int samples[], biquadState bs[])
and just pass samples straight over to check that the dsp core is passing data to/from decouple/audio OK.

Something like:

Code: Select all

// sample = biquadAsm(l_samp[i],bs[i]);
          samples[i] = l_samp[i];
User avatar
millenliam
Member++
Posts: 23
Joined: Fri Feb 14, 2014 2:51 pm
Contact:

Post by millenliam »

Hey

Sorry to hijack this thread, but like Bayanaa I've been attempting to add some DSP to my USB audio app using the USB Audio reference app note and the example code provided above, though I've taken out the filtering code as I'm trying understand where in the audio chain I can add my own DSP code.

However when trying to compile the code I'm getting three undeclared variables within dsp() - command, value, and underflow:

Code: Select all

…
command = inct (c_decouple); // Get the CT and command - See commands.h
value = inuint (c_decouple); // Get command value from decouple core - normally SR value
…
…
…
underflow = inuint (c_decouple); // Get confirmation from decouple indicating we're ready
…
Where are these variables meant to be declared?

Thanks,
Liam.
Post Reply