static void sound_read_preprocess(MSFilter *f){
	msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data;
	ms_debug("andsnd_read_preprocess");
	if (!d->started)
		sound_read_setup(f);
	ms_ticker_set_time_func(f->ticker,(uint64_t (*)(void*))ms_ticker_synchronizer_get_corrected_time, d->ticker_synchronizer);
}
static void sound_read_preprocess(MSFilter *f) {
    msandroid_sound_read_data *d=(msandroid_sound_read_data*)f->data;
    ms_debug("andsnd_read_preprocess");
    if (!d->started)
        sound_read_setup(f);
    ms_ticker_set_time_func(f->ticker,(uint64_t (*)(void*))ms_ticker_synchronizer_get_corrected_time, d->ticker_synchronizer);

    if (d->builtin_aec && d->audio_record) {
        //JNIEnv *env=ms_get_jni_env();

        JNIEnv *env = NULL;
        JavaVM *jvm = ms_get_jvm();
        if (jvm->AttachCurrentThread(&env, NULL)!=0) {
            ms_fatal("AttachCurrentThread() failed !");
            return;
        }
        jmethodID getsession_id=0;
        int sessionId=-1;
        getsession_id = env->GetMethodID(d->audio_record_class,"getAudioSessionId", "()I");
        if(getsession_id==0) {
            ms_error("cannot find AudioRecord.getAudioSessionId() method");
            jvm->DetachCurrentThread();
            return;
        }
        sessionId = env->CallIntMethod(d->audio_record,getsession_id);
        ms_message("AudioRecord.getAudioSessionId() returned %i", sessionId);
        if (sessionId==-1) {
            jvm->DetachCurrentThread();
            return;
        }
        d->aec = enable_hardware_echo_canceller(env, sessionId);
        jvm->DetachCurrentThread();
    }
}
static int get_latency(MSFilter *f, void *arg){
	msandroid_sound_data *d=(msandroid_sound_data*)f->data;
	if (!d->started){
		sound_read_setup(f);
		*((int*)arg)=(1000*d->buff_size)/(d->nchannels*2*d->rate);
	}
	return 0;
}