2017-12-28 56 views
1

wavファイルのFFTに続いてハミングを実行しようとしています。私はPythonで同じことを実装しました。 Javaでこれを行う方法。私はbytearrayOutputStreamを返す与えられたwaveファイルにハミングを適用しました。ここで、このbyteArrayOutputStreamに対してFFTを実行する方法は? 私はオーディオ処理が初めてです。私の現在のコードは次のとおりです。ハミングとそれに続くJavaのwavファイルのFFT

import java.io.BufferedInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.util.Arrays; 


import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.TargetDataLine; 
import javax.sound.sampled.UnsupportedAudioFileException; 

public class AudioFFT { 

    public static void main(String[] args) throws UnsupportedAudioFileException, IOException { 


     String wavFilePath="C:\\abc.wav"; 
     ByteArrayOutputStream byteArrayOutputStream=applyHamming(wavFilePath); 
     byte[] bytesOut=byteArrayOutputStream.toByteArray(); 
     System.out.println(Arrays.toString(bytesOut)); 
    } 

    public static ByteArrayOutputStream applyHamming(String filePath) 

    { 
     // TODO Auto-generated method stub 

     ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); 
     File fileIn = new File(filePath); 
     AudioInputStream audioInputStream; 
     try { 
      audioInputStream = AudioSystem.getAudioInputStream(fileIn); 
      int bytesPerFrame = audioInputStream.getFormat().getFrameSize(); 
      if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) { 
       bytesPerFrame = 1; 
      } 
      int numBytes = 1024 * bytesPerFrame; 
      byte[] audioBytes = new byte[numBytes]; 
      int numBytesRead = 0; 

