[Speex-dev] Again, teach me speex AEC please!

Hai Yun Tao hytparadisee at hotmail.com
Thu May 29 04:47:53 PDT 2008


Dear all:

I need the help desparately.

The code is attached below.

If you guys don't mind take a look at the code below and see how to fit speex's AEC into it.

Help me look at the #defines, and give me some suggestions on the AEC parameters, I totally have no idea about them.

Feel free to do anything with the code, if it is by any chance valuable.

Any ideas or suggestions or sharing is highly appreciated.

I believe someone has already made AEC to work?!

But beware, this will be used in my Voip program, so it should be async by nature.

/**
 * com_peterhi_Speex.h
 */
#include <jni.h>
#ifndef _Included_com_peterhi_Speex
#define _Included_com_peterhi_Speex
#ifdef __cplusplus
extern "C" {
#endif


JNIEXPORT jint JNICALL Java_com_peterhi_Speex_encoder__(JNIEnv *, jclass);
JNIEXPORT jint JNICALL Java_com_peterhi_Speex_decoder__(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_com_peterhi_Speex_encoder__I(JNIEnv *, jclass, jint);
JNIEXPORT void JNICALL Java_com_peterhi_Speex_decoder__I(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_peterhi_Speex_encode(JNIEnv *, jclass, jint, jbyteArray, jbyteArray);
JNIEXPORT void JNICALL Java_com_peterhi_Speex_decode(JNIEnv *, jclass, jint, jbyteArray, jint, jbyteArray);

#ifdef __cplusplus
}
#endif
#endif






/************************************************************************************************************/






/**
 * com_peterhi_Speex.c
 */
#include <speex/speex.h>
#include <speex/speex_preprocess.h>
#include <speex/speex_resampler.h>
#include "com_peterhi_Speex.h"

#define TYPE_ENCODE 1
#define TYPE_DECODE 2
#define DSP_FRAME_SIZE 160
#define ENC_FRAME_SIZE 320
#define FRAME_RATE 8000

int yes = 1;
int quality = 10;
float rate = 8000;

typedef struct {
    int type;
    SpeexBits bits;
    void* pSt;
    SpeexPreprocessState* pPre;
    // Perhaps the echo state here?
} Codec;

/**
 * Creates a new encoder state
 */
JNIEXPORT jint JNICALL Java_com_peterhi_Speex_encoder__(JNIEnv* env, jclass c)
{
    Codec* pCodec = malloc(sizeof(Codec));

    speex_bits_init(&pCodec->bits);
    pCodec->type = TYPE_ENCODE;
    pCodec->pSt = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
    pCodec->pPre = speex_preprocess_state_init(DSP_FRAME_SIZE, FRAME_RATE);

    speex_encoder_ctl(pCodec->pSt, SPEEX_SET_QUALITY, &quality);
    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_AGC, &yes);
    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_AGC_LEVEL, &rate);

    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_DEREVERB, &yes);
    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &yes);
    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &yes);
    speex_preprocess_ctl(pCodec->pPre, SPEEX_PREPROCESS_SET_DENOISE, &yes);
    
    // Any idea how to setup AEC here?

    return (jint )pCodec;
}

/**
 * Creates a new decoder state
 */
JNIEXPORT jint JNICALL Java_com_peterhi_Speex_decoder__(JNIEnv* env, jclass c)
{
    Codec* pCodec = malloc(sizeof(Codec));

    speex_bits_init(&pCodec->bits);
    pCodec->type = TYPE_DECODE;
    pCodec->pSt = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));

    return (jint )pCodec;
}

/**
 * Destroys a new encoder state
 */
JNIEXPORT void JNICALL Java_com_peterhi_Speex_encoder__I(JNIEnv* env, jclass c, jint p)
{
    Codec* pCodec = (Codec* )p;

    if (pCodec->type != TYPE_ENCODE)
    {
        return;
    }

    speex_preprocess_state_destroy(pCodec->pPre);
    speex_encoder_destroy(pCodec->pSt);
    speex_bits_destroy(&pCodec->bits);

    free(pCodec);
}

