What's wrong with these interfaces? Topic is solved

If you have a simple question and just want an answer.
Post Reply
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

What's wrong with these interfaces?

Post by shaileshwankhede »

I am having one parallel task inside which I am creating an instance of my interface and passing it to client and interface task. Client task is about filling some buffer and once buffer is filled it is passing it to server end. Server task has some processing on that buffer. But when I run this, execution seems to stuck in client only and debugging also getting terminated after one point. However if I send simple integer value without any buffer filling calculation from client task, then it is successfully received server end. I am not getting what is wrong over here? Below is my code:

Code: Select all

#define BUFFER_SIZE           1024
interface dsp_interface {
    void dsp_realTimeData(int32_t buff[NUM_USB_CHAN_IN][BUFFER_SIZE]);
    void dsp_complexTimeData(dsp_complex_t buff[NUM_USB_CHAN_IN][BUFFER_SIZE]);
};

Code: Select all

void bufferData(client interface dsp_interface i, mic_array_frame_time_domain * unsafe audio)
{
    //continous buffer and send data when buffer full
    static uint16_t wrIdx = 0;
    uint8_t normalizationFactor = 4;
    int32_t circBuffer[NUM_USB_CHAN_IN][BUFFER_SIZE];

    unsafe {
        for(unsigned i=0; i<num_of_mic; i++)
        {
            circBuffer[i][wrIdx] = audio->data[i][0]/normalizationFactor;
        }
    }
    if(wrIdx < BUFFER_SIZE-1)
        wrIdx++;
    else {
        wrIdx = 0;
        i.dsp_realTimeData(circBuffer);     //send buffered data
    }
}

Code: Select all

void soundLocalization(server interface dsp_interface i)
{
    //perform sound localization algorithm
    select {
        case i.dsp_realTimeData(int32_t buff[NUM_USB_CHAN_IN][BUFFER_SIZE]):
            {
                //...Code...                    //Doesn't come here!!!
           }
            break;
        case i.dsp_complexTimeData(dsp_complex_t buff[NUM_USB_CHAN_IN][BUFFER_SIZE]):
            break;
    }
}

Code: Select all

unsafe void user_pdm_process_timeFrames(mic_array_frame_time_domain * unsafe audio)
{
    /*Apply algorithm to time domain input frames*/
    interface dsp_interface i;
    par {
        bufferData(i, audio);
        soundLocalization(i);
    }
}
Thanks,
Shailesh


View Solution
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

Hi Shailesh,

I can't see anything too obvious, other than the fact that there isn't enough of a loop to fill your buffer so that it will be sent. I've taken your code and simplified it down a bit (and ensured everything was looping) and it works fine for me. Hopefully you can try this and spot what isn't working in your version:

Code: Select all

#include <platform.h>
#include <print.h>

#define NUM_USB_CHAN_IN 2
#define BUFFER_SIZE     1024
interface dsp_interface {
    void dsp_realTimeData(int buff[NUM_USB_CHAN_IN][BUFFER_SIZE]);
};

void bufferData(client interface dsp_interface i)
{
    //continous buffer and send data when buffer full
    int wrIdx = 0;
    int circBuffer[NUM_USB_CHAN_IN][BUFFER_SIZE];

    while (1) {
      unsafe {
          for(unsigned i=0; i<NUM_USB_CHAN_IN; i++)
          {
              circBuffer[i][wrIdx] = i;
          }
      }
      if(wrIdx < BUFFER_SIZE-1)
          wrIdx++;
      else {
          wrIdx = 0;
          i.dsp_realTimeData(circBuffer);     //send buffered data
      }
    }
}

void soundLocalization(server interface dsp_interface i)
{
  while(1) {
    //perform sound localization algorithm
    select {
        case i.dsp_realTimeData(int buff[NUM_USB_CHAN_IN][BUFFER_SIZE]):
            {
              printstr("Here\n");
           }
            break;
    }
  }
}

int main()
{
    /*Apply algorithm to time domain input frames*/
    interface dsp_interface i;
    par {
        bufferData(i);
        soundLocalization(i);
    }
    return 0;
}
Then compile:

