如何在 Java 中实现音高效果? (FFT、IFFT、幅度、相位)

     2023-02-25     86

关键词:

【中文标题】如何在 Java 中实现音高效果? (FFT、IFFT、幅度、相位)【英文标题】:How to implement a Pitch Effect in Java? (FFT, IFFT, Amplitude, Phase) 【发布时间】:2016-08-04 08:30:57 【问题描述】:

我使用 apache commons 数学库来转换我的音频样本缓冲区上的 FFt 和 IFFT。 FFT 的输出给了我一个复数数组。频率反映在中间。使用 4096 个样本的样本缓冲区大小,我得到 2048 个有用的复数。

我在 Java 中有两个实现,一个在 IFFT 之前遍历最终数组,并计算应该从中获取复数的位置的插值。所以基本上我所做的是在另一个频率范围内扭曲复数。

FastFourierTransformer fft = new FastFourierTransformer(DftNormalization.STANDARD);
Complex[] freq, inverse, freqn;

for(int c = 0; c < in.length; c++)

    freq = fft.transform(in[c], TransformType.FORWARD);
    freqn = new Complex[freq.length];

    freqn[0] = Complex.valueOf(freq[0].getReal(), freq[0].getImaginary());

    for (int i = 1; i <= freq.length/2; i++) 

        double fOrig = i / factor + shift;

        int left = (int) Math.floor(fOrig);
        int right = (int) Math.ceil(fOrig);
        double weighting = fOrig - left;

        double new_Re = 0, new_Im = 0;

        if(left > 0 && left < freq.length / 2 && right > 0 && right < freq.length / 2)
            new_Re = interpolate(freq[left].getReal(), freq[right].getReal(), weighting);
            new_Im = interpolate(freq[left].getImaginary(), freq[right].getImaginary(), weighting);
        
        freqn[i] = Complex.valueOf(new_Re, new_Im);
        freqn[freq.length-i] = Complex.valueOf(new_Re, new_Im);
    
    inverse = fft.transform(freqn, TransformType.INVERSE);

    for(int i = 0; i < inverse.length; i++)
        in[c][i] = inverse[i].getReal();
    

由于输入音频信号的采样率,我会从一个音高频率中获得多个音高频率,因此此实现主要在高音区域中产生具有副作用的声音。我的其他实现计算传入复数的幅度和相位。然后它仅将幅度标度扭曲到新位置,然后在原始相位值和新幅度值的帮助下计算新复数。在矩形到极坐标和矩形之间转换时,我失去了我的标志。因为我只改变了复数向量的长度,所以我可以在输出复数上强制输入符号。

FastFourierTransformer fft = new FastFourierTransformer(DftNormalization.STANDARD);
Complex[] freq, inverse;

for(int c = 0; c < in.length; c++)

    freq = fft.transform(in[c], TransformType.FORWARD);

    double[] ampl = new double[freq.length];
    double[] angl = new double[freq.length];

    double re, im;

    boolean[] unitRe = new boolean[freq.length];
    boolean[] unitIm = new boolean[freq.length];

    double fctr = factor;

    for(int f = 0; f < freq.length; f++)
        re = freq[f].getReal();
        im = freq[f].getImaginary();
        unitRe[f] = re >= 0;
        unitIm[f] = im >= 0;

        ampl[f] = op.magn(re, im);
        angl[f] = op.agl(re, im);
    

    for(int f = 0; f < freq.length; f++)
        int val = f < freq.length / 2 ? f : freq.length / 2 - (f - freq.length / 2);
        double weighting = ((double)val / fctr + shift) % 1;

        int left = (int) Math.floor(val / fctr + shift);
        int right = (int) Math.ceil(val / fctr + shift);
        double new_ampl = 0;

        if(left >= 0 && left < freq.length / 2 && right >= 0 && right < freq.length / 2)
            new_ampl = interpolate(ampl[left], ampl[right], weighting);
        

        re = op.real(new_ampl, angl[f]);
        im = op.imag(new_ampl, angl[f]);

        re = unitRe[f] ? Math.abs(re) : Math.abs(re) * -1;
        im = unitIm[f] ? Math.abs(im) : Math.abs(im) * -1;

        freq[f] = Complex.valueOf(re, im);
    

    inverse = fft.transform(freq, TransformType.INVERSE);

    for(int i = 0; i < inverse.length; i++)
        in[c][i] = inverse[i].getReal();
    

