All of lore.kernel.org
 help / color / mirror / Atom feed
* capture with non-interleaved mode
@ 2003-10-14 11:56 Cyril.Coquilleau@UTBM.fr
  2003-10-14 12:19 ` Paul Davis
  0 siblings, 1 reply; 7+ messages in thread
From: Cyril.Coquilleau@UTBM.fr @ 2003-10-14 11:56 UTC (permalink / raw)
  To: alsa-devel

Hi. I'm developping a signal processing program which needs to compute data 
from each channel of soundcards separately. 
After searches I found that I must open the soundcard with the 
SND_PCM_ACCESS_RW_NONINTERLEAVED flag but it doesn't works well : for each 
readn operation i get the -32 error code . Meanwhile, I tested capture in 
interleaved mode and it works well.
I had to use hw:x,y for the interleaved capture and plughw:x,y for the non-
interleaved capture, I don't know if non-interleaved capture works with hw:x,y.

Any advice (or piece of source code) ?

Thanks,

Cyril Coquilleau


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
  2003-10-14 11:56 capture with non-interleaved mode Cyril.Coquilleau@UTBM.fr
@ 2003-10-14 12:19 ` Paul Davis
  2003-10-14 15:30   ` Cyril.Coquilleau@UTBM.fr
  0 siblings, 1 reply; 7+ messages in thread
From: Paul Davis @ 2003-10-14 12:19 UTC (permalink / raw)
  To: Cyril.Coquilleau@UTBM.fr; +Cc: alsa-devel

>Hi. I'm developping a signal processing program which needs to compute data 
>from each channel of soundcards separately. 
>After searches I found that I must open the soundcard with the 
>SND_PCM_ACCESS_RW_NONINTERLEAVED flag but it doesn't works well : for each 
>readn operation i get the -32 error code . Meanwhile, I tested capture in 
>interleaved mode and it works well.
>I had to use hw:x,y for the interleaved capture and plughw:x,y for the non-
>interleaved capture, I don't know if non-interleaved capture works with hw:x,y.

[ We need a FAQ ... ]

ALSA's "hw" devices can only be used with parameters that match
capabilities offered by the underlying hardware. There's not much
hardware out there that supports non-interleaved I/O, so as a result,
most "hw" devices can't do this. The Hammerfall and ice1712 series are
notable exceptions. But there is a corollary: if you were using a
hammerfall, the "hw" device cannot do interleaved I/O either.

as to your error, its probably a bug in your code. JACK uses
non-interleaved mode by default, and it works with both plughw and hw
models of many different kinds. if you posted the relevant parts of it
here, somebody can probably help you.


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
  2003-10-14 12:19 ` Paul Davis
@ 2003-10-14 15:30   ` Cyril.Coquilleau@UTBM.fr
  2003-10-14 16:05     ` Takashi Iwai
  0 siblings, 1 reply; 7+ messages in thread
From: Cyril.Coquilleau@UTBM.fr @ 2003-10-14 15:30 UTC (permalink / raw)
  To: alsa-devel

> >Hi. I'm developping a signal processing program which needs to compute data
> 
> >from each channel of soundcards separately. 
> >After searches I found that I must open the soundcard with the 
> >SND_PCM_ACCESS_RW_NONINTERLEAVED flag but it doesn't works well : for each
> 
> >readn operation i get the -32 error code . Meanwhile, I tested capture in 
> >interleaved mode and it works well.
> >I had to use hw:x,y for the interleaved capture and plughw:x,y for the
> non-
> >interleaved capture, I don't know if non-interleaved capture works with
> hw:x,y.
> 
> [ We need a FAQ ... ]
> 
> ALSA's "hw" devices can only be used with parameters that match
> capabilities offered by the underlying hardware. There's not much
> hardware out there that supports non-interleaved I/O, so as a result,
> most "hw" devices can't do this. The Hammerfall and ice1712 series are
> notable exceptions. But there is a corollary: if you were using a
> hammerfall, the "hw" device cannot do interleaved I/O either.
> 
> as to your error, its probably a bug in your code. JACK uses
> non-interleaved mode by default, and it works with both plughw and hw
> models of many different kinds. if you posted the relevant parts of it
> here, somebody can probably help you.
> 
> 