/**
 * Destroys a new decoder state
 */
JNIEXPORT void JNICALL Java_com_peterhi_Speex_decoder__I(JNIEnv* env, jclass c, jint p)
{
    Codec* pCodec = (Codec* )p;

    if (pCodec->type != TYPE_DECODE)
    {
        return;
    }

    speex_bits_destroy(&pCodec->bits);
    speex_decoder_destroy(pCodec->pSt);

    free(pCodec);
}

/**
 * Encode a byte array.
 */
JNIEXPORT jint JNICALL Java_com_peterhi_Speex_encode(JNIEnv* env, jclass c, jint p, jbyteArray buf1, jbyteArray buf2)
{
    jbyte* bytes1 = (*env)->GetByteArrayElements(env, buf1, JNI_FALSE);
    jbyte* bytes2 = (*env)->GetByteArrayElements(env, buf2, JNI_FALSE);
    int len1 = (*env)->GetArrayLength(env, buf1);
    int len2 = (*env)->GetArrayLength(env, buf2);

    jint ret = 0;

    Codec* pCodec = (Codec* )p;

    if (pCodec->type != TYPE_ENCODE)
    {
        return ret;
    }

    // How to use AEC to cancel?
    
    speex_preprocess_run(pCodec->pPre, (spx_int16_t* )bytes1);
    speex_bits_reset(&pCodec->bits);
    speex_encode_int(pCodec->pSt, (spx_int16_t* )bytes1, &pCodec->bits);
    ret = speex_bits_write(&pCodec->bits, bytes2, len2);

    (*env)->SetByteArrayRegion(env, buf1, 0, len1, bytes1);
    (*env)->SetByteArrayRegion(env, buf2, 0, len2, bytes2);
    (*env)->ReleaseByteArrayElements(env, buf1, bytes1, 0);
    (*env)->ReleaseByteArrayElements(env, buf2, bytes2, 0);

    return ret;
}

/**
 * Decode a byte array.
 */
JNIEXPORT void JNICALL Java_com_peterhi_Speex_decode(JNIEnv* env, jclass c, jint p, jbyteArray buf1, jint len, jbyteArray buf2)
{
    jbyte* bytes1 = (*env)->GetByteArrayElements(env, buf1, JNI_FALSE);
    jbyte* bytes2 = (*env)->GetByteArrayElements(env, buf2, JNI_FALSE);
    int len1 = (*env)->GetArrayLength(env, buf1);
    int len2 = (*env)->GetArrayLength(env, buf2);

    Codec* pCodec = (Codec* )p;

    if (pCodec->type != TYPE_DECODE)
    {
        return;
    }

    speex_bits_read_from(&pCodec->bits, bytes1, len);
    speex_decode_int(pCodec->pSt, &pCodec->bits, (spx_int16_t* )bytes2);

    (*env)->SetByteArrayRegion(env, buf1, 0, len1, bytes1);
    (*env)->SetByteArrayRegion(env, buf2, 0, len2, bytes2);
    (*env)->ReleaseByteArrayElements(env, buf1, bytes1, 0);
    (*env)->ReleaseByteArrayElements(env, buf2, bytes2, 0);
}






/**************************************************************************************/






/*
 * Speex.java
 *
 * 21 May 2008
 *
 * copyright    : (C) 2008 by Yun Tao Hai and Beijing Teng Yun Software Inc.
 * email        : hytparadisee at gmail.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
package com.peterhi;

public class Speex {
    static {
        System.loadLibrary("speexjni");
    }
    
    public static native int encoder();
    public static native int decoder();
    public static native void encoder(int peer);
    public static native void decoder(int peer);
    public static native int encode(int peer, byte[] in, byte[] out);
    public static native void decode(int peer, byte[] in, int len, byte[] out);
}

_________________________________________________________________
Discover the new Windows Vista
http://search.msn.com/results.aspx?q=windows+vista&mkt=en-US&form=QBRE
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20080529/c8c5ce4b/attachment.htm 


More information about the Speex-dev mailing list