All of lore.kernel.org
 help / color / mirror / Atom feed
* [Alsa-devel] Read the input of a soundcard with ALSA
@ 2007-04-20 15:20 Nyx
       [not found] ` <4628FD65.4020407@gmail.com>
  0 siblings, 1 reply; 5+ messages in thread
From: Nyx @ 2007-04-20 15:20 UTC (permalink / raw)
  To: alsa-devel, alsa-devel

Hi,

I have some problems to read the input of my soundcard using Alsa and I
don't really understand how to have access to the input of my soundcard.
I follow :
http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2latency_8c-example.html

# So, in my program, I have created two handles for capture and playback :
char *device = "hw:0,0";
snd_output_t *output;
snd_input_t *input;
snd_pcm_t *phandle, *chandle;

# then I connect the phandle to the out
err = snd_output_stdio_attach(&output, stdout, 0);
if (..)

# Do I have to connect the chandle with the input ?
# err = snd_input_stdio_attach(&input, stdin, 0);

# I open the access to PCM
err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)
if (..)
err = snd_pcm_open(&chandle, pdevice, SND_PCM_STREAM_CAPTURE, 0)
if(..)

# Hardware and software Parameters
## Hardware Parameters
snd_pcm_hw_params;
int err;

err = snd_pcm_hw_params_any(phandle, params); if(..);
err = snd_pcm_hw_params_set_access(phandle,
params,SND_PCM_ACCESS_RW_INTERLEAVED); if(..);
err = snd_pcm_hw_params_set_format(phandle, params,SND_PCM_FORMAT_S16);
if(..);
err = snd_pcm_hw_params_set_channels(phandle, params, 1); if(..);
err = snd_pcm_hw_params_set_rate_near(phandle, params, 44100, 0); if(..);
err = snd_pcm_hw_params_set_buffer_time_near(phandle, params, 500000, &dir);
if(..);
err = snd_pcm_hw_params_set_time_near(phandle, params, 100000, &dir),
if(..);
err = snd_pcm_hw_params(phandle, params);

##Software parameters
err = snd_pcm_sw_params(phandle, params); if(..);
err = snd_pcm_sw_params_set_start_threshold(phandle, swparams, 0x7fffffff);
if(..);
err = snd_pcm_sw_params_set_avail_min(phandle, swparams, 4);

# same configuration for phandle

# Link output to input and start
err = snd_pcm_link(chandle, phandle); if(..);
err = snd_pcm_start(chandle); if(..);

#Then I want to read my input
frames_in = 0;
in_max = 0;
latency = 28;
buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);
while (1) {
        r = readbuf(chandle, buffer, latency, &frames_in, &in_max)); if(..);
}

# description of the function
long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t
*max)
{
        long r;
        do {
      r = snd_pcm_readi(handle, buf, len);
} while (r == -EAGAIN);

if  (r > 0) {
*frames += r;
if ((long)*max < r)
*max = r;
}
printf ("r = %s,  len %li and buf[%d] %f \r", snd_strerror(r), len,i,
buf[i]);
return r;
}

So I compile it and I run it, and I have
$ read = Broken Pipe, len = 28 and buf[..] = 0.000

Anyone can help me to read the input of my sound card ?

Thank you
-- 
K

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

* Fwd: [Alsa-devel] Read the input of a soundcard with ALSA
       [not found] ` <4628FD65.4020407@gmail.com>
@ 2007-04-23 14:18   ` Nyx
  2007-04-24 13:08     ` Takashi Iwai
  0 siblings, 1 reply; 5+ messages in thread
From: Nyx @ 2007-04-23 14:18 UTC (permalink / raw)
  To: alsa-devel

Hi,

I have some problems to read the input of my soundcard using Alsa and I
don't really understand how to have access to the input of my soundcard.
I follow :
http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2latency_8c-example.html


# So, in my program, I have created two handles for capture and playback :
char *device = "hw:0,0";
snd_output_t *output;
snd_input_t *input;
snd_pcm_t *phandle, *chandle;

# then I connect the phandle to the out
err = snd_output_stdio_attach(&output, stdout, 0);
if (..)

# Do I have to connect the chandle with the input ?
# err = snd_input_stdio_attach(&input, stdin, 0);

# I open the access to PCM
err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)
if (..)
err = snd_pcm_open(&chandle, pdevice, SND_PCM_STREAM_CAPTURE, 0)
if(..)

# Hardware and software Parameters
## Hardware Parameters
snd_pcm_hw_params;
int err;