I join the relevant parts of the source (without error handlers) :

#define BUF_SIZE 128

struct snd_card
{
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;

  short inputBuffer[BUF_SIZE*2];  
  void *buffer[2];
};
typedef struct snd_card snd_card_t;

int 
main (....)
{
  char card_id[32];
  int err;
  itn card = 0;
  snd_card_t *card1;
  
  card1 = calloc(1,sizeof(snd_card_t));
  card1->buffer[0] = card1->inputBuffer;
  card1->buffer[1] = &card1->inputBuffer[BUF_SIZE];
  snprintf (card_id, 32, "plughw:%d", card);
  
  snd_pcm_open (&card1->handle, card_id, SND_PCM_STREAM_CAPTURE, 0);
  snd_pcm_hw_params_malloc (&card1->params);
  snd_pcm_hw_params_any (card1->handle, card1->params);
  snd_pcm_hw_params_set_channels (card1->handle, card1->params, 2);
  snd_pcm_hw_params_set_access (card1->handle, card1->params,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
  snd_pcm_hw_params_set_format (card1->handle, card1->params,
SND_PCM_FORMAT_S16_LE);
  snd_pcm_hw_params_set_rate_near (card1->handle, card1->params, ECHANT, 0);
  snd_pcm_hw_params (card1->handle, card1->params);
  snd_pcm_hw_params_free (card1->params);
  snd_pcm_prepare (card1->handle);

  while (...)
  {
    err = snd_pcm_readn (card1->handle, card1->buffer, BUF_SIZE);
    printf("err=%d, buff=%d\n", err, card1->buffer[0]);
    ...
  }
 ...
}



And here is the result of printf 
err=-32, buff=-1
err=-32, buff=-1
err=-32, buff=-1
err=-32, buff=-1
err=-32, buff=-1


If you see the problem...


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
  2003-10-14 15:30   ` Cyril.Coquilleau@UTBM.fr
@ 2003-10-14 16:05     ` Takashi Iwai
  2003-10-15 19:09       ` Cyril.Coquilleau@UTBM.fr
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Iwai @ 2003-10-14 16:05 UTC (permalink / raw)
  To: Cyril.Coquilleau@UTBM.fr; +Cc: alsa-devel

At Tue, 14 Oct 2003 17:30:40 +0200,
Cyril.Coquilleau@UTBM.fr wrote:
> 
> > >Hi. I'm developping a signal processing program which needs to compute data
> > 
> > >from each channel of soundcards separately. 
> > >After searches I found that I must open the soundcard with the 
> > >SND_PCM_ACCESS_RW_NONINTERLEAVED flag but it doesn't works well : for each
> > 
> > >readn operation i get the -32 error code . Meanwhile, I tested capture in 
> > >interleaved mode and it works well.
> > >I had to use hw:x,y for the interleaved capture and plughw:x,y for the
> > non-
> > >interleaved capture, I don't know if non-interleaved capture works with
> > hw:x,y.
> > 
> > [ We need a FAQ ... ]
> > 
> > ALSA's "hw" devices can only be used with parameters that match
> > capabilities offered by the underlying hardware. There's not much
> > hardware out there that supports non-interleaved I/O, so as a result,
> > most "hw" devices can't do this. The Hammerfall and ice1712 series are
> > notable exceptions. But there is a corollary: if you were using a
> > hammerfall, the "hw" device cannot do interleaved I/O either.
> > 
> > as to your error, its probably a bug in your code. JACK uses
> > non-interleaved mode by default, and it works with both plughw and hw
> > models of many different kinds. if you posted the relevant parts of it
> > here, somebody can probably help you.
> > 
> > 
> 
> I join the relevant parts of the source (without error handlers) :
> 
> #define BUF_SIZE 128
> 
> struct snd_card
> {
>   snd_pcm_t *handle;
>   snd_pcm_hw_params_t *params;
> 
>   short inputBuffer[BUF_SIZE*2];  
>   void *buffer[2];
> };
> typedef struct snd_card snd_card_t;
> 
> int 
> main (....)
> {
>   char card_id[32];
>   int err;
>   itn card = 0;
>   snd_card_t *card1;
>   
>   card1 = calloc(1,sizeof(snd_card_t));
>   card1->buffer[0] = card1->inputBuffer;
>   card1->buffer[1] = &card1->inputBuffer[BUF_SIZE];
>   snprintf (card_id, 32, "plughw:%d", card);
>   
>   snd_pcm_open (&card1->handle, card_id, SND_PCM_STREAM_CAPTURE, 0);
>   snd_pcm_hw_params_malloc (&card1->params);
>   snd_pcm_hw_params_any (card1->handle, card1->params);
>   snd_pcm_hw_params_set_channels (card1->handle, card1->params, 2);
>   snd_pcm_hw_params_set_access (card1->handle, card1->params,
> SND_PCM_ACCESS_RW_NONINTERLEAVED);
>   snd_pcm_hw_params_set_format (card1->handle, card1->params,
> SND_PCM_FORMAT_S16_LE);
>   snd_pcm_hw_params_set_rate_near (card1->handle, card1->params, ECHANT, 0);
>   snd_pcm_hw_params (card1->handle, card1->params);
>   snd_pcm_hw_params_free (card1->params);
>   snd_pcm_prepare (card1->handle);
> 
>   while (...)
>   {
>     err = snd_pcm_readn (card1->handle, card1->buffer, BUF_SIZE);
>     printf("err=%d, buff=%d\n", err, card1->buffer[0]);
>     ...
>   }
>  ...
> }
> 
> 
> 
> And here is the result of printf 
> err=-32, buff=-1

-32 is EPIPE.  it's likely buffer under/overrun.


Takashi


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
  2003-10-14 16:05     ` Takashi Iwai
@ 2003-10-15 19:09       ` Cyril.Coquilleau@UTBM.fr
  2003-10-16 12:04         ` Paul Davis
  0 siblings, 1 reply; 7+ messages in thread
From: Cyril.Coquilleau@UTBM.fr @ 2003-10-15 19:09 UTC (permalink / raw)
  To: alsa-devel

> > > >Hi. I'm developping a signal processing program which needs to compute
> data
> > > 
> > > >from each channel of soundcards separately. 
> > > >After searches I found that I must open the soundcard with the 
> > > >SND_PCM_ACCESS_RW_NONINTERLEAVED flag but it doesn't works well : for
> each
> > > 
> > > >readn operation i get the -32 error code . Meanwhile, I tested capture
> in 
> > > >interleaved mode and it works well.
> > > >I had to use hw:x,y for the interleaved capture and plughw:x,y for the
> > > non-
> > > >interleaved capture, I don't know if non-interleaved capture works
> with
> > > hw:x,y.
> > > 
> > > [ We need a FAQ ... ]
> > > 
> > > ALSA's "hw" devices can only be used with parameters that match
> > > capabilities offered by the underlying hardware. There's not much
> > > hardware out there that supports non-interleaved I/O, so as a result,
> > > most "hw" devices can't do this. The Hammerfall and ice1712 series are
> > > notable exceptions. But there is a corollary: if you were using a
> > > hammerfall, the "hw" device cannot do interleaved I/O either.
> > > 
> > > as to your error, its probably a bug in your code. JACK uses
> > > non-interleaved mode by default, and it works with both plughw and hw
> > > models of many different kinds. if you posted the relevant parts of it
> > > here, somebody can probably help you.
> > > 
> > > 
> > 
> > I join the relevant parts of the source (without error handlers) :
> > 
> > #define BUF_SIZE 128
> > #define ECHANT 44100
> > 
> > struct snd_card
> > {
> >   snd_pcm_t *handle;
> >   snd_pcm_hw_params_t *params;
> > 
> >   short inputBuffer[BUF_SIZE*2];  
> >   void *buffer[2];
> > };
> > typedef struct snd_card snd_card_t;
> > 
> > int 
> > main (....)
> > {
> >   char card_id[32];
> >   int err;
> >   itn card = 0;
> >   snd_card_t *card1;
> >   
> >   card1 = calloc(1,sizeof(snd_card_t));
> >   card1->buffer[0] = card1->inputBuffer;
> >   card1->buffer[1] = &card1->inputBuffer[BUF_SIZE];
> >   snprintf (card_id, 32, "plughw:%d", card);
> >   
> >   snd_pcm_open (&card1->handle, card_id, SND_PCM_STREAM_CAPTURE, 0);
> >   snd_pcm_hw_params_malloc (&card1->params);
> >   snd_pcm_hw_params_any (card1->handle, card1->params);
> >   snd_pcm_hw_params_set_channels (card1->handle, card1->params, 2);
> >   snd_pcm_hw_params_set_access (card1->handle, card1->params,
> > SND_PCM_ACCESS_RW_NONINTERLEAVED);
> >   snd_pcm_hw_params_set_format (card1->handle, card1->params,
> > SND_PCM_FORMAT_S16_LE);
> >   snd_pcm_hw_params_set_rate_near (card1->handle, card1->params, ECHANT,
> 0);
> >   snd_pcm_hw_params (card1->handle, card1->params);
> >   snd_pcm_hw_params_free (card1->params);
> >   snd_pcm_prepare (card1->handle);
> > 
> >   while (...)
> >   {
> >     err = snd_pcm_readn (card1->handle, card1->buffer, BUF_SIZE);
> >     printf("err=%d, buff=%d\n", err, card1->buffer[0]);
> >     ...
> >   }
> >  ...
> > }
> > 
> > 
> > 
> > And here is the result of printf 
> > err=-32, buff=-1
> 
> -32 is EPIPE.  it's likely buffer under/overrun.
> 
> 

I've not managed to fix this bug into my program... Do you see the error on my 
code (bad soundcard initialization or other) or have you got another way to 
propose me to capture the two channels of my soundcard separately ?

Cyril


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
  2003-10-15 19:09       ` Cyril.Coquilleau@UTBM.fr
@ 2003-10-16 12:04         ` Paul Davis
  0 siblings, 0 replies; 7+ messages in thread
From: Paul Davis @ 2003-10-16 12:04 UTC (permalink / raw)
  To: Cyril.Coquilleau@UTBM.fr; +Cc: alsa-devel

>I've not managed to fix this bug into my program... Do you see the error on my
> 
>code (bad soundcard initialization or other) or have you got another way to 
>propose me to capture the two channels of my soundcard separately ?

try increasing BUF_SIZE to 4096 and see what happens. 128
frames/period is in seriously low-latency territory, and i doubt that
your program is designed for that. if i was to make a guess, you
probably try to write to disk after reading from the audio interface,
in the same thread, yes? sorry, you can't do that for 128
frames/period, and a general design rule, you shouldn't ever do it
(though it obviously works for some simple programs with just stereo
in).

--p


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: capture with non-interleaved mode
@ 2003-10-19 19:46 Cyril.Coquilleau@UTBM.fr
  0 siblings, 0 replies; 7+ messages in thread
From: Cyril.Coquilleau@UTBM.fr @ 2003-10-19 19:46 UTC (permalink / raw)
  To: alsa-devel


Hi !

I managed to capture sound but I have a problem due to the stereo. It is
impossible to capture data of channels separately.

I made a test for that : I have generated a sound with a square frequency of
2000 Hz in the left channel and a square frequency of 6000 Hz in the right
channel. And when I capture this sound I only have the sound of the right
channel : in the buffer I have the data of the right channel, but the data of
the left channel is replaced the right one.
I think that the stereo is taken only from the right channel (the signal is
exactly the same at the same time).

I join you the source of my program, if see the error...



#define BUF_SIZE 4096
#define ECHANT 44100
#define LASTING 10000

struct snd_card
{
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;

  char *name;
  char *card_id;  

  short inputBuffer[BUF_SIZE*2];  
  void *buffer[2];
};

typedef struct snd_card snd_card_t;


/////////////////////////////////
// Assigns a card to the program
snd_card_t*
assign_card (int card)
{
  char card_id[32];
  int err;
  snd_card_t *returned_card;
  returned_card = calloc(1,sizeof(snd_card_t));

  // Initialize the buffer
  returned_card->buffer[0] = returned_card->inputBuffer;
  returned_card->buffer[1] = &returned_card->inputBuffer[BUF_SIZE];
  
  snprintf (card_id, 32, "plughw:%d", card);
  returned_card->card_id = strdup(card_id);

  // I removed the error handlers
  snd_pcm_open (&returned_card->handle, returned_card->card_id,
SND_PCM_STREAM_CAPTURE, 0);
  snd_pcm_hw_params_malloc (&returned_card->params);
  snd_pcm_hw_params_any (returned_card->handle, returned_card->params);
  //2 for the two channels for stereo
  snd_pcm_hw_params_set_channels (returned_card->handle, returned_card->params, 2);
  snd_pcm_hw_params_set_access (returned_card->handle, returned_card->params,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
  snd_pcm_hw_params_set_format (returned_card->handle, returned_card->params,
SND_PCM_FORMAT_S16_LE);
  snd_pcm_hw_params_set_rate_near (returned_card->handle, returned_card->params,
ECHANT, 0);
  snd_pcm_hw_params (returned_card->handle, returned_card->params);
  snd_pcm_hw_params_free (returned_card->params);
  snd_pcm_prepare (returned_card->handle);
  return returned_card;
}


///////////////////////////////////////////////////// 
// Main 
int 
main (int argc, char *argv[]) 
{
  int i=0;
  int err;
  int card_number = 0;
  snd_card_t *card1;
 
  card1 = assign_card(card_number);

  for (i=0; i<LASTING; i++) 
  {
    err = snd_pcm_readn (card1->handle, card1->buffer, BUF_SIZE);
     
    if (err >= BUF_SIZE) 
    {
      // Write the content of the buffer into a file to examine the content
    } // End of treatment of the two channels
    else if (err == -EPIPE) 
    {     
      printf("Under-Run \n");
      // under-run 
      snd_pcm_prepare (card1->handle);
    } 
    else if (err == -ESTRPIPE) 
    {
      
      while ((err = snd_pcm_resume (card1->handle)) == -EAGAIN)
        sleep(1);       // wait until the suspend flag is released
	
      if (err < 0) 
        snd_pcm_prepare (card1->handle);  // prepare again to read
    }
  }
  
  snd_pcm_close (card1->handle);
  return 0;
}



And here is a very small part of the text file obtained, we see the data of left
channel is always the same as the right (altough the frequencies of each channel
are differents).

LEFT CHANNEL  ----   RIGHT CHANNEL
    
buff=25531    ----    25448
buff=29062    ----    29024
buff=28990    ----    28953
buff=25640    ----    25564
buff=27761    ----    27714
buff=-31412    ----    -31364
buff=-29466    ----    -29392
buff=-32110    ----    -32067
buff=-32600    ----    -32571
buff=30326    ----    30317
buff=28573    ----    28537
buff=30212    ----    30202
buff=31043    ----    31031
buff=28114    ----    28063
buff=32445    ----    32458



Cyril Coquilleau


-------------------------------------------------------
This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo
The Event For Linux Datacenter Solutions & Strategies in The Enterprise 
Linux in the Boardroom; in the Front Office; & in the Server Room 
http://www.enterpriselinuxforum.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-10-19 19:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 11:56 capture with non-interleaved mode Cyril.Coquilleau@UTBM.fr
2003-10-14 12:19 ` Paul Davis
2003-10-14 15:30   ` Cyril.Coquilleau@UTBM.fr
2003-10-14 16:05     ` Takashi Iwai
2003-10-15 19:09       ` Cyril.Coquilleau@UTBM.fr
2003-10-16 12:04         ` Paul Davis
2003-10-19 19:46 Cyril.Coquilleau@UTBM.fr

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.