Code: Select all

xcc -target=XCORE-200-EXPLORER main.xc -o test.xe
Then run:

Code: Select all

xsim test.xe
or

Code: Select all

xrun --io test.xe
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

Post by shaileshwankhede »

Sorry I forgot to mention, function user_pdm_process_timeFrames is itself running in loop. Then I don't require again looping for bufferData and soundLocalization, right? It's coming like par inside par. Is it allowed?

Below is modified code of pcm_pdm_mic

Code: Select all

chan c;

    par
    {
        mic_array_pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1);
        mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_0, c_ds_output[0]);
        mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1]);
        pdm_process(c_ds_output, c_pcm_out, c);
        pdm_process_timeFrames(c);     
    }

Code: Select all

void pdm_process_timeFrames(chanend c)   //getting mic_array_frame_time_domain from pdm_process
{
    mic_array_frame_time_domain * unsafe f;
    while(1) {
        unsafe {
            c :> f;
            user_pdm_process_timeFrames(f);
        }
    }
}
I will recheck code what's going wrong.

Thanks,
Shailesh
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

Post by shaileshwankhede »

I figured out one thing. If I send some dummy value to server continuously instead of sending it once buffer complete, program executes continuously and data is received server side. But if I add one statement to send some value once buffer is filled (means after every 128ms for 8KHz sampling rate and 1024 samples), programs halts after some time. It shows 'No source available for "__start_other_cores() " ' if pressed suspend in debug process. I even tried lowering number of samples to 128, but that didn't help.

My aim is to use buffer for processing once it is filled. During processing, filling of buffer should not stop, it should run parallel. Is there any other way to do this?

Thanks,
Shailesh
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

What's your mic array frame size configured to? If it's just 1 sample, why not set it up for 1024-sample frames and then your processing gets the buffer size it needs?
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

Post by shaileshwankhede »

This I already thought of changing mic array frame size. With this method I will get required data for processing. But problem here is for seamless usb audio functionality, we again need to loop and get individual sample values from mic frames, which then need to send over chanend c_audio in pdm_process of pcm_pdm_mic.xc. This is because we cannot send array over channel. With looping I couldn't get audio recorded for different frame size. If we try to use interface for this purpose then I think again same problem will occur (Haven't tested!).

As mentioned:

Code: Select all

chan c;

    par
    {
        mic_array_pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1);
        mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_0, c_ds_output[0]);
        mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1]);
        pdm_process(c_ds_output, c_pcm_out, c); //usb audio functionality for conference application
        pdm_process_timeFrames(c);     //Sound localization algorithm to detect speaker direction
    }
Both pdm_process and pdm_process_timeFrames should work seamlessly. With current architecture pdm_process_timeFrames is interrupting pdm_process.

Thanks,
Shailesh
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

I see what the problem is now. Your processing is block based and USB is essentially sample based. Mic array can be either block or sample. So you will need block-to-sample or sample-to-block conversion in your system.
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

Post by shaileshwankhede »

How do I use or from where I get block-to-sample or sample-to-block conversion ? Is it with sample rate conversion library lib_src? I checked but I think what it will do is downsample to single sample instead of getting one-one sample from block.

Thanks,
Shailesh
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

There isn't an off the shelf S2B or B2S component from XMOS, I'm afraid
shaileshwankhede
Experienced Member
Posts: 65
Joined: Fri Dec 02, 2016 1:30 pm

Post by shaileshwankhede »

Hi,

I got the root problem with my source code with interfaces.
Problem is user_pdm_process_timeFrames() is called periodically and inside this function I am initializing interface which will destroy once function exits.
To fix I am now initializing interface inside pcm_pdm_mic() and then passing it to pdm_process_timeFrames() which has looping to execute user_pdm_process_timeFrames continuously.
Another problem is for all 'Select' statement, I haven't put Default break case, so that program should not halt there till required case function is not fired by server.\
Now code is working as expected.

Thanks,
Shailesh
Post Reply