err = snd_pcm_hw_params_any(phandle, params); if(..);
err = snd_pcm_hw_params_set_access(phandle,
params,SND_PCM_ACCESS_RW_INTERLEAVED); if(..);
err = snd_pcm_hw_params_set_format(phandle, params,SND_PCM_FORMAT_S16);
if(..);
err = snd_pcm_hw_params_set_channels(phandle, params, 1); if(..);
err = snd_pcm_hw_params_set_rate_near(phandle, params, 44100, 0); if(..);
err = snd_pcm_hw_params_set_buffer_time_near(phandle, params, 500000, &dir);
if(..);
err = snd_pcm_hw_params_set_time_near(phandle, params, 100000, &dir),
if(..);
err = snd_pcm_hw_params(phandle, params);

##Software parameters
err = snd_pcm_sw_params(phandle, params); if(..);
err = snd_pcm_sw_params_set_start_threshold(phandle, swparams, 0x7fffffff);
if(..);
err = snd_pcm_sw_params_set_avail_min(phandle, swparams, 4);

# same configuration for phandle

# Link output to input and start
err = snd_pcm_link(chandle, phandle); if(..);
err = snd_pcm_start(chandle); if(..);

#Then I want to read my input
frames_in = 0;
in_max = 0;
latency = 28;
buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);
while (1) {
        r = readbuf(chandle, buffer, latency, &frames_in, &in_max)); if(..);

}

# description of the function
long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t
*max)
{
        long r;
        do {
      r = snd_pcm_readi(handle, buf, len);
} while (r == -EAGAIN);

if  (r > 0) {
*frames += r;
if ((long)*max < r)
*max = r;
}
printf ("r = %s,  len %li and buf[%d] %f \r", snd_strerror(r), len,i,
buf[i]);
return r;
}

So I compile it and I run it, and I have
$ read = Broken Pipe, len = 28 and buf[..] = 0.000

Anyone can help me to read the input of my sound card ?

Thank you
-- 
K

PS : if I sent this message twice, excuse-me. I haven't confirm my
subscription the first time

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

* Re: Fwd: [Alsa-devel] Read the input of a soundcard with ALSA
  2007-04-23 14:18   ` Fwd: " Nyx
@ 2007-04-24 13:08     ` Takashi Iwai
  2007-05-02 12:23       ` Nyx
  0 siblings, 1 reply; 5+ messages in thread
From: Takashi Iwai @ 2007-04-24 13:08 UTC (permalink / raw)
  To: Nyx; +Cc: alsa-devel

At Mon, 23 Apr 2007 16:18:30 +0200,
Nyx wrote:
> 
> Hi,
> 
> I have some problems to read the input of my soundcard using Alsa and I
> don't really understand how to have access to the input of my soundcard.
> I follow :
> http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
> http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2latency_8c-example.html
> 
> 
> # So, in my program, I have created two handles for capture and playback :
> char *device = "hw:0,0";
> snd_output_t *output;
> snd_input_t *input;
> snd_pcm_t *phandle, *chandle;
> 
> # then I connect the phandle to the out
> err = snd_output_stdio_attach(&output, stdout, 0);
> if (..)
> 
> # Do I have to connect the chandle with the input ?
> # err = snd_input_stdio_attach(&input, stdin, 0);
> 
> # I open the access to PCM
> err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)
> if (..)
> err = snd_pcm_open(&chandle, pdevice, SND_PCM_STREAM_CAPTURE, 0)
> if(..)
> 
> # Hardware and software Parameters
> ## Hardware Parameters
> snd_pcm_hw_params;
> int err;
> 
> err = snd_pcm_hw_params_any(phandle, params); if(..);
> err = snd_pcm_hw_params_set_access(phandle,
> params,SND_PCM_ACCESS_RW_INTERLEAVED); if(..);
> err = snd_pcm_hw_params_set_format(phandle, params,SND_PCM_FORMAT_S16);
> if(..);
> err = snd_pcm_hw_params_set_channels(phandle, params, 1); if(..);
> err = snd_pcm_hw_params_set_rate_near(phandle, params, 44100, 0); if(..);
> err = snd_pcm_hw_params_set_buffer_time_near(phandle, params, 500000, &dir);
> if(..);
> err = snd_pcm_hw_params_set_time_near(phandle, params, 100000, &dir),
> if(..);
> err = snd_pcm_hw_params(phandle, params);
> 
> ##Software parameters
> err = snd_pcm_sw_params(phandle, params); if(..);
> err = snd_pcm_sw_params_set_start_threshold(phandle, swparams, 0x7fffffff);
> if(..);
> err = snd_pcm_sw_params_set_avail_min(phandle, swparams, 4);
> 
> # same configuration for phandle
> 
> # Link output to input and start
> err = snd_pcm_link(chandle, phandle); if(..);
> err = snd_pcm_start(chandle); if(..);
> 
> #Then I want to read my input
> frames_in = 0;
> in_max = 0;
> latency = 28;
> buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);
> while (1) {
>         r = readbuf(chandle, buffer, latency, &frames_in, &in_max)); if(..);
> 
> }
> 
> # description of the function
> long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t
> *max)
> {
>         long r;
>         do {
>       r = snd_pcm_readi(handle, buf, len);
> } while (r == -EAGAIN);
> 
> if  (r > 0) {
> *frames += r;
> if ((long)*max < r)
> *max = r;
> }
> printf ("r = %s,  len %li and buf[%d] %f \r", snd_strerror(r), len,i,
> buf[i]);
> return r;
> }
> 
> So I compile it and I run it, and I have
> $ read = Broken Pipe, len = 28 and buf[..] = 0.000
> 
> Anyone can help me to read the input of my sound card ?

When you link both playback and capture streams and start them at the
same time, then it results in buffer underrun for the playback --
unless you fill the data beforehand.  snd_pcm_start() triggers _both_
streams linked together.  Hence, a common technique for such
full-duplex streams is to fill empty data to the playback stream
beforehand, then starts.


Takashi

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

* Re: Fwd: [Alsa-devel] Read the input of a soundcard with ALSA
  2007-04-24 13:08     ` Takashi Iwai
