音频特效实践 | 您所在的位置:网站首页 › audacity频谱图怎么放大 › 音频特效实践 |
音频特效
基础概念
波形图
波形图横轴是时间,纵轴为强度。 在波形图中选取一段时间的音频,快速傅立叶变换(FFT)可以得到频谱图。 频谱图的横轴为频率,纵轴为强度。 语谱图横轴为时间,纵轴为频率,颜色表示强度。 它是由STFT(短时傅里叶变换)得到。可以理解它是将时域的数据按固定的窗口分段进行FFT变换,然后叠加在一起。 可以把它理解为一个三位图形,但是用二维的形式呈现给了用户,即x轴为时间,y轴为频率,z轴为强度。 均衡器可以提高/降低一段音频信号中某段频率的强度。比如我想比较喜欢一首歌的低频部分。我想将它的低频部分强度放大。则可以通过均衡器来调节低频区域的强度。 它的原理是将音频从时域进行FFT转换为频域,然后根据用户选择的中心频率,调节对应频率的强度,之后再进行FFT逆变换回时域信号。 压缩效果器,是指在时域上对声音强度所进行的一个处理。当音频的音量剧增的时候,会自动将音量调小一点。 实际生活中人听到的声音很多都是经过多次反射进入人耳的。你在一间教室,一个山谷、或者其他场所听到的声音都会有所不同。混响效果就是模拟这种环境。 编写sh脚本 #!/bin/bash CWD=`pwd` LOCAL=$CWD ./configure \ --prefix="$LOCAL/pc_lib" \ --enable-static \ --disable-shared \ --disable-openmp \ --without-libltdl \ --without-coreaudio 运行shell脚本构建及安装 make && make install 使用sox 构建完成之后可以在pc_lib目下下找到可执行文件sox. 如执行均衡器: sox audio.wav audio_output.wav equalizer 100.1 1.5q 3 equalizer 120 2.0q -19上面的命令可以将audio.wav以100.1 位中心频率,宽为1.5q,强度提升3. 以及 120为中心频率宽度为 2.0q,强度降低19. 宽度为 ${x}q 表示的频宽。根据q可以计算出一个O(八度),一个O体现在频率上是2倍的频率。比如一个音调比另一个音调高一个八度,在频率上就是这个音调是另一个音调的2倍。 android上使用sox。 交叉编译配置文件 #!/bin/bash CWD=`pwd` LOCAL=$CWD NDK=~/Library/Android/sdk/ndk/22.1.7171670 NDK_SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64 export TARGET=armv7a-linux-androideabi # Set this to your minSdkVersion. export API=28 # Configure and build. export AR=$TOOLCHAIN/bin/llvm-ar export CC=$TOOLCHAIN/bin/$TARGET$API-clang export AS=$CC export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++ export LD=$TOOLCHAIN/bin/ld export RANLIB=$TOOLCHAIN/bin/llvm-ranlib export STRIP=$TOOLCHAIN/bin/llvm-strip ./configure \ --prefix="$LOCAL/android_lib" \ --host $TARGET \ --with-pic \ --disable-openmp \ --without-libltdl make cmake 配置 cmake_minimum_required(VERSION 3.18) project(audioeffect) set(CMAKE_CXX_STANDARD 11) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_VERBOSE_MAKEFILE ON) set(PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../../../prebuilt/armv7a) message(STATUS "include ${PREBUILT_DIR}/include") file(GLOB SOURCES "*.cpp" "*.h" ) add_library(audioeffect SHARED ${SOURCES} ) add_library(sox STATIC IMPORTED GLOBAL) set_target_properties(sox PROPERTIES IMPORTED_LOCATION ${PREBUILT_DIR}/lib/libsox.a) set_target_properties(sox PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${PREBUILT_DIR}/include) target_link_libraries(audioeffect PRIVATE log PRIVATE sox) 实现一个均衡器 #include "Equalizer.h" #include "logger.h" #include #include void Equalizer::setInput(string input) { logi("%s,%s", "setInput", input.c_str()); input_ = std::move(input); } void Equalizer::setOutput(string output) { logi("%s,%s", "setOutput", output.c_str()); output_ = std::move(output); } void Equalizer::start() { assert(sox_init() == SOX_SUCCESS); in_ = sox_open_read(input_.c_str(), nullptr, nullptr, nullptr); out_ = sox_open_write(output_.c_str(), &in_->signal, nullptr, nullptr, nullptr, nullptr); chain_ = sox_create_effects_chain(&in_->encoding, &out_->encoding); // 输入 sox_effect_t *e = sox_create_effect(sox_find_effect("input")); char *args[10]; args[0] = (char *) in_; logi("in paths is %s:", args[0]); int result = sox_effect_options(e, 1, args); logi("effect input result is %d", result); assert(result == SOX_SUCCESS); sox_add_effect(chain_, e, &in_->signal, &in_->signal); free(e); // 均衡器 e = sox_create_effect(sox_find_effect("equalizer")); char *frequency = "300"; char *bandwidth = "1.25q"; char *gain = "3"; char *equalizer_chars[] = {frequency, bandwidth, gain}; result = sox_effect_options(e, 3, equalizer_chars); if (result != SOX_SUCCESS) { logi("option equalizer failed : error code is %d", result); assert(result == SOX_SUCCESS); } sox_add_effect(chain_, e, &in_->signal, &out_->signal); free(e); e = sox_create_effect(sox_find_effect("equalizer")); frequency = "300"; bandwidth = "1.25q"; gain = "30"; equalizer_chars[0] = frequency; equalizer_chars[1] = bandwidth; equalizer_chars[2] = gain; result = sox_effect_options(e, 3, equalizer_chars); if (result != SOX_SUCCESS) { logi("option equalizer failed : error code is %d", result); assert(result == SOX_SUCCESS); } sox_add_effect(chain_, e, &in_->signal, &out_->signal); free(e); // 输出 e = sox_create_effect(sox_find_effect("output")); args[0] = (char *) out_; result = sox_effect_options(e, 1, args); if (result != SOX_SUCCESS) { logi("option output effect failed : error code is %d", result); assert(result == SOX_SUCCESS); } sox_add_effect(chain_, e, &out_->signal, &out_->signal); free(e); sox_flow_effects(chain_, nullptr, nullptr); sox_delete_effects_chain(chain_); sox_close(out_); sox_close(in_); sox_quit(); }sox的设计是一个责任链。使用时,先创建出一个chain,然后创建出需要的effect添加到chain中。上述的例子中为模式为: input ----> equalizer1 -------> equalizer2 ----------> output最终可以对比处理过后的音频和原音频的差异。 我这个例子中原音频的频谱为: 改法: #elif defined _MSC_VER || defined _WIN32 || defined _WIN64 || \ defined _ISO_STDIO_ISO_H || defined __sgi fp->_ptr = fp->_base; #else /* To fix this #error, either simply remove the #error line and live without * file-type detection with pipes, or add support for your compiler in the * lines above. Test with cat monkey.wav | ./sox --info - */ // #error FIX NEEDED HERE #define NO_REWIND_PIPE (void)fp; #endif 找不到glob、globfree符号。这2个文件是在api28之后引入的,所有需要讲android api 调整为28及以上 copying selected object files to avoid basename conflicts... CCLD sox ld: error: undefined symbol: glob >>> referenced by sox.c:2606 >>> sox.o:(main) ld: error: undefined symbol: globfree >>> referenced by sox.c:2612 >>> sox.o:(main) clang: error: linker command failed with exit code 1 (use -v to see invocation) make[1]: *** [sox] Error 1 make: *** [all-recursive] Error 1 参考https://zhuanlan.zhihu.com/p/19763358 http://sox.sourceforge.net/ https://github.com/paramsen/noise https://howtoeq.wordpress.com/2010/10/07/q-factor-and-bandwidth-in-eq-what-it-all-means/ https://developer.android.com/ndk/guides/other_build_systems |
CopyRight 2018-2019 实验室设备网 版权所有 |