当前位置: 首页 > 面试题库 >

从音频文件计算FFT

轩辕亮
2023-03-14
问题内容

之前,我问过有关使用FFT和Complex
class获取频率wav音频的
问题,

在那里,我需要从AudioRecord输入->从麦克风计算FFT值,以某种方式设法获得FFT值…

现在,我需要从之前保存的* .wav音频文件中计算FFT值,然后将音频保存到项目中“ res”文件夹中的“ raw”文件夹中

我仍然使用相同的FFT类:http :
//www.cs.princeton.edu/introcs/97data/FFT.java

与之配套的复杂类:http
:
//introcs.cs.princeton.edu/java/97data/Complex.java.html

我使用这种方法从原始文件夹中读取音频文件,然后调用方法calculateFFT来处理它

private static final int RECORDER_BPP = 16;
  private static final int RECORDER_SAMPLERATE = 44100;
  private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
  private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;


private void asli(){

            int counter = 0;
            int data;
            InputStream inputStream  = getResources().openRawResource(R.raw.b1);
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            List<Integer> content = new ArrayList<Integer>();

            try {
                while ((data = dataInputStream.read()) != -1) {
                    content.add(data);
                    counter++; }
            } catch (IOException e) {
                e.printStackTrace();}

                int[] b = new int[content.size()];
                int cont = 0;
                byte[] audio = convertArray(b);
        }

转换为字节的方法

public byte[] convertArray(int[] array) {

            int minBufferSize = AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING,minBufferSize, AudioTrack.MODE_STREAM);

        byte[] newarray = new byte[array.length];
        for (int i = 0; i < array.length; i++) {
        newarray[i] = (byte) ((array[i]) & 0xFF);       }

            absNormalizedSignal = calculateFFT(newarray);
            return newarray;
        }

这是CalculateFFT方法

public double[] calculateFFT(byte[] signal)
        {           
            final int mNumberOfFFTPoints =1024;
            double mMaxFFTSample;
            double temp;
            Complex[] y;
            Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
            double[] absSignal = new double[mNumberOfFFTPoints/2];

            for(int i = 0; i < mNumberOfFFTPoints; i++){
                temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
                complexSignal[i] = new Complex(temp,0.0);
            }

            y = FFT.fft(complexSignal);

            mMaxFFTSample = 0.0;
            mPeakPos = 0;
            for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
            {
                 absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
                 if(absSignal[i] > mMaxFFTSample)
                 {
                     mMaxFFTSample = absSignal[i];
                     mPeakPos = i;
                 } 
            }

            return absSignal;

        }

我也使用了CalculateFFT方法来处理AudioRecorder的音频->以前是通过麦克风输入的…我设法从AudioRecorder取得了价值,但我无法从音频文件中获得价值…我没有计划播放音频..我只需要使用FFT处理它。

我的代码有什么问题吗?:o似乎我无法从方法Asli()获得价值;但是我不知道哪一部分错了。

任何帮助将不胜感激… :)谢谢


问题答案:

我花了大部分时间在上午,使用发现的FFT
Java代码片段为该代码编写解决方案…但是后来我偶然发现了这个极为出色的Google代码项目,该项目具有一堆用于执行信号处理任务的util类在WAV和MP3文件上都一样。

https://github.com/Uriopass/audio-
analysis
以前SVN导出是在以下Google代码上进行的:https :
//storage.googleapis.com/google-code-archive-source/v2/code.google.com/audio-
analysis / source-archive.zip

现在,它变得异常简单:

WaveDecoder decoder = new WaveDecoder(new FileInputStream(wavFile));
FFT fft = new FFT(1024, wavFileObj.getSampleRate());

现在,您可以使用fft对象进行各种计算。他们有很多很好的例子,例如生成包含光谱通量的列表:

    float[] samples = new float[1024];
    float[] spectrum = new float[1024 / 2 + 1];
    float[] lastSpectrum = new float[1024 / 2 + 1];
    List<Float> spectralFlux = new ArrayList<Float>();

    while (decoder.readSamples(samples) > 0) {
        fft.forward(samples);
        System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length);
        System.arraycopy(fft.getSpectrum(), 0, spectrum, 0, spectrum.length);

        float flux = 0;
        for (int i = 0; i < spectrum.length; i++)
            flux += (spectrum[i] - lastSpectrum[i]);
        spectralFlux.add(flux);
    }

我的公司需要我一种分析音频的方法,以查看是否发生了预期的保持音乐。因此,首先,我为一个具有保留音乐的示例生成了一个WAV文件。然后,我捕获了其中一个没有保留音乐的示例的一些音频。现在剩下的就是对wav的频谱通量求平均,我就开始了。

注意:我不能简单地获取幅度…但是傅立叶变换具有可以正确用于进行比较的频率。

我爱数学。



 类似资料:
  • 我的音乐应用程序从外部应用程序启动,使用意向数据作为音乐文件。 我有mp3音频URI,类似这样 file:///storage/emulated/0/Music/Tamil/I(2014)/Ennodu Nee Irundhaal。mp3 如何从媒体获取音频详细信息。标题,媒体。相册,媒体_身份证件

  • 我想在Discord语音频道中录制音频,并使用Discord机器人将其保存到文件中。 我收到音频每20毫秒作为pcm编码字节[],我想保存到一个文件。MP3是首选,但我没有其他文件格式的问题,如ogg(它可能更容易)。 我正在使用JDA版本我还包括lavaplayer版本用于其他功能。如果这些库是一个很好的库,这将是很有帮助的,但是如果我必须包含更多的库,这是没有问题的。

  • 我正在从两个不同的线程接收视频H264编码数据和音频G.711 PCM编码数据,以mux/写入多媒体容器。 writer函数签名如下所示: 提前感谢! 编辑:在我的视频流中,没有B帧。所以,我认为这里PTS和DTS可以保持不变。

  • 如果一些文件是带音频的视频,而一些文件只是音频,是否可以连接多个文件。最终结果应该如下所示: 我认为这一定是可能的,因为我也可以结合一个大的音频文件和一个小的视频与FFMPEG。结果将是一个视频文件,其中最后一帧只是冻结,但音频仍然播放。我想实现相同的结果,要么冻结最后一帧或简单的黑色帧。这可能吗?

  • 我正在尝试从视频文件中提取音频。我试过python中的moviepy、ffmpeg等库。提取的音频文件太大。对于大小为75 MB的音频文件,音频文件与moviepy的距离约为1.1 GB。即使比特率为16 kbps,采样率为16000 Hz,提取的文件大小也将达到200 MB。任何其他库或提取的音频文件大小至少相同或小于完整视频文件的方式。 我正在ffmpeg中使用上述命令。

  • 我正在尝试制作一个用于共享音频文件的按钮。这不起作用。首先,我试图直接从原始文件夹发送文件,而不将其复制到手机卡上。这并没有解决我的问题。我尝试的第二件事是将文件保存到手机上,然后共享。将文件保存到手机的部分现在可以工作了,但当我尝试将音频文件共享到其他设备时,所有兼容的应用程序(Whatsapp、Gmail等)都崩溃了。 这是我的代码: 顺便说一下,音频文件是一个。ogg文件。我希望这些应用程序