Re: [alsa-devel] ALSA 1.0.20 Speex PCM Plugin

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Frederic:

Here is what I have in my asound.conf...

pcm.record_left {
    type dsnoop
    ipc_key 4096
    ipc_perm 0666
    slave {
        pcm "hw:0,0"
        channels 2
    }
    bindings.0  0
}
pcm.record_right {
    type dsnoop
    ipc_key 8192
    ipc_perm 0666
    slave {
        pcm "hw:0,0"
        channels 2
    }
    bindings.0  1
}
pcm.my_pcm {
    type speex
    slave.pcm "record_right"
    frames 128
    denoise 0
    agc 1
    echo 1
    filter_length 8192
    agc_level 8000
    dereverb 0
    dereverb_decay 0
    dereverb_level 0
}

Best Regards,

--
Rob Krakora
Senior Software Engineer
MessageNet Systems
101 East Carmel Dr. Suite 105
Carmel, IN 46032
(317)566-1677 Ext. 206
(317)663-0808 Fax

2009/9/17 Frédéric COIFFIER <fcoiffie.coiffier@xxxxxxx>
Hello Mr Krakora, Mr Iwai,

Have you succeeded to get a generic asound.conf which is able to convert in
mono before using the speex plugin ?
I don't succeed to get a default device using speex plugin for capture (and
ALSA configuration seems really complex and not well documented).

Frederic Coiffier

