|  |  |  | @ -25,7 +25,6 @@ extern "C" { | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define TAG "AudioPlayer" | 
			
		
	
		
			
				
					|  |  |  |  | #define VOLUME_VAL 0.50 | 
			
		
	
		
			
				
					|  |  |  |  | #define SLEEP_TIME (1000 * 16) | 
			
		
	
		
			
				
					|  |  |  |  | #define MAX_AUDIO_FRAME_SIZE (48000 * 4) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -36,104 +35,6 @@ FrankVisualizer *mVisualizer; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void fft_callback(JNIEnv *jniEnv, jobject thiz, jmethodID fft_method, int8_t* arg, int samples); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int init_volume_filter(AVFilterGraph **graph, AVFilterContext **src, AVFilterContext **sink, | 
			
		
	
		
			
				
					|  |  |  |  |         uint64_t channel_layout, AVSampleFormat inputFormat, int sample_rate) { | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterGraph   *filter_graph; | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterContext *buffer_ctx; | 
			
		
	
		
			
				
					|  |  |  |  |     const AVFilter  *buffer; | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterContext *volume_ctx; | 
			
		
	
		
			
				
					|  |  |  |  |     const AVFilter  *volume; | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterContext *buffersink_ctx; | 
			
		
	
		
			
				
					|  |  |  |  |     const AVFilter  *buffersink; | 
			
		
	
		
			
				
					|  |  |  |  |     AVDictionary *options_dict = nullptr; | 
			
		
	
		
			
				
					|  |  |  |  |     uint8_t ch_layout[64]; | 
			
		
	
		
			
				
					|  |  |  |  |     int ret; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /* Create a new filter graph, which will contain all the filters. */ | 
			
		
	
		
			
				
					|  |  |  |  |     filter_graph = avfilter_graph_alloc(); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!filter_graph) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Unable to create filter graph..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR(ENOMEM); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /* Create the abuffer filter: feed data into the graph. */ | 
			
		
	
		
			
				
					|  |  |  |  |     buffer = avfilter_get_by_name("abuffer"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!buffer) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not find the buffer filter..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR_FILTER_NOT_FOUND; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     buffer_ctx = avfilter_graph_alloc_filter(filter_graph, buffer, "src"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!buffer_ctx) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not allocate the buffer instance..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR(ENOMEM); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /* Set the filter options through the AVOptions API. */ | 
			
		
	
		
			
				
					|  |  |  |  |     av_get_channel_layout_string(reinterpret_cast<char *>(ch_layout), sizeof(ch_layout), 0, channel_layout); | 
			
		
	
		
			
				
					|  |  |  |  |     av_opt_set    (buffer_ctx, "channel_layout", reinterpret_cast<char *>(ch_layout), AV_OPT_SEARCH_CHILDREN); | 
			
		
	
		
			
				
					|  |  |  |  |     av_opt_set    (buffer_ctx, "sample_fmt",     av_get_sample_fmt_name(inputFormat), AV_OPT_SEARCH_CHILDREN); | 
			
		
	
		
			
				
					|  |  |  |  |     av_opt_set_q  (buffer_ctx, "time_base",      (AVRational){ 1, sample_rate },      AV_OPT_SEARCH_CHILDREN); | 
			
		
	
		
			
				
					|  |  |  |  |     av_opt_set_int(buffer_ctx, "sample_rate",    sample_rate,                         AV_OPT_SEARCH_CHILDREN); | 
			
		
	
		
			
				
					|  |  |  |  |     ret = avfilter_init_str(buffer_ctx, nullptr); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not initialize the buffer filter:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |         return ret; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /* Create volume filter. */ | 
			
		
	
		
			
				
					|  |  |  |  |     volume = avfilter_get_by_name("volume"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!volume) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not find the volume filter..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR_FILTER_NOT_FOUND; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     volume_ctx = avfilter_graph_alloc_filter(filter_graph, volume, "volume"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!volume_ctx) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not allocate the volume instance..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR(ENOMEM); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /* Passing the options is as key/value pairs in a dictionary. */ | 
			
		
	
		
			
				
					|  |  |  |  |     av_dict_set(&options_dict, "volume", AV_STRINGIFY(VOLUME_VAL), 0); | 
			
		
	
		
			
				
					|  |  |  |  |     ret = avfilter_init_dict(volume_ctx, &options_dict); | 
			
		
	
		
			
				
					|  |  |  |  |     av_dict_free(&options_dict); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not initialize the volume filter:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |         return ret; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /* Create the abuffersink filter: get the filtered data from graph. */ | 
			
		
	
		
			
				
					|  |  |  |  |     buffersink = avfilter_get_by_name("abuffersink"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!buffersink) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not find the abuffersink filter..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR_FILTER_NOT_FOUND; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     buffersink_ctx = avfilter_graph_alloc_filter(filter_graph, buffersink, "sink"); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!buffersink_ctx) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not allocate the abuffersink instance..."); | 
			
		
	
		
			
				
					|  |  |  |  |         return AVERROR(ENOMEM); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     ret = avfilter_init_str(buffersink_ctx, nullptr); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Could not initialize the abuffersink instance:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |         return ret; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /* Connect the filters */ | 
			
		
	
		
			
				
					|  |  |  |  |     ret = avfilter_link(buffer_ctx, 0, volume_ctx, 0); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret >= 0) | 
			
		
	
		
			
				
					|  |  |  |  |         ret = avfilter_link(volume_ctx, 0, buffersink_ctx, 0); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Error connecting filters:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |         return ret; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     /* Configure the graph. */ | 
			
		
	
		
			
				
					|  |  |  |  |     ret = avfilter_graph_config(filter_graph, nullptr); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Error configuring the filter graph:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |         return ret; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     *graph = filter_graph; | 
			
		
	
		
			
				
					|  |  |  |  |     *src   = buffer_ctx; | 
			
		
	
		
			
				
					|  |  |  |  |     *sink  = buffersink_ctx; | 
			
		
	
		
			
				
					|  |  |  |  |     return 0; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int init_equalizer_filter(const char *filter_description, AVCodecContext *codecCtx, AVFilterGraph **graph, | 
			
		
	
		
			
				
					|  |  |  |  |         AVFilterContext **src, AVFilterContext **sink) { | 
			
		
	
		
			
				
					|  |  |  |  |     int ret = 0; | 
			
		
	
	
		
			
				
					|  |  |  | @ -203,7 +104,7 @@ end: | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { | 
			
		
	
		
			
				
					|  |  |  |  |     int got_frame = 0, ret = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     int got_frame = 0, ret; | 
			
		
	
		
			
				
					|  |  |  |  |     AVPacket packet; | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterGraph *audioFilterGraph; | 
			
		
	
		
			
				
					|  |  |  |  |     AVFilterContext *audioSrcContext; | 
			
		
	
	
		
			
				
					|  |  |  | @ -273,8 +174,6 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     /* Set up the filter graph. */ | 
			
		
	
		
			
				
					|  |  |  |  |     AVFrame *filter_frame = av_frame_alloc(); | 
			
		
	
		
			
				
					|  |  |  |  | //    ret = init_volume_filter(&audioFilterGraph, &audioSrcContext, &audioSinkContext,
 | 
			
		
	
		
			
				
					|  |  |  |  | //            in_ch_layout, in_sample_fmt, in_sample_rate);
 | 
			
		
	
		
			
				
					|  |  |  |  |     ret = init_equalizer_filter(filter_desc, codecCtx, &audioFilterGraph, &audioSrcContext, &audioSinkContext); | 
			
		
	
		
			
				
					|  |  |  |  |     if (ret < 0) { | 
			
		
	
		
			
				
					|  |  |  |  |         LOGE(TAG, "Unable to init filter graph:%d", ret); | 
			
		
	
	
		
			
				
					|  |  |  | @ -317,7 +216,7 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { | 
			
		
	
		
			
				
					|  |  |  |  |                 LOGE(TAG, "Error add the frame to the filter graph:%d", ret); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             /* Get all the filtered output that is available. */ | 
			
		
	
		
			
				
					|  |  |  |  |             while (1) { | 
			
		
	
		
			
				
					|  |  |  |  |             while (true) { | 
			
		
	
		
			
				
					|  |  |  |  |                 ret = av_buffersink_get_frame(audioSinkContext, filter_frame); | 
			
		
	
		
			
				
					|  |  |  |  |                 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
	
		
			
				
					|  |  |  | 
 |