Шумоподавление с помощью speex

У меня есть Java-приложение, создающее живой поток на RTMP-сервер, я хочу отменить шум, используя speex через JNI, я делаю реализацию jni очень хорошо, но в java-приложении он хорошо обрабатывает короткий массив, но результаты во флеш-плеере для потока не очень хорошие звук очень непонятный.

я покажу вам простой код, чтобы получить представление о том, что сделано в коде, и что не так в моем коде

здесь код c для jni

#include <jni.h>
#include "speex/speex_preprocess.h"
#include "speex_pushStream.h"


SpeexPreprocessState *st;
int i;
float f;

JNIEXPORT void JNICALL Java_speex_pushStream_echoCanceller_1open
(JNIEnv *env, jobject jObj, jint jSampleRate, jint jBufSize)
{
    int sampleRate = jSampleRate;
    st = speex_preprocess_state_init(jBufSize , sampleRate);

    i = 1;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
    i = 0;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
    i = sampleRate;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
    i = 0;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
    f = .0;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
    f = .0;
    speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);

}

JNIEXPORT jshortArray JNICALL Java_speex_pushStream_cancel_1noise
(JNIEnv *env , jobject jObj , jshortArray input_frame)
{
    //create native shorts from java shorts
    jshort *native_input_frame = (*env)->GetShortArrayElements(env, input_frame, NULL);


    //allocate memory for output data
    jint length = (*env)->GetArrayLength(env, input_frame);
    jshortArray temp = (*env)->NewShortArray(env, length);
    jshort *native_output_frame = (*env)->GetShortArrayElements(env, temp, 0);


    //preprocess output frame
    speex_preprocess_run(st , native_input_frame);



    //convert native output to java layer output
    jshortArray output_shorts = (*env)->NewShortArray(env, length);
    (*env)->SetShortArrayRegion(env, output_shorts, 0, length, native_input_frame);


    //cleanup and return
    (*env)->ReleaseShortArrayElements(env, input_frame, native_input_frame, 0);
    (*env)->ReleaseShortArrayElements(env, temp, native_output_frame, 0);

    return output_shorts;
}

JNIEXPORT void JNICALL Java_speex_pushStream_close_1noise
(JNIEnv *env , jobject jObj)
{
    speex_preprocess_state_destroy(st);
}

и это часть потоковой передачи в приложении Java

new Thread(new Runnable() {     

                private int rate;
                private int numChannels;
                private byte[] audioBytes;

                @Override
                public void run() {



                    final float sampleRate  = sampleAudioRateInHz;
                    int sampleSizeBit = 16;
                    int channel       = audioChannel;
                    boolean signed    = true;
                    boolean endian    = false;



                    AudioFormat audioFormat = new AudioFormat(sampleRate , sampleSizeBit , channel , signed , endian );

                    Mixer.Info[] minfoSet = AudioSystem.getMixerInfo();
                    Mixer mixer = AudioSystem.getMixer(minfoSet[AUDIO_DEVICE_INDEX]);
                    final DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);


                    try {

                        line = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
                        line.open(audioFormat);
                        line.start();


                        rate = (int) audioFormat.getSampleRate();
                        numChannels = audioFormat.getChannels();

                        // Let's initialize our audio buffer...
                        int audioBufferSize = rate * numChannels;
                        audioBytes = new byte[audioBufferSize];

                        ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
                        exec.scheduleAtFixedRate(new Runnable() {
                            @Override
                            public void run() {

                                try {
                                    int nBytesRead = 0;
                                    while (nBytesRead == 0) {// filterNoise(audioBytes , 2) filterNoise(audioBytes , 10) 
                                        nBytesRead = line.read( audioBytes , 0 , line.available());                                    
                                    }

                                    int nSamplesRead = nBytesRead / 2;
                                    short[] samples = new short[nSamplesRead];

                                    //System.out.println("sample length: " + nSamplesRead + " length : " + samples.length );

                                    echoCanceller_open((int)sampleRate , nSamplesRead); // nSamplesRead);
                                    //echoCanceller_open((int)sampleRate , nSamplesRead , 0);

                                    ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
                                    ShortBuffer sBuff = null;

                                    short tmp[] = samples; // cancel_noise(samples);

                                    for(short frame : tmp)
                                    {
                                        System.out.println( "two: " + frame);                               
                                    }

                                    sBuff = ShortBuffer.wrap( tmp  , 0, samples.length); //cancel_noise(samples)

                                    close_noise();



                                    recorder.recordSamples( rate , numChannels, sBuff );

                                } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } 

                            }
                        }, 0, (long) ((long) 1000 / frameRate) , TimeUnit.MILLISECONDS);



                    } catch (LineUnavailableException e) {
                        e.printStackTrace();
                    }


                }
            }).start();

я хочу знать, есть ли проблема на Java-приложение или код C спасибо

0 ответов

Другие вопросы по тегам