Le jeudi 4 juin 2009 15:46:19, Takashi Iwai a écrit :
> At Tue, 2 Jun 2009 16:39:46 -0400,
>
> Robert Krakora wrote:
> > Hello,
> >
> > Has anyone successfully employed the ALSA 1.0.20 Speex PCM Plugin?  I
> > followed the "speexdsp.txt" document under the 'doc' directory but the
> > result was the following error:
> >
> > [root@vizioroom105 ~]# arecord -Dplug:mic poopy.wav
> > Recording WAVE 'poopy.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
> > ALSA lib pcm_params.c:2135:(snd1_pcm_hw_refine_slave) Slave PCM not
> > usable arecord: set_params:957: Broken configuration for this PCM: no
> > configurations available
>
> It's because the slave plugin of pcm.mic is "hw" and that doesn't
> support mono streams but only stereo.  speex plugin requires a mono
> stream explicitly.
>
> Wrap speex plugin over the default or add plug layer inside it, too.
>
> BTW, I found that I didn't put any echo-cancelling code in the speex
> plugin.  It was just written for denoising.
>
> The below is a quick hack to add the echo-cancelling part.  Give it a try
> (although it's totally untested :)
>
>
> Takashi
>
> ---
> diff --git a/doc/speexdsp.txt b/doc/speexdsp.txt
> index 875fc19..1937de6 100644
> --- a/doc/speexdsp.txt
> +++ b/doc/speexdsp.txt
> @@ -12,7 +12,7 @@ using libspeex DSP API.  You can use the plugin with the
>  plugin type
>
>  Then record like
>
> -     % arecord -fdat -c1 -Dplug:speex foo.wav
> +     % arecord -fdat -c1 -Dplug:my_pcm foo.wav
>
>  so that you'll get 48kHz mono stream with the denoising effect.
>
> @@ -44,6 +44,16 @@ The following parameters can be set optionally:
>
>    A boolean value to enable/disable dereverb function.  Default is no.
>
> +* echo
> +
> +  A boolean value to enable/disable echo-cancellation function.
> +  Default is no.
> +
> +* filter_length
> +
> +  Number of samples of echo to cancel.  As default it's 256.
> +
> +
>  For example, you can enable agc like
>
>       pcm.my_pcm {
> diff --git a/speex/pcm_speex.c b/speex/pcm_speex.c
> index 7bb9213..38b3582 100644
> --- a/speex/pcm_speex.c
> +++ b/speex/pcm_speex.c
> @@ -1,5 +1,5 @@
>  /*
> - * Speex preprocess plugin
> + * Speex DSP plugin
>   *
>   * Copyright (c) 2009 by Takashi Iwai <tiwai@xxxxxxx>
>   *
> @@ -21,12 +21,15 @@
>  #include <alsa/asoundlib.h>
>  #include <alsa/pcm_external.h>
>  #include <speex/speex_preprocess.h>
> +#include <speex/speex_echo.h>
>
> -/* preprocessing parameters */
> +/* DSP parameters */
>  struct spx_parms {
>       int frames;
>       int denoise;
>       int agc;
> +     int echo;
> +     int filter_length;
>       float agc_level;
>       int dereverb;
>       float dereverb_decay;
> @@ -38,7 +41,9 @@ typedef struct {
>       struct spx_parms parms;
>       /* instance and intermedate buffer */
>       SpeexPreprocessState *state;
> +     SpeexEchoState *echo_state;
>       short *buf;
> +     short *outbuf;
>       /* running states */
>       unsigned int filled;
>       unsigned int processed;
> @@ -64,6 +69,12 @@ spx_transfer(snd_pcm_extplug_t *ext,
>       short *src = "" src_offset);
>       short *dst = area_addr(dst_areas, dst_offset);
>       unsigned int count = size;
> +     short *databuf;
> +
> +     if (spx->parms.echo)
> +             databuf = spx->outbuf;
> +     else
> +             databuf = spx->buf;
>
>       while (count > 0) {
>               unsigned int chunk;
> @@ -72,14 +83,19 @@ spx_transfer(snd_pcm_extplug_t *ext,
>               else
>                       chunk = count;
>               if (spx->processed)
> -                     memcpy(dst, spx->buf + spx->filled, chunk * 2);
> +                     memcpy(dst, databuf + spx->filled, chunk * 2);
>               else
>                       memset(dst, 0, chunk * 2);
>               dst += chunk;
>               memcpy(spx->buf + spx->filled, src, chunk * 2);
>               spx->filled += chunk;
>               if (spx->filled == spx->parms.frames) {
> -                     speex_preprocess_run(spx->state, spx->buf);
> +                     if (spx->parms.echo)
> +                             speex_echo_capture(spx->echo_state, spx->buf,
> +                                                spx->outbuf);
> +                     speex_preprocess_run(spx->state, databuf);
> +                     if (spx->parms.echo)
> +                             speex_echo_playback(spx->echo_state, databuf);
>                       spx->processed = 1;
>                       spx->filled = 0;
>               }
> @@ -101,13 +117,34 @@ static int spx_init(snd_pcm_extplug_t *ext)
>       }
>       memset(spx->buf, 0, spx->parms.frames * 2);
>
> -     if (spx->state)
> +     if (spx->state) {
>               speex_preprocess_state_destroy(spx->state);
> +             spx->state = NULL;
> +     }
> +     if (spx->echo_state) {
> +             speex_echo_state_destroy(spx->echo_state);
> +             spx->echo_state = NULL;
> +     }
> +
> +     if (spx->parms.echo) {
> +             spx->echo_state = speex_echo_state_init(spx->parms.frames,
> +                                             spx->parms.filter_length);
> +             if (!spx->echo_state)
> +                     return -EIO;
> +             speex_echo_ctl(spx->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE,
> +                            &spx->ext.rate);
> +     }
> +
>       spx->state = speex_preprocess_state_init(spx->parms.frames,
>                                                spx->ext.rate);
>       if (!spx->state)
>               return -EIO;
>
> +     if (spx->parms.echo)
> +             speex_preprocess_ctl(spx->state,
> +                                  SPEEX_PREPROCESS_SET_ECHO_STATE,
> +                                  spx->echo_state);
> +
>       speex_preprocess_ctl(spx->state, SPEEX_PREPROCESS_SET_DENOISE,
>                            &spx->parms.denoise);
>       speex_preprocess_ctl(spx->state, SPEEX_PREPROCESS_SET_AGC,
> @@ -132,6 +169,8 @@ static int spx_close(snd_pcm_extplug_t *ext)
>       free(spx->buf);
>       if (spx->state)
>               speex_preprocess_state_destroy(spx->state);
> +     if (spx->echo_state)
> +             speex_echo_state_destroy(spx->echo_state);
>       return 0;
>  }
>
> @@ -205,6 +244,8 @@ SND_PCM_PLUGIN_DEFINE_FUNC(speex)
>               .dereverb = 0,
>               .dereverb_decay = 0,
>               .dereverb_level = 0,
> +             .echo = 0,
> +             .filter_length = 256,
>       };
>
>       snd_config_for_each(i, next, conf) {
> @@ -242,6 +283,12 @@ SND_PCM_PLUGIN_DEFINE_FUNC(speex)
>                                    &parms.dereverb_level);
>               if (err)
>                       goto ok;
> +             err = get_bool_parm(n, id, "echo", &parms.echo);
> +             if (err)
> +                     goto ok;
> +             err = get_int_parm(n, id, "filter_length", &parms.filter_length);
> +             if (err)
> +                     goto ok;
>               SNDERR("Unknown field %s", id);
>               err = -EINVAL;
>       ok:
> @@ -259,7 +306,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(speex)
>               return -ENOMEM;
>
>       spx->ext.version = SND_PCM_EXTPLUG_VERSION;
> -     spx->ext.name = "Speex Denoise Plugin";
> +     spx->ext.name = "Speex DSP Plugin";
>       spx->ext.callback = &speex_callback;
>       spx->ext.private_data = spx;
>       spx->parms = parms;
>
> ---------------------------------------------------------------------------
> --- OpenSolaris 2009.06 is a cutting edge operating system for enterprises
>  looking to deploy the next generation of Solaris that includes the latest
>  innovations from Sun and the OpenSource community. Download a copy and
>  enjoy capabilities such as Networking, Storage and Virtualization. Go to:
>  http://p.sf.net/sfu/opensolaris-get
> _______________________________________________
> Alsa-user mailing list
> Alsa-user@xxxxxxxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/alsa-user
>



------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux