Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Need help on getting raw audio stream from a dummy sound card
@ 2009-03-05 16:34 Santo Chow
  2009-03-10 15:25 ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Santo Chow @ 2009-03-05 16:34 UTC (permalink / raw)
  To: alsa-devel

Hi everyone :)

I'm currently assigned to a task that requires me to capture raw audio stream from a dummy sound card. Is this even possible?

Previously, I have been able to capture raw audio stream from my default sound card, by using the following example I got from http://www.linuxjournal.com/article/6735

/*
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;
}

The above example allows me to capture 5 seconds of raw audio. I can use aplay to play the recorded sound and it plays nicely. But right now, I'm working on a project that involves the usage of a small development board. Basically, this board does not have a sound card or an actual speaker. So I thought, I can use the dummy soundcard provided by the linux kernel by calling out modprobe snd-dummy. Right now, I'm still testing it in my PC so to simulate the board's environment. I have configured the .asoundrc file and create a new dummy pcm by putting the lines below onto my .asoundrc file.

pcm.dummy{
    type hw
    card Dummy
}

So, I change the above ecample code, so it listens to this new dummy pcm rather than the 'default'. Like this :

rc = snd_pcm_open(&handle, "dummy",
                    SND_PCM_STREAM_CAPTURE, 0);
Supposedly, the above modification would allow me to record from this dummy pcm, no? I do this by playing a song, using aplay -f cd -D dummy song.wav and at the same time, execute the above example. As expected, no sound was coming out from my speaker. When the program finished recording for 5 seconds, I play back the result, but all i heard was just noise.

Of curiousity, I try using file plugins. I modify my .asoundrc file like this:

pcm.dummy{
    type plug
    slave{
        pcm file
        format S16_LE
        channels 2
        rate 44100
    }
}

pcm.file{
    type file
    slave{
        pcm d
    }
    file /home/mydir/out.raw
}

pcm.d{
    type hw
    card Dummy
}

Then i called aplay -f cd -D dummy song.wav again, well.. still no sound coming out from the speaker, but it does output the raw audio file into my /home/mydir/out.raw file. I play the out.raw using aplay -f cd /home/mydir/out.raw it's flawless.

But I can't use this for my implementation. What I need is actually a way to read raw audio data (or stream) from the dummy sound card, to a buffer inside my program. I need this because I'm going to stream the buffer to my server, so I can listen the sound from my server. I can't afford to use the file plugin approach, basically because later on, in my development board, i won't have that much space.

So, the question is: capturing raw audio data from a dummy soundcard, is this possible? I'm pretty sure that if the file plugin works, means that the raw audio data is there. It's just that i'm probably doing a wrong approach to read it. Hence, needs explanation and help..

Please help me.. :(


Thank you so much for reading my long request.

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

* Re: Need help on getting raw audio stream from a dummy sound card
  2009-03-05 16:34 Need help on getting raw audio stream from a dummy sound card Santo Chow
@ 2009-03-10 15:25 ` Takashi Iwai
  2009-03-12  7:17   ` Santo Chow
  2009-03-17  6:22   ` Santo Chow
  0 siblings, 2 replies; 4+ messages in thread
From: Takashi Iwai @ 2009-03-10 15:25 UTC (permalink / raw)
  To: Santo Chow; +Cc: alsa-devel

At Thu, 5 Mar 2009 08:34:03 -0800 (PST),
Santo Chow wrote:
> 
> Hi everyone :)
> 
> I'm currently assigned to a task that requires me to capture raw audio stream from a dummy sound card. Is this even possible?

You can use aloop driver in alsa-driver tree for such a purpose.
Then you can capture streams freely from the currently running playbacks.


Takashi

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

* Re: Need help on getting raw audio stream from a dummy sound card
  2009-03-10 15:25 ` Takashi Iwai
@ 2009-03-12  7:17   ` Santo Chow
  2009-03-17  6:22   ` Santo Chow
  1 sibling, 0 replies; 4+ messages in thread
From: Santo Chow @ 2009-03-12  7:17 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

Takashi,

Thanks for the great response. I've searched for this aloop documentation, but no luck :(. I've managed to follow the wiki, and modprobbed the snd-aloop. Now i'll experiment a little with the aloop. If you have further guide about this aloop, can you please send to me? Thanks.. you've made my day :D



Santo




________________________________
From: Takashi Iwai <tiwai@suse.de>
To: Santo Chow <santo_chow@yahoo.com>
Cc: alsa-devel@alsa-project.org
Sent: Tuesday, March 10, 2009 11:25:03 PM
Subject: Re: [alsa-devel] Need help on getting raw audio stream from a dummy sound card

At Thu, 5 Mar 2009 08:34:03 -0800 (PST),
Santo Chow wrote:
> 
> Hi everyone :)
> 
> I'm currently assigned to a task that requires me to capture raw audio stream from a dummy sound card. Is this even possible?

You can use aloop driver in alsa-driver tree for such a purpose.
Then you can capture streams freely from the currently running playbacks.


Takashi

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

* Re: Need help on getting raw audio stream from a dummy sound card
  2009-03-10 15:25 ` Takashi Iwai
  2009-03-12  7:17   ` Santo Chow
@ 2009-03-17  6:22   ` Santo Chow
  1 sibling, 0 replies; 4+ messages in thread
From: Santo Chow @ 2009-03-17  6:22 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

Hi Takashi,

I have followed your suggestion and now i'm faced with another problem. So, right now, i have a Loopback soundcard as my default. My .asoundrc looks like this:

pcm.!default{
   type hw
   card 1
}

Card
0 is my actual soundcard (that can actually produce sound). Card 1,
when i checked on the /proc/asound/cards actually pointing to Loopback
card. So right now, the way i test the card 1, is to call arecord from
card 1, and play it to card 0. Right now, i'm still developing this in
my ubuntu PC.

so i ran this
arecord -f cd -D hw:1,1 | aplay -f cd -D hw:0

in
one terminal, and in the other terminal i can play mplayer, watching
youtube, etc.. and the sound would come out nicely. (Thanks to all of
your efforts, nevertheless)

But I notice that, when i play
mplayer, then i open a web-browser, and surf youtube, the sound from
youtube is gone. But if i close the browser, close the mplayer, then
reopen the browser, go to youtube and play a video, i can hear the
sound nicely. but then, if during the time i start mplayer, it will
complain about 'no sound'. Turns out, I have to use dmix. So, i modify
my .asoundrc like this:

pcm.!default {
   type plug
   slave.pcm "dmixer"
}

pcm.dmixer  {
   type dmix
   ipc_key 1025
   slave {
      pcm "hw:0,0"
      rate 44100
   }
   bindings {

  0 0
      1 1
   }
}
i put 'pcm "hw:0,0" ' over there, because i want to make sure that this setting works with my actual sound card first. If it works with my card 0, it should work with my card 1. with
the above .asoundrc file, i can play multiple sound from different
application at the same time. I even tried to remove the "bindings"
tag, and it still able to play multiple sound very well. so i guess,
this should work on my card 1.

then i change the .asoundrc become like this again:


pcm.!default {
   type plug
   slave.pcm "dmixer"
}

pcm.dmixer  {
   type dmix
   ipc_key 1025
   slave {
      pcm "hw:1,1"
      period_time 0
      period_size 881
      buffer_size 3524
      rate 44100

 }
}the value for perio_time,
period_size, and buffer_size have been adjusted by me to suits my
hardware requirement. This is the setting that works on my machine.
It's just that, in the end, I'm still ended up with one sound at a
time. I can't run mplayer + youtube at the same time. I can only run
one of them. And furthermore, if i just paused the mplayer, the audio device is still locks. It will be good enough if someone can hint me a way to unlock the audio device.

So,
what i want to ask is.. can this Loopback card handle more than 1 sound
at a time? Have anyone tried this before? I have tried changing the
value of .asoundrc, switching the slave pcm to pcm "hw:1,0" (not
working) pcm "hw:1" (works, but only 1 sound too). Any idea guys?


Santo




________________________________
From: Takashi Iwai <tiwai@suse.de>
To: Santo Chow <santo_chow@yahoo.com>
Cc: alsa-devel@alsa-project.org
Sent: Tuesday, March 10, 2009 11:25:03 PM
Subject: Re: [alsa-devel] Need help on getting raw audio stream from a dummy sound card

At Thu, 5 Mar 2009 08:34:03 -0800 (PST),
Santo Chow wrote:
> 
> Hi everyone :)
> 
> I'm currently assigned to a task that requires me to capture raw audio stream from a dummy sound card. Is this even possible?

You can use aloop driver in alsa-driver tree for such a purpose.
Then you can capture streams freely from the currently running playbacks.


Takashi

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

end of thread, other threads:[~2009-03-17  6:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-05 16:34 Need help on getting raw audio stream from a dummy sound card Santo Chow
2009-03-10 15:25 ` Takashi Iwai
2009-03-12  7:17   ` Santo Chow
2009-03-17  6:22   ` Santo Chow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox