Holen Frequenz wav-audio mit FFT und Komplexe Klasse

Es wurde eine Menge gefragt, aber ich immer noch nicht über die Umsetzung der FFT-Klasse auf Android
Ich brauche um meine audio-Daten, die mit FFT...

Ich schon gelesen die fast gleiche Frage hier Wie kann ich die Frequenz die Daten von PCM unter Verwendung von FFT
und hier Wie man die Frequenz von der fft-Ergebnis?
und noch mehr Fragen, aber finde immer noch keine Antwort, auch nachdem ich versuchte die gegebenen Antworten...

FFT-Klasse, die ich verwende:
http://www.cs.princeton.edu/introcs/97data/FFT.java

Der komplexen Klasse mit ihm zu gehen: http://introcs.cs.princeton.edu/java/97data/Complex.java.html

Hier ist mein code

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;

public class Latihan extends Activity{
        private static final int RECORDER_BPP = 16;
        private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
        private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
        private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
        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;
        short[] audioData;

        private AudioRecord recorder = null;
        private int bufferSize = 0;
        private Thread recordingThread = null;
        private boolean isRecording = false;
        Complex[] fftTempArray;
        Complex[] fftArray;
        int[] bufferData;
        int bytesRecorded;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.p1);

        setButtonHandlers();
        enableButtons(false);

        bufferSize = AudioRecord.getMinBufferSize
                (RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING)*3;

        audioData = new short [bufferSize]; //short array that pcm data is put into.

        }


    private void setButtonHandlers() {
        ((Button)findViewById(R.id.btStart)).setOnClickListener(btnClick);
        ((Button)findViewById(R.id.btStop)).setOnClickListener(btnClick);
        }


        private void enableButton(int id,boolean isEnable){
                ((Button)findViewById(id)).setEnabled(isEnable);
        }

        private void enableButtons(boolean isRecording) {
                enableButton(R.id.btStart,!isRecording);
                enableButton(R.id.btStop,isRecording);
        }

        private String getFilename(){
                String filepath = Environment.getExternalStorageDirectory().getPath();
                File file = new File(filepath,AUDIO_RECORDER_FOLDER);

                if(!file.exists()){
                        file.mkdirs();
                }

                return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
        }


        public void convert(){



        }

        public void calculate(){
            Complex[] fftTempArray = new Complex[bufferSize];
            for (int i=0; i<bufferSize; i++)
            {
                fftTempArray[i] = new Complex(audioData[i], 0);
            }
            Complex[] fftArray = FFT.fft(fftTempArray);

            double[] micBufferData = new double[bufferSize];
            final int bytesPerSample = 2; 
            final double amplification = 100.0; 
            for (int index = 0, floatIndex = 0; index < bytesRecorded - bytesPerSample + 1; index += bytesPerSample, floatIndex++) {
                double sample = 0;
                for (int b = 0; b < bytesPerSample; b++) {
                    int v = bufferData[index + b];
                    if (b < bytesPerSample - 1 || bytesPerSample == 1) {
                        v &= 0xFF;
                    }
                    sample += v << (b * 8);
                }
                double sample32 = amplification * (sample / 32768.0);
                micBufferData[floatIndex] = sample32;
            }


     }


        private String getTempFilename(){
                String filepath = Environment.getExternalStorageDirectory().getPath();
                File file = new File(filepath,AUDIO_RECORDER_FOLDER);

                if(!file.exists()){
                        file.mkdirs();
                }

                File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);

                if(tempFile.exists())
                        tempFile.delete();

                return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
        }

        private void startRecording(){
            recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                                RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);

                recorder.startRecording();

                isRecording = true;

                recordingThread = new Thread(new Runnable() {

                        public void run() {
                                writeAudioDataToFile();
                        }
                },"AudioRecorder Thread");

                recordingThread.start();
        }

        private void writeAudioDataToFile(){
                byte data[] = new byte[bufferSize];
                String filename = getTempFilename();
                FileOutputStream os = null;

                try {
                        os = new FileOutputStream(filename);
                } catch (FileNotFoundException e) {
                        //TODO Auto-generated catch block
                        e.printStackTrace();
                }

                int read = 0;

                if(null != os){
                        while(isRecording){
                                read = recorder.read(data, 0, bufferSize);

                                if(AudioRecord.ERROR_INVALID_OPERATION != read){
                                        try {
                                                os.write(data);
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }

                        try {
                                os.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }

        private void stopRecording(){
                if(null != recorder){
                        isRecording = false;

                        recorder.stop();
                        recorder.release();

                        recorder = null;
                        recordingThread = null;
                }

                copyWaveFile(getTempFilename(),getFilename());
               //deleteTempFile();
        }

        private void deleteTempFile() {
                File file = new File(getTempFilename());
                file.delete();
        }

        private void copyWaveFile(String inFilename,String outFilename){
                FileInputStream in = null;
                FileOutputStream out = null;
                long totalAudioLen = 0;
                long totalDataLen = totalAudioLen + 36;
                long longSampleRate = RECORDER_SAMPLERATE;
                int channels = 2;
                long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;

                byte[] data = new byte[bufferSize];

                try {
                        in = new FileInputStream(inFilename);
                        out = new FileOutputStream(outFilename);
                        totalAudioLen = in.getChannel().size();
                        totalDataLen = totalAudioLen + 36;

                        AppLog.logString("File size: " + totalDataLen);

                        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                                        longSampleRate, channels, byteRate);

                        while(in.read(data) != -1){
                                out.write(data);
                        }

                        in.close();
                        out.close();
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

        private void WriteWaveFileHeader(
                        FileOutputStream out, long totalAudioLen,
                        long totalDataLen, long longSampleRate, int channels,
                        long byteRate) throws IOException {
            //another code    

        }

        private View.OnClickListener btnClick = new View.OnClickListener() {
                public void onClick(View v) {
                     switch(v.getId()){
                              case R.id.btStart:{
                                        AppLog.logString("Start Recording");
                                        enableButtons(true);
                                        startRecording();
                                        break;
                                }
                                case R.id.btStop:{
                                    AppLog.logString("Stop Recording");
                                        enableButtons(false);
                                        stopRecording();
                                        calculate();
                                        break;

                                }
                        }
                }
        }; 
}

Ich nehme an, das von Audiodateien array enthält die rohen audio-Daten,aber mein code exception fangen und return "N ist keine Potenz von 2"

Ist es etwas falsch mit meinem code ??
Wie gebe ich es zu FFT.java Klasse und Holen Sie sich die fftResult ??

Oder gibt es einen anderen Weg, um zu konvertieren time-domain-Daten zu Häufigkeit, Daten, einfacher ?

Es ist schon ein paar Monate her, seit ich stecken mit diesem... Mein Projekt ist zu vergleichen 2 audio *.wav-Dateien,
Jede Hilfe würde geschätzt... 🙂

Für diejenigen von Ihnen mit einer ähnlichen Fehlermeldung aus: "N ist keine Potenz von 2", so heißt die FFT-Algorithmus, die Sie verwenden, erwartet ein array mit einer Größe von 2^n, wobei 'n' ist eine ganze Zahl größer als 0 ist. Der FFT-Algorithmus arbeitet effizient auf algorithmen, die diese Größen, indem Sie mit dem Cooley-Tukey-FFT-Transformation, die arbeitet mit 2 radices. Eine Lösung ist die Suche nach einem FFT-Algorithmus die enthält auch die Bluestein-Transformation, die verwendet werden können, für arrays von beliebigen Längen. Eine solche FFT, ist hier zu finden : nayuki.io/Seite/free-small-fft-in-mehrere-Sprachen.

InformationsquelleAutor raisa_ | 2013-07-02

Schreibe einen Kommentar