diff --git a/AutoCoverTool/ref/tools/mixer/audio_effects_lib/CMakeLists.txt b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/CMakeLists.txt index 6724db8..03cfd63 100644 --- a/AutoCoverTool/ref/tools/mixer/audio_effects_lib/CMakeLists.txt +++ b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/CMakeLists.txt @@ -1,183 +1,184 @@ cmake_minimum_required(VERSION 3.4) project(audio_effects_lib) #set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") option(AELIB_BUILD_WHOLE_LIBS "Audio Effect Lib build as a whole lib" ON) option(WITH_FFT "Audio Effect Lib build with fft" ON) #add_definitions(-DAE_CONFUSE_CODE) include_directories(./) include_directories(inc common src) include_directories(ref) # 指定本机的ffmpeg地址,如果为arm编译,则不需要给,因为代码库中自带了 #include_directories(/Users/yangjianli/starMaker/ffmpeg_lib/ffmpeg-4.3.1/mac/include) #set(FFMPEG_LIB /Users/yangjianli/starMaker/ffmpeg_lib/ffmpeg-4.3.1/mac/lib) IF(NOT AELIB_BUILD_WHOLE_LIBS) # 子项目 add_subdirectory(ref) AUX_SOURCE_DIRECTORY(common SRC_COMMON_DIR) file(GLOB_RECURSE CPP_SRC_DIR src/*cpp) add_library(audio_effects_lib ${CPP_SRC_DIR} ${SRC_COMMON_DIR}) ELSE() include_directories(ref/al_reverb/inc) include_directories(ref/al_reverb/src) include_directories(ref/autotune/inc) include_directories(ref/autotune/src) include_directories(ref/iir_eq/inc) include_directories(ref/iir_eq/src) include_directories(ref/phonograph/inc) include_directories(ref/phonograph/src) include_directories(ref/reverb/inc) include_directories(ref/reverb/src) include_directories(ref/saudio_effects/inc) include_directories(ref/saudio_effects/src) include_directories(ref/slow_flanging/inc) include_directories(ref/slow_flanging/src) include_directories(ref/tone_shift/inc) include_directories(ref/tone_shift/src) #include_directories(ref/waves/inc) #include_directories(ref/waves/src) include_directories(ref/common) include_directories(ref/al_reverb/src/biquad_filters) include_directories(ref/al_reverb/src/fast_delay) include_directories(ref/al_reverb/src/filter) include_directories(ref/al_reverb/src/AlReverbApi.cpp) include_directories(ref/al_reverb/src/al_reverb) include_directories(ref/al_reverb/src/al_reverb_biquad) include_directories(ref/al_reverb/src/al_reverb_common) include_directories(ref/al_reverb/src/al_reverb_early_reflection) include_directories(ref/al_reverb/src/al_reverb_echo) include_directories(ref/al_reverb/src/al_reverb_late_allpass) include_directories(ref/al_reverb/src/al_reverb_late_lowpass) include_directories(ref/al_reverb/src/al_reverb_late_reverb) include_directories(ref/al_reverb/src/al_reverb_modulation) include_directories(ref/iir_eq/src/audacious_arma) include_directories(ref/iir_eq/src/audacious_eq) include_directories(ref/saudio_effects/src/all_plat ref/saudio_effects/src/audio_effect ref/saudio_effects/src/biquad ref/saudio_effects/src/buffer ref/saudio_effects/src/damper ref/saudio_effects/src/delay ref/saudio_effects/src/delayi ref/saudio_effects/src/envelope_follower ref/saudio_effects/src/equalizer ref/saudio_effects/src/reverb ref/saudio_effects/src/simple_delay_effect ref/saudio_effects/src/simple_reverb_effect) include_directories(ref/tone_shift/src/aa_filter) include_directories(ref/tone_shift/src/bpm_detect) include_directories(ref/tone_shift/src/cpu_detect) include_directories(ref/tone_shift/src/fifo_sample_buffer) include_directories(ref/tone_shift/src/fir_filter) include_directories(ref/tone_shift/src/peak_finder) include_directories(ref/tone_shift/src/rate_transposer) include_directories(ref/tone_shift/src/sound_touch) include_directories(ref/tone_shift/src/td_stretch) include_directories(ref/supersound/inc) include_directories(ref/supersound/src) include_directories(ref/supersound/src/common) include_directories(ref/supersound/src/impulse) include_directories(ref/supersound/ref) include_directories(ref/supersound/ref/kiss_fft) # include_directories(ref/audio_resample/inc) AUX_SOURCE_DIRECTORY(common SRC_COMMON_DIR) file(GLOB_RECURSE CPP_SRC_DIR src/*cpp) file(GLOB_RECURSE CPP_REF_DIR ref/*cpp) file(GLOB_RECURSE C_REF_DIR ref/*c) include_directories(ref/waves/inc) # include_directories(ref/audio_codec/inc) # list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/waves/src/STWaveFile.cpp") # list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/autotune/src/common/util/util.cpp") list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/audio_resample/src/FfmpegResampler.cpp") # IF(NOT WITH_FFT) # list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/supersound/ref/kiss_fft/kiss_fft.cpp") # list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/supersound/ref/kiss_fft/kiss_fftr.cpp") # list(REMOVE_ITEM CPP_REF_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ref/supersound/ref/kiss_fft/kiss_fftnd.c") # endif() add_library(audio_effects_lib ${CPP_SRC_DIR} ${CPP_REF_DIR} ${C_REF_DIR} ${SRC_COMMON_DIR}) # set_target_properties(audio_effects_lib PROPERTIES CXX_VISIBILITY_PRESET hidden) ENDIF() #set_target_properties(audio_effects_lib PROPERTIES CXX_VISIBILITY_PRESET hidden) #add_executable(main example/main.cpp example/ae_server/CAeServer.cpp) # 强制链接.a中的所有变量,否则每个类无法自动注册到map中,外部无法调用 # 静态链接库链接的时候,会将没有任何调用的变量抛弃 #if(APPLE) # target_link_libraries(main # -Wl,-all_load ${LIBRARY_OUTPUT_PATH}/libaudio_codec.a -Wl,-noall_load # ) # target_link_libraries(main # -Wl,-all_load ${LIBRARY_OUTPUT_PATH}/libaudio_effects_lib.a -Wl,-noall_load # ) #else() # target_link_libraries(main # -Wl,--whole-archive ${LIBRARY_OUTPUT_PATH}/libaudio_codec.a -Wl,--no-whole-archive # ) # target_link_libraries(main # -Wl,-all_load ${LIBRARY_OUTPUT_PATH}/libaudio_effects_lib.a -Wl,-noall_load # ) #endif() #add_executable(effect_im_tool example/effect_im_tool.cpp example/ae_server/CAeServer.cpp ${CPP_SRC_DIR} ${CPP_REF_DIR} ${C_REF_DIR} ${SRC_COMMON_DIR}) +add_executable(effect_tool example/effect_tool.cpp example/ae_server/CAeServer.cpp ${CPP_SRC_DIR} ${CPP_REF_DIR} ${C_REF_DIR} ${SRC_COMMON_DIR}) #if(APPLE) # target_link_libraries(effect_im_tool # -Wl,-all_load ${LIBRARY_OUTPUT_PATH}/libaudio_effects_lib.a -Wl,-noall_load # ) #else() # target_link_libraries(effect_im_tool # -Wl,--whole-archive ${LIBRARY_OUTPUT_PATH}/libaudio_effects_lib.a -Wl,--whole-archive # ) #endif() #target_link_libraries(effect_im_tool # -lpthread -lz -lbz2 -ldl # ) #target_link_libraries(main # ${LIBRARY_OUTPUT_PATH}/libaudio_effects_lib.a # ${LIBRARY_OUTPUT_PATH}/libwaves.a # ${LIBRARY_OUTPUT_PATH}/libiir_eq.a # ${LIBRARY_OUTPUT_PATH}/libsaudio_effects.a # ${LIBRARY_OUTPUT_PATH}/libautotune.a # ${LIBRARY_OUTPUT_PATH}/libreverb.a # ${LIBRARY_OUTPUT_PATH}/libal_reverb.a # ${LIBRARY_OUTPUT_PATH}/libphonograph.a # ${LIBRARY_OUTPUT_PATH}/libslow_flanging.a # ${LIBRARY_OUTPUT_PATH}/libref_common.a # ${LIBRARY_OUTPUT_PATH}/libtone_shift.a # ) # #target_link_libraries(main # ${FFMPEG_LIB}/libavfilter.a # ${FFMPEG_LIB}/libavformat.a # ${FFMPEG_LIB}/libavcodec.a # ${FFMPEG_LIB}/libswresample.a # ${FFMPEG_LIB}/libswscale.a # ${FFMPEG_LIB}/libavutil.a # -lz -lbz2 -liconv -llzma # "-framework VideoToolbox" # "-framework Security" # "-framework CoreFoundation" # "-framework CoreMedia" # "-framework CoreVideo" # "-framework VideoDecodeAcceleration" # "-framework AVFoundation" # "-framework CoreGraphics" # "-framework Foundation" # "-framework CoreServices" # ## ${LIBRARY_OUTPUT_PATH}/libwaves.a # ) diff --git a/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/ae_server/CAeServer.cpp b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/ae_server/CAeServer.cpp index 1406fad..3ba7607 100644 --- a/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/ae_server/CAeServer.cpp +++ b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/ae_server/CAeServer.cpp @@ -1,480 +1,480 @@ // // Created by yangjianli on 2020-01-16. // #include "CAeServer.h" #include "cstring" -#include "WaveFile.h" +#include "STWaveFile.h" #ifdef FFMEPG #include "DecoderWrapper.h" #endif //////////////////////////////////////////内部函数////////////////////////////////////////////////////////////// int32_t CAeServer::get_im_params_by_ffmpeg(void* params, Impulse_Param* new_param) { AE_PARAMS_IM_EFFECT* cur_params = (AE_PARAMS_IM_EFFECT*) params; // 空字符串则直接返回一个结构出去 if (cur_params->effect_path.empty()) { return AE_ERR_PARAMS_ERR; } std::string audio_path(cur_params->effect_path); if (m_im_path2params.find(audio_path) == m_im_path2params.end()) { #ifdef FFMPEG // 载入数据 CDecoderWrapper* m_decode_inst = new(std::nothrow) CDecoderWrapper(); if (NULL == m_decode_inst) { return AE_ERR_NO_BUFFER; } MediaParam param; param.duration = 0; param.prelude_time = 0; param.start_time = 0; param.end_time = 0; param.need_decrypt = false; param.path = cur_params->effect_path.c_str(); MediaInfo info; int errcode = m_decode_inst->init(¶m, m_sample_rate, m_channel, CONTEXT_FFMPEG, DECODER_FFMPEG, PROTOCOL_TYPE_FILE); if(0 != errcode) { m_decode_inst->uninit(); delete m_decode_inst; return errcode; } m_decode_inst->get_media_info(&info); // 解码音频 int frame_len = 512 * m_channel; int cap_len = int(info.duration * m_sample_rate / 1000.0 * m_channel) + 10; cap_len = (cap_len / frame_len + 1) * frame_len; int out_len = 0; float* out_buf = new float[cap_len]; AudioFrameBuffer m_tmp_buffer; m_tmp_buffer.init(512 * m_channel); errcode = m_decode_inst->decode(&m_tmp_buffer); while(E_NATIVE_DECODER_SUCCESS == errcode) { // 这种情况基本不会出现 if (cap_len < out_len + m_tmp_buffer.get_size()) { cap_len = out_len + m_tmp_buffer.get_size(); float* tmp_out = new float[cap_len]; memcpy(tmp_out, out_buf, sizeof(float) * out_len); delete[] out_buf; out_buf = tmp_out; } memcpy(out_buf+out_len, m_tmp_buffer.get_buffer(), sizeof(float) * m_tmp_buffer.get_size()); out_len += m_tmp_buffer.get_size(); memset(m_tmp_buffer.get_buffer(), 0, sizeof(float) * m_tmp_buffer.get_size()); errcode = m_decode_inst->decode(&m_tmp_buffer); } delete m_decode_inst; if (errcode != E_NATIVE_DECODER_END) { delete [] out_buf; return errcode; } #else - CWaveFile wave_im = CWaveFile(cur_params->effect_path.c_str(), false); + STCWaveFile wave_im = STCWaveFile(cur_params->effect_path.c_str(), false); if(!wave_im.GetStatus()) { return AE_ERR_NO_BUFFER; } int channel = wave_im.GetChannels(); int sample_rate = wave_im.GetSampleRate(); if (sample_rate != m_sample_rate || channel != m_channel) { printf("impluse params err!\n"); return AE_ERR_NO_BUFFER; } int out_len = wave_im.GetTotalFrames() * channel; float* out_buf = new float[out_len]; wave_im.ReadFrameAsfloat(out_buf, out_len / channel); #endif Impulse_Param* im_params = new Impulse_Param(); im_params->in_channels = m_channel; im_params->out_channels = m_channel; im_params->fs = m_sample_rate; im_params->im_response = out_buf; im_params->response_len = out_len / m_channel; im_params->response_channels = m_channel; // 一般最小是192的buffer_size,fft搞小一点,更合适 im_params->window_bits = 9; im_params->process_buffer_len = m_buffer_size; im_params->high_performance = true; im_params->effect_path = cur_params->effect_path; m_im_path2params[audio_path] = im_params; // STCWaveFile wave_out = STCWaveFile("/Users/yangjianli/starmaker-work/research/tmp_code/音效相关/test1/t1.wav", true); // wave_out.SetChannels(m_channel); // wave_out.SetSampleRate(m_sample_rate); // wave_out.SetSampleFormat(SF_IEEE_FLOAT); // wave_out.SetupDone(); // wave_out.WriteFrame(out_buf, out_len / m_channel); } copy_impluse_params(new_param, m_im_path2params[audio_path]); return AE_ERR_SUCCESS; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// CAeServer::CAeServer() { m_chain = nullptr; m_ae2group_id.clear(); m_ae2inst_map.clear(); m_ae_group.clear(); } CAeServer::~CAeServer() { uninit(); } int32_t CAeServer::init(int sample_rate, int channel, int buffer_size) { m_chain = ae_create_object(); ae_init(m_chain, sample_rate, channel); AE_TYPE ae_types[] = {AE_TYPE_NONE, AE_TYPE_KTV, AE_TYPE_AUTOTUNE,AE_TYPE_DISTANT, AE_TYPE_WARM,AE_TYPE_PHONOGRAPH,AE_TYPE_MAGNETIC,AE_TYPE_ETHEREAL, AE_TYPE_DIZZY,AE_TYPE_NEW_DISTANT,AE_TYPE_TONE_SHIFT,AE_TYPE_CUSTOM, AE_TYPE_KARAOKE,SAE_POP,SAE_STUDIO, AE_TYPE_IM_EFFECT}; combine_group(ae_types, 16); AE_TYPE ae_types1[] = {EQ_TYPE_BEGIN, EQ_TYPE_END}; combine_group(ae_types1, 2); m_sample_rate = sample_rate; m_channel = channel; m_buffer_size = buffer_size; return AE_ERR_SUCCESS; } int32_t CAeServer::uninit() { if(nullptr != m_chain) { ae_destory_object(m_chain); m_chain = nullptr; } m_ae_group.clear(); m_ae2inst_map.clear(); m_ae2group_id.clear(); // 删除im效果器中所有参数映射过的结果 std::map::iterator itt; for(itt = m_im_path2params.begin(); itt != m_im_path2params.end(); itt++) { if (itt->second != NULL) { if (itt->second->im_response != NULL) { delete[] itt->second->im_response; itt->second->im_response = NULL; } delete itt->second; itt->second = NULL; } } m_im_path2params.clear(); return AE_ERR_SUCCESS; } int CAeServer::get_latency_ms() { return ae_get_latency_ms(m_chain); } int32_t CAeServer::reset() { return ae_reset(m_chain); } int32_t CAeServer::get_ae_effect_params(AE_TYPE ae_type, void *ae_params, AE_EFFECT_TYPE &ae_effect_type, void*& ret) { pAECustomParam tp_custom; AE_PARAMS_REVERB* tp_reverb; int err_code = AE_ERR_SUCCESS; switch(ae_type){ case AE_TYPE_KTV: ae_effect_type = AE_EFFECT_TYPE_REVERB; ret = new AE_PARAMS_REVERB(); memcpy(ret, &gs_ae_params_reverb_params[AE_PARAMS_TYPE_REVERB_ID_11 - AE_PARAMS_TYPE_RERVERB], sizeof(AE_PARAMS_REVERB)); break; case AE_TYPE_AUTOTUNE: ae_effect_type = AE_EFFECT_TYPE_AUTOTUNE; break; case AE_TYPE_DISTANT: ae_effect_type = AE_EFFECT_TYPE_REVERB; ret = new AE_PARAMS_REVERB(); memcpy(ret, &gs_ae_params_reverb_params[AE_PARAMS_TYPE_REVERB_ID_15 - AE_PARAMS_TYPE_RERVERB], sizeof(AE_PARAMS_REVERB)); break; case AE_TYPE_WARM: ae_effect_type = AE_EFFECT_TYPE_AL_REVERB; ret = new AE_PARAMS_AL_REVERB(); memcpy(ret, &gs_ae_params_al_reverbs[AE_PARAMS_TYPE_AL_REVERB_CITY_STREETS - AE_PARAMS_TYPE_AL_REVERB], sizeof(AE_PARAMS_AL_REVERB)); break; case AE_TYPE_PHONOGRAPH: ae_effect_type = AE_EFFECT_TYPE_PHONOGRAPH; break; case AE_TYPE_MAGNETIC: ae_effect_type = AE_EFFECT_TYPE_AL_REVERB; ret = new AE_PARAMS_AL_REVERB(); memcpy(ret, &gs_ae_params_al_reverbs[AE_PARAMS_TYPE_AL_REVERB_GENERIC_1 - AE_PARAMS_TYPE_AL_REVERB], sizeof(AE_PARAMS_AL_REVERB)); break; case AE_TYPE_ETHEREAL: ae_effect_type = AE_EFFECT_TYPE_AL_REVERB; ret = new AE_PARAMS_AL_REVERB(); memcpy(ret, &gs_ae_params_al_reverbs[AE_PARAMS_TYPE_AL_REVERB_CASTLE_COURTYARD - AE_PARAMS_TYPE_AL_REVERB], sizeof(AE_PARAMS_AL_REVERB)); break; case AE_TYPE_DIZZY: ae_effect_type = AE_EFFECT_TYPE_SLOWFLANGING; break; case AE_TYPE_NEW_DISTANT: ae_effect_type = AE_EFFECT_TYPE_REVERB; ret = new AE_PARAMS_REVERB(); memcpy(ret, &gs_ae_params_reverb_params[AE_PARAMS_TYPE_REVERB_NEW_CONCERT - AE_PARAMS_TYPE_RERVERB], sizeof(AE_PARAMS_REVERB)); break; case AE_TYPE_TONE_SHIFT: ae_effect_type = AE_EFFECT_TYPE_TONE_SHIFT; ret = new AE_PARAMS_TONE_SHIFT(); ((AE_PARAMS_TONE_SHIFT*) ret)->shift_value = ((AEToneShiftParam*) ae_params)->tone_shift; break; case AE_TYPE_CUSTOM: ae_effect_type = AE_EFFECT_TYPE_REVERB; ret = new AE_PARAMS_REVERB(); memcpy(ret, &gs_ae_params_reverb_params[AE_PARAMS_TYPE_REVERB_ID_18 - AE_PARAMS_TYPE_RERVERB], sizeof(AE_PARAMS_REVERB)); tp_custom = (pAECustomParam) ae_params; tp_reverb = (AE_PARAMS_REVERB*) ret; tp_reverb->wet = tp_custom->reverb_wet / 3.0; // 兼容android当前的使用方式 tp_reverb->room_size = tp_custom->room_size; break; case AE_TYPE_KARAOKE: ae_effect_type = AE_EFFECT_TYPE_REVERB; ret = new AE_PARAMS_REVERB(); memcpy(ret, &gs_ae_params_reverb_params[AE_PARAMS_TYPE_REVERB_ID_18 - AE_PARAMS_TYPE_RERVERB], sizeof(AE_PARAMS_REVERB)); break; case SAE_POP: ae_effect_type = AE_EFFECT_TYPE_SAE; ret = new AE_PARAMS_SAE(); ((AE_PARAMS_SAE*)ret)->params_list.assign( gs_sae_params[AE_PARAMS_TYPE_SAE_POP - AE_PARAMS_TYPE_SAE].params_list.begin(), gs_sae_params[AE_PARAMS_TYPE_SAE_POP - AE_PARAMS_TYPE_SAE].params_list.end() ); break; case SAE_STUDIO: ae_effect_type = AE_EFFECT_TYPE_SAE; ret = new AE_PARAMS_SAE(); ((AE_PARAMS_SAE*)ret)->params_list.assign( gs_sae_params[AE_PARAMS_TYPE_SAE_STUDIO - AE_PARAMS_TYPE_SAE].params_list.begin(), gs_sae_params[AE_PARAMS_TYPE_SAE_STUDIO - AE_PARAMS_TYPE_SAE].params_list.end() ); break; case EQ_TYPE_END: ae_effect_type = AE_EFFECT_TYPE_EQ; ret = new AE_PARAMS_EQ(); memcpy(ret, ae_params, sizeof(AE_PARAMS_EQ)); break; case AE_TYPE_IM_EFFECT: ae_effect_type = AE_EFFECT_TYPE_IM_EFFECT; ret = new Impulse_Param (); // 内部的对象地址是复制的,不会被释放,将由外部做释放 err_code = get_im_params_by_ffmpeg(ae_params, (Impulse_Param*)ret); break; default: ae_effect_type = AE_EFFECT_TYPE_NONE; } return err_code; } int32_t CAeServer::combine_group(AE_TYPE *ae_types, int size) { int group_id = m_ae_group.size(); for(int i=0;i::iterator iter = m_ae2group_id.find(ae_type); if(iter != m_ae2group_id.end()) { int group_id = iter->second; if(group_id >= 0 && group_id < m_ae_group.size()) { // 删除ae2inst中效果 std::map::iterator itt; for(itt = m_ae2inst_map.begin(); itt != m_ae2inst_map.end(); itt++) { if(m_ae_group[group_id] == itt->second) { m_ae2inst_map.erase(itt); break; } } // 删除效果,去掉type2ins映射 ae_delete_effect(m_chain, m_ae_group[group_id]); m_ae_group[group_id] = nullptr; // 这块搞空 } } return AE_ERR_SUCCESS; } // 判断是否在效果链上 std::map::iterator it = m_ae2inst_map.find(ae_type); if(it != m_ae2inst_map.end()) { // 在效果链上 ae_set_params(m_chain, it->second, ae_params); }else { // 没在链上,添加效果 void* new_effect_ptr = ae_add_effect(m_chain, effect_type); if(nullptr == new_effect_ptr) { // 没有该效果 if(nullptr != ae_params) { delete ae_params; } return AE_ERR_NO_EFFECTS; } ae_set_params(m_chain, new_effect_ptr, ae_params); m_ae2inst_map.insert(std::make_pair(ae_type, new_effect_ptr)); // 删除该效果所在分组的其他效果 std::map::iterator iter = m_ae2group_id.find(ae_type); if(iter != m_ae2group_id.end()) { int group_id = iter->second; if(group_id >= 0 && group_id < m_ae_group.size()) { // 删除分组音效,存放上自己的音效 if(nullptr != m_ae_group[group_id]) { // 删除ae2inst中效果 std::map::iterator itt; for(itt = m_ae2inst_map.begin(); itt != m_ae2inst_map.end(); itt++) { if(m_ae_group[group_id] == itt->second) { m_ae2inst_map.erase(itt); break; } } // 删除效果,去掉type2ins映射 ae_delete_effect(m_chain, m_ae_group[group_id]); m_ae_group[group_id] = nullptr; // 这块搞空 } m_ae_group[group_id] = new_effect_ptr; } } } // 在上面return 不需要处理的原因是,当出现上述条件时,ae_params // 没有被创建 if(nullptr != ae_params) { delete ae_params; } return AE_ERR_SUCCESS; } int32_t CAeServer::get_params(AE_TYPE ae_type, void *params) { std::map::iterator it = m_ae2inst_map.find(ae_type); if(it != m_ae2inst_map.end()) { // 在效果链上才有结果 // 根据对应的类型选择参数结构 AE_EFFECT_TYPE effect_type; void* cur_params = nullptr; int err_code = get_ae_effect_params(ae_type, params, effect_type, cur_params); if (cur_params == nullptr) { return err_code; } AE_PARAMS* ae_params = (AE_PARAMS*)cur_params; ae_get_params(m_chain, it->second, (AE_PARAMS*) ae_params); switch (ae_type) { case AE_TYPE_TONE_SHIFT: { pAEToneShiftParam tp_server = (pAEToneShiftParam) params; AE_PARAMS_TONE_SHIFT* tp_system = (AE_PARAMS_TONE_SHIFT*) ae_params; tp_server->tone_shift = int(tp_system->shift_value); tp_server->max_shift = int(tp_system->max_value); tp_server->min_shift = int(tp_system->min_value); break; } case AE_TYPE_CUSTOM: { pAECustomParam tp_server = (pAECustomParam) params; AE_PARAMS_REVERB* tp_system = (AE_PARAMS_REVERB*) ae_params; tp_server->reverb_wet = tp_system->wet; tp_server->room_size = tp_system->room_size; break; } case AE_TYPE_IM_EFFECT: { AE_PARAMS_IM_EFFECT* tp_server = (AE_PARAMS_IM_EFFECT*) params; Impulse_Param * tp_system = (Impulse_Param*) ae_params; tp_server->effect_path = tp_system->effect_path; break; } case EQ_TYPE_END: { pAECustomEqParam tp_server = (pAECustomEqParam) params; AE_PARAMS_EQ* tp_system = (AE_PARAMS_EQ*) ae_params; memcpy(tp_server->params, tp_system->params, sizeof(float) * 10); } } delete ae_params; return AE_ERR_SUCCESS; } return AE_ERR_EFFECT_NOT_IN_CHAIN; } int32_t CAeServer::process(float *in_buf, float *out_buf, int length) { return ae_process(m_chain, in_buf, out_buf, length); } diff --git a/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/effect_tool.cpp b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/effect_tool.cpp new file mode 100644 index 0000000..cfb1b97 --- /dev/null +++ b/AutoCoverTool/ref/tools/mixer/audio_effects_lib/example/effect_tool.cpp @@ -0,0 +1,70 @@ +// +// Created by Administrator on 2024/6/18. +// +#include "CAudioEffectsChainApi.h" +#include "iir_eq/inc/CAudaciousEqApi.h" +#include "waves/inc/STWaveFile.h" +#include "string" +#include "saudio_effects/inc/SAudioEffectsApi.h" +#include "autotune/inc/ATndkWrapper.h" +#include "reverb/inc/CReverb.h" +#include "al_reverb/inc/AlReverbApi.h" +#include "phonograph/inc/CPhonograph.h" +#include "slow_flanging/inc/CSlowFlanging.h" +#include "tone_shift/inc/CToneShift.h" +#include "tone_shift/inc/CSpeedShift.h" +#include "ae_server/CAeServer.h" +#include +#include +#include +#include +#include +void cae_server_float(const char* in_file, const char* out_file) +{ + STCWaveFile oWaveFile = STCWaveFile(in_file, false); + int length = oWaveFile.GetTotalFrames() * oWaveFile.GetChannels(); + int sample_rate = oWaveFile.GetSampleRate(); + int channel = oWaveFile.GetChannels(); + float* in_buf = new float[length]; + oWaveFile.ReadFrameAsfloat(in_buf, oWaveFile.GetTotalFrames()); + + // 处理逻辑 + int32_t process_buffer_len = 2048; + CAeServer cAeServer; + cAeServer.init(sample_rate, channel, process_buffer_len); + + cAeServer.set_params(AE_TYPE_KARAOKE, NULL); + int step = process_buffer_len * channel; + + struct timeval start; + struct timeval end; + gettimeofday(&start, NULL); + for(int i=0,frame=0;i length) step = length - i; + cAeServer.process(in_buf + i, in_buf + i, step); + } + cAeServer.uninit(); + + // 保存起来 + STCWaveFile out_file_inst = STCWaveFile(out_file, true); + out_file_inst.SetSampleRate(sample_rate); + out_file_inst.SetSampleFormat(SF_IEEE_FLOAT); + out_file_inst.SetChannels(channel); + out_file_inst.SetupDone(); + out_file_inst.WriteFrame(in_buf, length / channel); +} + +int main(int argc, char* argv[]) +{ + if(argc != 3) + { + printf("input err! ./main s_audio_path(wav) out_path(wav)\n"); + return -1; + } + + std::string sAudio = argv[1]; + std::string sAudioOut = argv[2]; + cae_server_float(sAudio.c_str(), sAudioOut.c_str()); + return 0; +} \ No newline at end of file