@ 2007-05-02 12:23       ` Nyx
  2007-05-07 14:26         ` Nyx
  0 siblings, 1 reply; 5+ messages in thread
From: Nyx @ 2007-05-02 12:23 UTC (permalink / raw)
  To: alsa-devel

OK. I only want to read on the input of soundcard. So I wrote an other
program easier than the first, I write the data in file, but it seems that
it doesn't work...

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "alsa/asoundlib.h"
#include <errno.h>

unsigned int rate = 44100;
unsigned int nb_channels = 2;

int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *hw_params)
{
    int err;
    int dir=0;
    if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
        fprintf (stderr, "cannot allocate hardware parameter structure
(%s)\n", snd_strerror (err));
        exit (1);
    }

    if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) {
        fprintf (stderr, "cannot initialize hardware parameter structure
(%s)\n", snd_strerror (err));
        exit (1);
    }
    printf("Initialisation des paramètres\n");

    if ((err = snd_pcm_hw_params_set_access (handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf (stderr, "cannot set access type (%s)\n", snd_strerror
(err));
        exit (1);
    }
    printf("Access card configuration\n");

    if ((err = snd_pcm_hw_params_set_format (handle, hw_params,
SND_PCM_FORMAT_S16_LE)) < 0) {
        fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror
(err));
        exit (1);
    }

    if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &rate,
&dir)) < 0) {
        fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror
(err));
        exit (1);
    }
    if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, nb_chann))
< 0) {
        fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror
(err));
        exit (1);
    }

    if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
        fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror
(err));
        exit (1);
    }
    printf("Parameters recorded\n");

    //snd_pcm_hw_params_free (hw_params);

    if ((err = snd_pcm_prepare (handle)) < 0) {
        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
        exit (1);
    }
        return 0;
}