第二个实现听起来比第一个好得多。它实际上甚至比我使用的大多数 Dj 应用程序听起来更好,但我不知道为什么?难道我做错了什么?我在 Java 中找不到任何其他实现可以比较。他们通常只是用幅度和相位在一个新的尺度上扭曲整个频率尺度,还是他们只是把幅度强加到另一个尺度的原始相位上?

【问题讨论】:

nitpick:“我失去了我的迹象” - 你想要的单词拼写为“失去”。 “松”是“紧”的反义词。 @davmac 好的,谢谢,我刚刚改了!对不起我的英语不好。 【参考方案1】:

您的第二种算法类似于时间音高修改的相位声码器方法。据报道,许多音频处理库使用相位声码器技术的变体,但通常只有在有足够的处理能力可用的情况下。

【讨论】:

如何在颤动中实现这种效果/布局?

】如何在颤动中实现这种效果/布局?【英文标题】:Howtoachievethiseffect/layoutinflutter?【发布时间】:2021-10-0520:29:18【问题描述】:我发现,这种搜索效果是内置在ios框架中的。但是这种布局如何在Flutter中实现呢?【问题讨论】:... 查看详情

如何在android中实现这种折叠效果?

】如何在android中实现这种折叠效果?【英文标题】:Howtoachievethisfoldingeffectinandroid?【发布时间】:2012-09-1212:24:41【问题描述】:这是在ios上的效果像纸折叠的效果适用于iOS的PaperFold:https://github.com/honcheng/PaperFold-for-iOS【问题讨... 查看详情

如何在 Flutter 中实现“磨砂玻璃”效果?

】如何在Flutter中实现“磨砂玻璃”效果?【英文标题】:HowdoIdothe"frostedglass"effectinFlutter?【发布时间】:2017-09-1822:29:18【问题描述】:我正在编写一个Flutter应用程序,我想使用/实现iOS上常见的“磨砂玻璃”效果。我该怎... 查看详情

如何在unity中实现拖尾效果

...会添加拖尾或者鼠标点击的特效,接下来就说说在unity中如何实现拖尾效果,首先unity中有个组件,叫TrailRenderer,在Component——>Effect——>TrailRenderer中添加,根据自己需要的效果设置自己需要的颜色,然后还有相... 查看详情

如何在 UITable 中实现 Instagram 评论的效果?

】如何在UITable中实现Instagram评论的效果?【英文标题】:howcaniaccomplishtheeffectofinstagramcommentsinaUITable?【发布时间】:2013-12-0523:57:06【问题描述】:当我们在cmets中滚动时,我想完成instagram的效果,它像这样隐藏键盘:我知道它不... 查看详情

如何在 MATLAB 中实现鱼眼镜头效果(桶形变换)?

】如何在MATLAB中实现鱼眼镜头效果(桶形变换)?【英文标题】:HowcanIimplementafisheyelenseffect(barreltransformation)inMATLAB?【发布时间】:2010-04-0703:37:57【问题描述】:如何实现该图像中所示的鱼眼镜头效果:大家可以试试谷歌的logo:... 查看详情

如何在导航栏菜单中实现平滑的向下滑动效果

】如何在导航栏菜单中实现平滑的向下滑动效果【英文标题】:HowtoachievesmootheslidedowneffectinNavbarMenu【发布时间】:2018-03-2404:43:24【问题描述】:目标-我想在一些滚动后实现向下滑动(用于导航栏)效果。我实际上实现了我想要... 查看详情

你如何在 iOS 中实现“时钟擦除”/径向擦除效果?