      while ((numBytesRead = audioInputStream.read(audioBytes, 0, audioBytes.length)) != -1) { 

       outputStream.write(audioBytes, 0, numBytesRead); 
      } 

     } catch (UnsupportedAudioFileException | IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     return outputStream; 
    } 


    private static int BITS_IN_BYTE = 8; 

    private static AudioInputStream audioInputStream; 
    private static AudioFormat format; 
    final static int W = 1024; 

    public static void getFFT() { 
     String wavFilePath="C:\\abc.wav";; 
     File AudioFile = new File(wavFilePath); 

     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     BufferedInputStream in; 

     try { 
      audioInputStream = AudioSystem.getAudioInputStream(AudioFile); 
     } catch (UnsupportedAudioFileException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     format = audioInputStream.getFormat(); 
     DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); 

     if (!AudioSystem.isLineSupported(info)) { 
      System.out.println("Error"); 
     } 

     TargetDataLine line = null; 
     try { 

      line = (TargetDataLine) AudioSystem.getLine(info); 
      line.open(format); 

     } catch (LineUnavailableException ex) { 
      System.out.println("Error"); 
     } 

     line.start(); 
     byte[] data = new byte[W * format.getSampleSizeInBits()/BITS_IN_BYTE]; 
     double[] inbuf = new double[W]; 
     double[] fftbuf = new double[W]; 

     try { 
      in = new BufferedInputStream(new FileInputStream(AudioFile)); 
      int read; 
      while ((read = in.read(data)) > 0) { 
       out.write(data, 0, read); 
      } 
      out.flush(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     data = out.toByteArray(); 

     decode(data, inbuf); 

     fft(inbuf, fftbuf); 

    } 

    public static void decode(byte[] input, double[] output) { 
     assert input.length == 2 * output.length; 
     for (int i = 0; i < output.length; i++) { 
      output[i] = (short) (((0xFF & input[2 * i + 1]) << 8) | (0xFF & input[2 * i])); 
      output[i] /= Short.MAX_VALUE; 
     } 
    } 

    public static void fft(final double[] inputReal, double[] inputImag) { 
     assert inputReal.length == 2 * inputImag.length; 
     int n = inputReal.length; 
     double ld = Math.log(n)/Math.log(2.0); 

     if (((int) ld) - ld != 0) { 
      System.out.println("The number of elements is not a power of 2."); 
     } 
     int nu = (int) ld; 
     int n2 = n/2; 
     int nu1 = nu - 1; 
     double[] xReal = new double[n]; 
     double[] xImag = new double[n]; 
     double tReal, tImag, p, arg, c, s; 

     double constant; 
     if (true){ 
      constant = -2 * Math.PI; 
     } 

     for (int i = 0; i < n; i++) { 
      xReal[i] = inputReal[i]; 
      xImag[i] = inputImag[i]; 
     } 

     int k = 0; 
     for (int l = 1; l <= nu; l++) { 
      while (k < n) { 
       for (int i = 1; i <= n2; i++) { 
        p = bitreverseReference(k >> nu1, nu); 
        arg = constant * p/n; 
        c = Math.cos(arg); 
        s = Math.sin(arg); 
        tReal = xReal[k + n2] * c + xImag[k + n2] * s; 
        tImag = xImag[k + n2] * c - xReal[k + n2] * s; 
        xReal[k + n2] = xReal[k] - tReal; 
        xImag[k + n2] = xImag[k] - tImag; 
        xReal[k] += tReal; 
        xImag[k] += tImag; 
        k++; 
       } 
       k += n2; 
      } 
      k = 0; 
      nu1--; 
      n2 /= 2; 
     } 

     k = 0; 
     int r; 
     while (k < n) { 
      r = bitreverseReference(k, nu); 
      if (r > k) { 
       tReal = xReal[k]; 
       tImag = xImag[k]; 
       xReal[k] = xReal[r]; 
       xImag[k] = xImag[r]; 
       xReal[r] = tReal; 
       xImag[r] = tImag; 
      } 
      k++; 
     } 

     double[] newArray = new double[xReal.length * 2]; 
     double radice = 1/Math.sqrt(n); 
     for (int i = 0; i < newArray.length; i += 2) { 
      int i2 = i/2; 
      newArray[i] = xReal[i2] * radice; 
      newArray[i + 1] = xImag[i2] * radice; 
     } 

     for (int i = 0; i < newArray.length; i++) { 
      System.out.println("Array: " + newArray[i]); 
     } 

    } 

    private static int bitreverseReference(int j, int nu) { 
     int j2; 
     int j1 = j; 
     int k = 0; 
     for (int i = 1; i <= nu; i++) { 
      j2 = j1/2; 
      k = 2 * k + j1 - 2 * j2; 
      j1 = j2; 
     } 
     return k; 
    } 
} 

答えて

0

bytesOutHamming window関数によって変更された後に)あなたのwavファイルのデータが含まれています。これらのデータ は、fftメソッド(inputReal)に送信するreal partを表します。あなたが持っている今

double[] imgBytesOut = new double[1024]; //imgBytesOut is not a good name for this 
for(int i=0; i<1024;i++) 
    imgBytesOut[i] = 0; 

(私は長さが1024を想定)、虚部について、 inputRealと同じサイズの配列を作成し、虚部の配列を作成

//ゼロでそれを埋めますあなたはあなたのFFT法が​​とxImg配列を移入ができますが、ローカルに宣言しているので、あなたがすることができ できません

fft(bytesOut, imgBytesOut); 

FFTを呼び出すために必要なすべてfftがfinsihed(静的なグローバル変数として宣言)した後でそれらを使用してください。あなたのファイルは、たとえば、10000個のサンプルが含まれており、fft sizeが長い1024個のサンプルである場合

また、あなたはファイル全体を処理するために繰り返しfftを呼び出す必要があります (outBytesimgBytesOutは1024個のサンプルの長さです)。最高の結果を得るには、overlappingを適用する必要があります(例:50%オーバーラップと1024のFFTサイズの場合は、1-1024、次に512-15361024-2048などのサンプルを処理します)。

関連する問題