int main(int   argc, char *argv[]){
    int err;
    int j;
    printf("Beginning \n");
    snd_pcm_hw_params_t *hw_params_capture, *hw_params_playback;
    short buf[256];
    FILE *file;

    fichier = fopen( "/root/Desktop/Test/Audio/Capture.001", "w");
    if (fichier == NULL) printf("cannot create file : %i\n", errno);
    else printf("file created\n");

    /*Open soundcard as capture*/
    snd_pcm_t *capture_handle;

    if ((err = snd_pcm_open (&capture_handle, "hw:0,0",
SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf (stderr, "cannot open audio device %s (%s)\n",  argv[1],
 snd_strerror (err));
        exit (1);
    }

   set_hwparams(capture_handle, hw_params_capture);

   for (j = 0 ;  j < 256 ; j++) {
            if ((err = snd_pcm_readi (capture_handle, buf, 128)) < 0)
printf("cherche pas\n");
            putc(buf[j], file);       //write in file LEFT Channel
            putc(buf[j+1], file);  //write in file RIGHT Channel
            putc(0x0A, file);
    }

    printf("Close File\n");
    fclose(file);
    snd_pcm_close (capture_handle);
    return 0 ;
}


What do you think about this program... ? I searched about an How-to or some
help for capture on a soundcard with ALSA, but I didn't found

Thank you
-- 
K

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

* Re: Fwd: [Alsa-devel] Read the input of a soundcard with ALSA
  2007-05-02 12:23       ` Nyx
@ 2007-05-07 14:26         ` Nyx
  0 siblings, 0 replies; 5+ messages in thread
From: Nyx @ 2007-05-07 14:26 UTC (permalink / raw)
  To: alsa-devel

OK men and women... I found how I can do this... I am a stupid man ;)

So I found here some help http://www.linuxjournal.com/article/6735

So for capture :

/*
This example reads from the default PCM device
and writes to standard output for 5 seconds of data.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
int main() {
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  char *buffer;
  /* Open PCM device for recording (capture). */
  rc = snd_pcm_open(&handle, "default",
                    SND_PCM_STREAM_CAPTURE, 0);
  if (rc < 0) {
    fprintf(stderr,
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);
  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);
  /* Set the desired hardware parameters. */
  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);
  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,
                              SND_PCM_FORMAT_S16_LE);
  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 2);
  /* 44100 bits/second sampling rate (CD quality) */
  val = 44100;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);
  /* Set period size to 32 frames. */
  frames = 32;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);
  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params,
                                      &frames, &dir);
  size = frames * 4; /* 2 bytes/sample, 2 channels */
  buffer = (char *) malloc(size);
  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,
                                         &val, &dir);
  loops = 5000000 / val;
  while (loops > 0) {
    loops--;
    rc = snd_pcm_readi(handle, buffer, frames);
    if (rc == -EPIPE) {
      /* EPIPE means overrun */
      fprintf(stderr, "overrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      fprintf(stderr,
              "error from read: %s\n",
              snd_strerror(rc));
    } else if (rc != (int)frames) {
      fprintf(stderr, "short read, read %d frames\n", rc);
    }
    rc = write(1, buffer, size);
    if (rc != size)
      fprintf(stderr,
              "short write: wrote %d bytes\n", rc);
  }
  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);
  return 0;

and for playback

/*
This example reads standard from input and writes
to the default PCM device for 5 seconds of data.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
int main() {
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  char *buffer;
  /* Open PCM device for playback. */
  rc = snd_pcm_open(&handle, "default",
                    SND_PCM_STREAM_PLAYBACK, 0);
  if (rc < 0) {
    fprintf(stderr,
            "unable to open pcm device: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);
  /* Fill it in with default values. */
  snd_pcm_hw_params_any(handle, params);
  /* Set the desired hardware parameters. */
  /* Interleaved mode */
  snd_pcm_hw_params_set_access(handle, params,
                      SND_PCM_ACCESS_RW_INTERLEAVED);
  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,
                              SND_PCM_FORMAT_S16_LE);
  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 2);
  /* 44100 bits/second sampling rate (CD quality) */
  val = 44100;
  snd_pcm_hw_params_set_rate_near(handle, params,
                                  &val, &dir);
  /* Set period size to 32 frames. */
  frames = 32;
  snd_pcm_hw_params_set_period_size_near(handle,
                              params, &frames, &dir);
  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,
            "unable to set hw parameters: %s\n",
            snd_strerror(rc));
    exit(1);
  }
  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params, &frames,
                                    &dir);
  size = frames * 4; /* 2 bytes/sample, 2 channels */
  buffer = (char *) malloc(size);
  /* We want to loop for 5 seconds */
  snd_pcm_hw_params_get_period_time(params,
                                    &val, &dir);
  /* 5 seconds in microseconds divided by
   * period time */
  loops = 5000000 / val;
  while (loops > 0) {
    loops--;
    rc = read(0, buffer, size);
    if (rc == 0) {
      fprintf(stderr, "end of file on input\n");
      break;
    } else if (rc != size) {
      fprintf(stderr,
              "short read: read %d bytes\n", rc);
    }
    rc = snd_pcm_writei(handle, buffer, frames);
    if (rc == -EPIPE) {
      /* EPIPE means underrun */
      fprintf(stderr, "underrun occurred\n");
      snd_pcm_prepare(handle);
    } else if (rc < 0) {
      fprintf(stderr,
              "error from writei: %s\n",
              snd_strerror(rc));
    }  else if (rc != (int)frames) {
      fprintf(stderr,
              "short write, write %d frames\n", rc);
    }
  }
  snd_pcm_drain(handle);
  snd_pcm_close(handle);
  free(buffer);
  return 0;

Thank you

K.
}

}

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

end of thread, other threads:[~2007-05-07 14:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-20 15:20 [Alsa-devel] Read the input of a soundcard with ALSA Nyx
     [not found] ` <4628FD65.4020407@gmail.com>
2007-04-23 14:18   ` Fwd: " Nyx
2007-04-24 13:08     ` Takashi Iwai
2007-05-02 12:23       ` Nyx
2007-05-07 14:26         ` Nyx

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.