From 318ba98c2b0bb954bdff35915037bf0c90e591f3 Mon Sep 17 00:00:00 2001 From: xufuji456 <839789740@qq.com> Date: Fri, 17 Sep 2021 00:37:59 +0800 Subject: [PATCH] do fft directly --- app/src/main/cpp/audio_player.cpp | 30 ++---- app/src/main/cpp/visualizer/execute_fft.c | 120 +++++++++++++++++++++- app/src/main/cpp/visualizer/execute_fft.h | 2 + 3 files changed, 128 insertions(+), 24 deletions(-) diff --git a/app/src/main/cpp/audio_player.cpp b/app/src/main/cpp/audio_player.cpp index 9cefc37..14c2725 100644 --- a/app/src/main/cpp/audio_player.cpp +++ b/app/src/main/cpp/audio_player.cpp @@ -34,11 +34,7 @@ int filter_again = 0; int filter_release = 0; const char *filter_desc = "superequalizer=6b=4:8b=5:10b=5"; -JavaVM *java_vm; -jobject jni_object; -jmethodID fft_method; - -static void fft_callback(void* arg); +void fft_callback(JNIEnv *jniEnv, jobject thiz, jmethodID fft_method, int16_t* arg); int init_volume_filter(AVFilterGraph **graph, AVFilterContext **src, AVFilterContext **sink, uint64_t channel_layout, AVSampleFormat inputFormat, int sample_rate) { @@ -287,15 +283,14 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { // goto end; } - env->GetJavaVM(&java_vm); - jni_object = env->NewGlobalRef(thiz); - fft_method = env->GetMethodID(player_class, "fftCallbackFromJNI", "([I)V"); + jmethodID fft_method = env->GetMethodID(player_class, "fftCallbackFromJNI", "([I)V"); filter_sys_t *fft_filter = static_cast(malloc(sizeof(filter_sys_t))); open_visualizer(fft_filter); auto *block = static_cast(malloc(sizeof(block_t))); block->i_nb_samples = 0; - block->fft_callback.callback = fft_callback; +// block->fft_callback.callback = fft_callback; + int16_t *output = static_cast(malloc(FFT_BUFFER_SIZE * sizeof(int16_t))); //read audio frame while (av_read_frame(pFormatCtx, packet) >= 0 && !filter_release) { @@ -327,7 +322,8 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { if (block->i_nb_samples == frame->nb_samples) { LOGE(TAG, "start frame->nb_samples=%d", frame->nb_samples); memcpy(block->p_buffer, frame->data[0], static_cast(frame->nb_samples)); - filter_audio(fft_filter, block); + fft_once(fft_filter, block, output); + fft_callback(env, thiz, fft_method, output); } ret = av_buffersrc_add_frame(audioSrcContext, frame); @@ -390,14 +386,8 @@ AUDIO_PLAYER_FUNC(void, release) { filter_release = 1; } -static void fft_callback(void* arg) { -// float* data = (float*) arg; -// LOGE(TAG, "fft data[0]=%f,data[1]=%f,data[2]=%f", data[0], data[1], data[2]); - - JNIEnv *jniEnv = nullptr; - java_vm->AttachCurrentThread(&jniEnv, nullptr); - jintArray dataArray = jniEnv->NewIntArray(/*20*/256); - jniEnv->SetIntArrayRegion(dataArray, 0, /*20*/256, (int*)arg); - jniEnv->CallVoidMethod(jni_object, fft_method, dataArray); - java_vm->DetachCurrentThread(); +void fft_callback(JNIEnv *jniEnv, jobject thiz, jmethodID fft_method, int16_t * arg) { + jintArray dataArray = jniEnv->NewIntArray(256); + jniEnv->SetIntArrayRegion(dataArray, 0, 256, (int*)arg); + jniEnv->CallVoidMethod(thiz, fft_method, dataArray); } \ No newline at end of file diff --git a/app/src/main/cpp/visualizer/execute_fft.c b/app/src/main/cpp/visualizer/execute_fft.c index 28ab61d..a50822f 100644 --- a/app/src/main/cpp/visualizer/execute_fft.c +++ b/app/src/main/cpp/visualizer/execute_fft.c @@ -35,11 +35,11 @@ window_get_param(&p_sys->wind_param); /* Create the FIFO for the audio data. */ - vlc_queue_t *queue = vlc_queue_init(5); - p_sys->queue = *queue; - p_sys->dead = false; +// vlc_queue_t *queue = vlc_queue_init(5); +// p_sys->queue = *queue; +// p_sys->dead = false; - pthread_create (&p_sys->thread, NULL, fft_thread, p_sys); +// pthread_create (&p_sys->thread, NULL, fft_thread, p_sys);//TODO return VLC_SUCCESS; } @@ -197,3 +197,115 @@ release: return NULL; } + +void fft_once(void *p_data, block_t *block, int16_t *output) +{ + filter_sys_t *p_sys = (filter_sys_t*)p_data; + + float height[NB_BANDS] = {0}; + + /* Horizontal scale for 20-band equalizer */ + const unsigned xscale[] = {0,1,2,3,4,5,6,7,8,11,15,20,27, + 36,47,62,82,107,141,184,255}; + + fft_state *p_state = NULL; /* internal FFT data */ + DEFINE_WIND_CONTEXT(wind_ctx); /* internal window data */ + + unsigned i, j; + float p_output[FFT_BUFFER_SIZE]; /* Raw FFT Result */ + int16_t p_buffer1[FFT_BUFFER_SIZE]; /* Buffer on which we perform + the FFT (first channel) */ + int16_t p_dest[FFT_BUFFER_SIZE]; /* Adapted FFT result */ + float *p_buffl = (float*)block->p_buffer; /* Original buffer */ + + int16_t *p_buffs; /* int16_t converted buffer */ + int16_t *p_s16_buff; /* int16_t converted buffer */ + + if (!block->i_nb_samples) { + LOGE("no samples yet..."); + goto release; + } + + /* Allocate the buffer only if the number of samples change */ + if (block->i_nb_samples != p_sys->i_prev_nb_samples) + { + free(p_sys->p_prev_s16_buff); + p_sys->p_prev_s16_buff = malloc(block->i_nb_samples * + p_sys->i_channels * + sizeof(int16_t)); + if (!p_sys->p_prev_s16_buff) + goto release; + p_sys->i_prev_nb_samples = block->i_nb_samples; + } + p_buffs = p_s16_buff = p_sys->p_prev_s16_buff; + + /* Convert the buffer to int16_t */ + for (i = block->i_nb_samples * p_sys->i_channels; i--;) + { + union {float f; int32_t i;} u; + + u.f = *p_buffl + 384.f; + if (u.i > 0x43c07fff) + *p_buffs = 32767; + else if (u.i < 0x43bf8000) + *p_buffs = -32768; + else + *p_buffs = u.i - 0x43c00000; + + p_buffl++; p_buffs++; + } + p_state = visual_fft_init(); + if (!p_state) + { + LOGE("unable to initialize FFT transform..."); + goto release; + } + if (!window_init(FFT_BUFFER_SIZE, &p_sys->wind_param, &wind_ctx)) + { + LOGE("unable to initialize FFT window..."); + goto release; + } + p_buffs = p_s16_buff; + for (i = 0 ; i < FFT_BUFFER_SIZE; i++) + { + p_output[i] = 0; + p_buffer1[i] = *p_buffs; + + p_buffs += p_sys->i_channels; + if (p_buffs >= &p_s16_buff[block->i_nb_samples * p_sys->i_channels]) + p_buffs = p_s16_buff; + } + window_scale_in_place (p_buffer1, &wind_ctx); + fft_perform (p_buffer1, p_output, p_state); + + for (i = 0; i< FFT_BUFFER_SIZE; ++i) + p_dest[i] = p_output[i] * (2 ^ 16) + / ((FFT_BUFFER_SIZE / 2 * 32768) ^ 2); + + for (i = 0 ; i < NB_BANDS; i++) + { + /* Decrease the previous size of the bar. */ + height[i] -= BAR_DECREMENT; + if (height[i] < 0) + height[i] = 0; + + int y = 0; + /* We search the maximum on one scale + to determine the current size of the bar. */ + for (j = xscale[i]; j < xscale[i + 1]; j++) + { + if (p_dest[j] > y) + y = p_dest[j]; + } + /* Calculate the height of the bar */ + float new_height = y != 0 ? logf(y) * 0.4f : 0; + height[i] = new_height > height[i] + ? new_height : height[i]; + } + + memcpy(output, p_dest, FFT_BUFFER_SIZE); + +release: + window_close(&wind_ctx); + fft_close(p_state); +} diff --git a/app/src/main/cpp/visualizer/execute_fft.h b/app/src/main/cpp/visualizer/execute_fft.h index 6b8e6fc..fd6b707 100644 --- a/app/src/main/cpp/visualizer/execute_fft.h +++ b/app/src/main/cpp/visualizer/execute_fft.h @@ -45,4 +45,6 @@ static void *fft_thread(void *); /*static*/ void close_visualizer(filter_sys_t *p_filter); +void fft_once(void *p_data, block_t *block, int16_t *output); + #endif //PLAYER_CORE_RUN_FFT_H