】你如何在iOS中实现“时钟擦除”/径向擦除效果?【英文标题】:Howdoyouachievea"clockwipe"/radialwipeeffectiniOS?【发布时间】:2014-03-1415:24:29【问题描述】:有时您会看到正在使用的“时钟擦除”动画。像这样的:你将如何在iO... 查看详情

如何在android中实现图像视图的缩放效果?

】如何在android中实现图像视图的缩放效果?【英文标题】:Howtoimplementzoomeffectforimageviewinandroid?【发布时间】:2012-01-1400:26:57【问题描述】:我必须实现图像缩放,我尝试了很多代码。但我没有完全了解手势事件。我想在我们应... 查看详情

WinUI3如何在桌面应用中实现亚克力窗口效果?

】WinUI3如何在桌面应用中实现亚克力窗口效果?【英文标题】:HowtoimplementacrylicwindowseffectinWinUI3indesktopapplication?【发布时间】:2022-01-1020:39:39【问题描述】:在使用VS2022创建WinUI3(WindowsAppSDK1.0)项目时,我无法在Windows上实现亚克... 查看详情

如何在unity3d中实现战争迷雾效果

参考技术AiTweeniTween.CameraFadeToiTween.CameraFadeFrom,或者用深度摄像机,改切换画面color.a 查看详情

如何在html中实现图片的滚动效果

<MARQUEEonmouseover=stop()onmouseout=start()scrollAmount=3loop=infinitedeplay="0"><IMGsrc="第一张图片地址"><IMGsrc="第二张图片地址"></MARQUEE>注释:1)scrollAmount。它表示速度,值越大速度越快。2)加入onmouseover= 查看详情

如何在 UISlider 中实现 sender.selected if 语句?

】如何在UISlider中实现sender.selectedif语句?【英文标题】:Howtoimplementsender.selectedifstatementintoUISlider?【发布时间】:2016-06-2309:54:36【问题描述】:我正在尝试创建一个滑块,它可以根据滑块的值更改音频。因此,例如,如果滑块值... 查看详情

如何在 GameMaker:Studio 1 中实现 3D 低分辨率效果

】如何在GameMaker:Studio1中实现3D低分辨率效果【英文标题】:Howtoachieve3Dlow-reseffectinGameMaker:Studio1【发布时间】:2019-08-0107:09:15【问题描述】:我正在一个名为GameMaker:Studio1.99.44的流行游戏引擎中编写一个3DFPS类型的游戏。我正在尝... 查看详情

如何在 PIG Script 中实现 IF ELSE 控制逻辑

】如何在PIGScript中实现IFELSE控制逻辑【英文标题】:HowtoImplementIFELSEcontrollogicinPIGScript【发布时间】:2015-11-2419:37:43【问题描述】:我们需要根据条件执行脚本如果(真)//执行这条语句别的//执行这条语句我听说IFelse不存在,但... 查看详情

在 python 中实现 2D、基于 FFT 的核密度估计器,并将其与 SciPy 实现进行比较

】在python中实现2D、基于FFT的核密度估计器,并将其与SciPy实现进行比较【英文标题】:Implementinga2D,FFT-basedKernelDensityEstimatorinpython,andcomparingittotheSciPyimplimentation【发布时间】:2013-09-2602:47:25【问题描述】:我需要代码来执行2D核... 查看详情

如何在 Swift iOS 中实现 iMessage 渐变?

】如何在SwiftiOS中实现iMessage渐变?【英文标题】:HowcanIimplementtheiMessagegradientinSwiftiOS?【发布时间】:2020-12-2423:40:30【问题描述】:我正在努力实现的目标我正在尝试在SwiftiOS中实现渐变气泡效果,其中顶部的聊天气泡颜色较浅... 查看详情

如何在 MuPDF 中实现页面卷曲

】如何在MuPDF中实现页面卷曲【英文标题】:HowtoimplementPageCurlinMuPDF【发布时间】:2013-01-0410:14:40【问题描述】:我有两个库,一个是MuPDF,用于在android中查看PDF文件,第二个是pageCurl,用于实现页面卷曲效果,但它适用于位图。... 查看详情