获取音频文件的频率,每1/4秒的android [英] Get the frequency of an audio file in every 1/4 seconds in android

查看:1168
本文介绍了获取音频文件的频率,每1/4秒的android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个声音文件(名为.3gp)及其有关〜1分钟。我想获得这个声音文件的频率,每1/4秒。我的想法是从音频文件接收样品中每1/4秒和用FFT我可能得到的频率值。有没有办法做到这一点?

I have a sound file (.3gp) and its about ~1 min. I would like to get the frequency of this sound file in every 1/4 seconds. My idea is to receive samples in every 1/4 seconds from the audio file and using FFT I might get the frequency values. Is there any way to do this?

其实我会分裂的声音文件转换成1/4秒的样本声音文件(alwyas覆盖preveious一个),然后使用FFT算法和检测频率,其中magintude是bigggest。但也有可能是更容易的解决方案,但是我没有一个线索如何可以做到这一点。

Actually I would split the sound file into 1/4sec samples sound files (alwyas overwriting the preveious one), then using FFT algorithm and detect the frequency where the magintude is the bigggest. But there might be easier solutions however I dont have a clue how to do this either.

***更新2 - 新的code

***UPDATE 2 - new code

我用这个code到目前为止:

I use this code so far:

公共类RecordAudio扩展的AsyncTask {

public class RecordAudio extends AsyncTask {

    @Override
    protected Void doInBackground(Void... arg0) {

        try {
             int bufferSize = AudioRecord.getMinBufferSize(frequency,
             AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);


            //int bufferSize = AudioRecord.getMinBufferSize(frequency, 
                  //  channelConfiguration, audioEncoding); 

            AudioRecord audioRecord = new AudioRecord( 
                    MediaRecorder.AudioSource.MIC, frequency, 
                    channelConfiguration, audioEncoding, bufferSize); 

            short[] buffer = new short[blockSize];
            //double[] toTransform = new double[blockSize];


            audioRecord.startRecording();


            // started = true; hopes this should true before calling
            // following while loop

            while (started) {
               sampling++;

               double[] re = new double[blockSize];
               double[] im = new double[blockSize];

               double[] newArray = new double[blockSize*2];
               double[] magns = new double[blockSize];

               double MaxMagn=0;
               double pitch = 0;

               int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);


               for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                   re[i] = (double) buffer[i] / 32768.0; // signed   16bit
                   im[i] = 0;
               }    

               newArray = FFTbase.fft(re, im,true);

               for (int i = 0; i < newArray.length; i+=2) {

                   re[i/2]=newArray[i];
                   im[i/2]=newArray[i+1];
                   magns[i/2] = Math.sqrt(re[i/2]*re[i/2]+im[i/2]*im[i/2]);
               }

//我只需要上半年

// I only need the first half

              for (int i = 0; i < (magns.length)/2; i++) {
                   if (magns[i]>MaxMagn)
                   {
                       MaxMagn = magns[i];
                       pitch=i;
                   }
               }                                           
                 if (sampling > 50) {
                   Log.i("pitch and magnitude", "" + MaxMagn + "   " + pitch*15.625f);
                   sampling=0;
                   MaxMagn=0;pitch=0;
                   }                   


            }

            audioRecord.stop();

        } catch (Throwable t) {
            t.printStackTrace();
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }

我用这个: http://www.wikijava.org/wiki/The_Fast_Fourier_Transform_in_Java_% 28part_1%29

吉他弦似乎正确的,但我自己的声音,因为这样并不好:

Guitar strings seem correct, but my own sound is not good because of this:

两峰的幅度改变大部分时间,我总能找到最大的,以获得基本频率。

The magnitude of the two peaks change most of the time and I always find the biggest to get the fundamental frequency.

推荐答案

间距跟踪与FFT人们常常要求对堆栈溢出,我写了的blog进入样品code 。在code是C,但与解释和链接,您应该可以做你想做的。

Pitch tracking with the FFT is asked so often on Stack Overflow I wrote a blog entry with sample code. The code is in C, but with the explanation and links you should be able to do what you want.

至于它划分成1/4秒为单位,你可以简单地利用,而不是默认的(我认为这是大约1秒)的1/4第二部分的FFT如你所说。如果这不会给你想要的频率分辨率,您可能需要使用不同的音高的识别方法。你可以做的另一件事是使用重叠的部分,比1/4秒的时间越长,但启动时间间隔是1/4秒分开。此方法提到的博客条目,但它可能无法满足您的设计规格。

As to dividing it up into 1/4 second increments, you could simply take FFTs of 1/4 second segments as you suggested, instead of the default (which I think is about 1 second). If this doesn't give you the frequency resolution you want, you may have to use a different pitch recognition method. Another thing you could do is use overlapping segments that are longer than 1/4 second, but start at intervals that are 1/4 second apart. This method is alluded to the blog entry, but it may not meet your design spec.

这篇关于获取音频文件的频率,每1/4秒的android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