2014-11-06 146 views
2
public class MainActivity 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; 

    private AudioRecord recorder = null; 
    private int bufferSize = 0; 
    private Thread recordingThread = null; 
    private boolean isRecording = false; 

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

    setButtonHandlers(); 
    enableButtons(false); 

    bufferSize = AudioRecord.getMinBufferSize(8000, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 

} 

    private void setButtonHandlers() { 
      ((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick); 
    ((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick); 
    } 

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

    private void enableButtons(boolean isRecording) { 
      enableButton(R.id.btnStart,!isRecording); 
      enableButton(R.id.btnStop,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); 
    } 

    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); 

      int i = recorder.getState(); 
      if(i==1) 
       recorder.startRecording(); 

      isRecording = true; 

      recordingThread = new Thread(new Runnable() { 

        @Override 
        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; 

        int i = recorder.getState(); 
        if(i==1) 
         recorder.stop(); 
        recorder.release(); 

        recorder = null; 
        recordingThread = null; 
      } 

      copyWaveFile(getTempFilename(),getFilename()); 
      compareTempFile(); 
    } 

    private void compareTempFile() { 
      File file = new File(getTempFilename()); 
      Wave w1 = new Wave(getResources().openRawResource(R.raw.selam)); 
      Wave w2 = new Wave(file.getPath()); 


      FingerprintSimilarity fps = w1.getFingerprintSimilarity(w2); 
      float score = fps.getScore(); 
      float sim = fps.getSimilarity(); 
      System.out.println(sim+" buldum"); 

    } 

    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 { 

      byte[] header = new byte[44]; 

      header[0] = 'R'; // RIFF/WAVE header 
      header[1] = 'I'; 
      header[2] = 'F'; 
      header[3] = 'F'; 
      header[4] = (byte) (totalDataLen & 0xff); 
      header[5] = (byte) ((totalDataLen >> 8) & 0xff); 
      header[6] = (byte) ((totalDataLen >> 16) & 0xff); 
      header[7] = (byte) ((totalDataLen >> 24) & 0xff); 
      header[8] = 'W'; 
      header[9] = 'A'; 
      header[10] = 'V'; 
      header[11] = 'E'; 
      header[12] = 'f'; // 'fmt ' chunk 
      header[13] = 'm'; 
      header[14] = 't'; 
      header[15] = ' '; 
      header[16] = 16; // 4 bytes: size of 'fmt ' chunk 
      header[17] = 0; 
      header[18] = 0; 
      header[19] = 0; 
      header[20] = 1; // format = 1 
      header[21] = 0; 
      header[22] = (byte) channels; 
      header[23] = 0; 
      header[24] = (byte) (longSampleRate & 0xff); 
      header[25] = (byte) ((longSampleRate >> 8) & 0xff); 
      header[26] = (byte) ((longSampleRate >> 16) & 0xff); 
      header[27] = (byte) ((longSampleRate >> 24) & 0xff); 
      header[28] = (byte) (byteRate & 0xff); 
      header[29] = (byte) ((byteRate >> 8) & 0xff); 
      header[30] = (byte) ((byteRate >> 16) & 0xff); 
      header[31] = (byte) ((byteRate >> 24) & 0xff); 
      header[32] = (byte) (2 * 16/8); // block align 
      header[33] = 0; 
      header[34] = RECORDER_BPP; // bits per sample 
      header[35] = 0; 
      header[36] = 'd'; 
      header[37] = 'a'; 
      header[38] = 't'; 
      header[39] = 'a'; 
      header[40] = (byte) (totalAudioLen & 0xff); 
      header[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
      header[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
      header[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

      out.write(header, 0, 44); 

    } 

    private View.OnClickListener btnClick = new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
        switch(v.getId()){ 
          case R.id.btnStart:{ 
            AppLog.logString("Start Recording"); 

            enableButtons(true); 
            startRecording(); 

            break; 
          } 
          case R.id.btnStop:{ 
            AppLog.logString("Start Recording"); 

            enableButtons(false); 
            stopRecording(); 

            break; 
          } 
        } 
      } 
    }; 
} 

我试图比较wav文件和实时编写的wav文件的相似度。但实时wav文件抛出异常。比较声音文件和实时语音与音乐g

compareTempFile()方法中的比较。

11-06 05:01:36.810: E/AndroidRuntime(28346): java.lang.NullPointerException 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.musicg.dsp.Resampler.reSample(Resampler.java:43) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.musicg.fingerprint.FingerprintManager.extractFingerprint(FingerprintManager.java:72) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.musicg.wave.Wave.getFingerprint(Wave.java:329) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.musicg.wave.Wave.getFingerprintSimilarity(Wave.java:335) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.example.deneme.MainActivity.compareTempFile(MainActivity.java:178) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.example.deneme.MainActivity.stopRecording(MainActivity.java:169) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.example.deneme.MainActivity.access$2(MainActivity.java:155) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.example.deneme.MainActivity$1.onClick(MainActivity.java:292) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.view.View.performClick(View.java:4470) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.view.View$PerformClick.run(View.java:18593) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.os.Handler.handleCallback(Handler.java:733) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.os.Handler.dispatchMessage(Handler.java:95) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.os.Looper.loop(Looper.java:157) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at android.app.ActivityThread.main(ActivityThread.java:5867) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at java.lang.reflect.Method.invokeNative(Native Method) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at java.lang.reflect.Method.invoke(Method.java:515) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674) 
11-06 05:01:36.810: E/AndroidRuntime(28346): at dalvik.system.NativeStart.main(Native Method) 

有没有人对上述错误有任何建议?

+0

请告诉我,如果你找到了解决办法,我有同样的问题 – 2018-02-24 14:35:13

回答

4

而不是比较与临时原始文件,比较您的原始声音资源与添加标题和复制数据后创建的.wav文件。因此,而不是使用compareTempFile()方法,使用方法类似如下:

function compareFile() { 
    File file = new File(getFilename()); 
    Wave w1 = new Wave(getResources().openRawResource(R.raw.selam)); 
    Wave w2 = new Wave(file.getPath()); 


    FingerprintSimilarity fps = w1.getFingerprintSimilarity(w2); 
    float score = fps.getScore(); 
    float sim = fps.getSimilarity(); 
    System.out.println(sim+" buldum"); 
} 

,是的!您用来存储录制声音的名称取决于当前时间,因此现在需要更改getFilename()现在从两个地方调用。完整的工作副本如下:

public class MainActivity 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; 
private double currentTime; 

private AudioRecord recorder = null; 
private int bufferSize = 0; 
private Thread recordingThread = null; 
private boolean isRecording = false; 

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

setButtonHandlers(); 
enableButtons(false); 

bufferSize = AudioRecord.getMinBufferSize(8000, 
     AudioFormat.CHANNEL_CONFIGURATION_MONO, 
     AudioFormat.ENCODING_PCM_16BIT); 

} 

private void setButtonHandlers() { 
     ((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick); 
((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick); 
} 

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

private void enableButtons(boolean isRecording) { 
     enableButton(R.id.btnStart,!isRecording); 
     enableButton(R.id.btnStop,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() + "/" + currentTime + AUDIO_RECORDER_FILE_EXT_WAV); 
} 

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); 

     int i = recorder.getState(); 
     if(i==1) 
      recorder.startRecording(); 

     isRecording = true; 

     recordingThread = new Thread(new Runnable() { 

       @Override 
       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; 

       int i = recorder.getState(); 
       if(i==1) 
        recorder.stop(); 
       recorder.release(); 

       recorder = null; 
       recordingThread = null; 
     } 

     copyWaveFile(getTempFilename(),getFilename()); 
     compareTempFile(); 
} 

private void compareTempFile() { 
     File file = new File(getTempFilename()); 
     Wave w1 = new Wave(getResources().openRawResource(R.raw.selam)); 
     Wave w2 = new Wave(file.getPath()); 


     FingerprintSimilarity fps = w1.getFingerprintSimilarity(w2); 
     float score = fps.getScore(); 
     float sim = fps.getSimilarity(); 
     System.out.println(sim+" buldum"); 

} 

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 { 

     byte[] header = new byte[44]; 

     header[0] = 'R'; // RIFF/WAVE header 
     header[1] = 'I'; 
     header[2] = 'F'; 
     header[3] = 'F'; 
     header[4] = (byte) (totalDataLen & 0xff); 
     header[5] = (byte) ((totalDataLen >> 8) & 0xff); 
     header[6] = (byte) ((totalDataLen >> 16) & 0xff); 
     header[7] = (byte) ((totalDataLen >> 24) & 0xff); 
     header[8] = 'W'; 
     header[9] = 'A'; 
     header[10] = 'V'; 
     header[11] = 'E'; 
     header[12] = 'f'; // 'fmt ' chunk 
     header[13] = 'm'; 
     header[14] = 't'; 
     header[15] = ' '; 
     header[16] = 16; // 4 bytes: size of 'fmt ' chunk 
     header[17] = 0; 
     header[18] = 0; 
     header[19] = 0; 
     header[20] = 1; // format = 1 
     header[21] = 0; 
     header[22] = (byte) channels; 
     header[23] = 0; 
     header[24] = (byte) (longSampleRate & 0xff); 
     header[25] = (byte) ((longSampleRate >> 8) & 0xff); 
     header[26] = (byte) ((longSampleRate >> 16) & 0xff); 
     header[27] = (byte) ((longSampleRate >> 24) & 0xff); 
     header[28] = (byte) (byteRate & 0xff); 
     header[29] = (byte) ((byteRate >> 8) & 0xff); 
     header[30] = (byte) ((byteRate >> 16) & 0xff); 
     header[31] = (byte) ((byteRate >> 24) & 0xff); 
     header[32] = (byte) (2 * 16/8); // block align 
     header[33] = 0; 
     header[34] = RECORDER_BPP; // bits per sample 
     header[35] = 0; 
     header[36] = 'd'; 
     header[37] = 'a'; 
     header[38] = 't'; 
     header[39] = 'a'; 
     header[40] = (byte) (totalAudioLen & 0xff); 
     header[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
     header[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
     header[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

     out.write(header, 0, 44); 

} 

private View.OnClickListener btnClick = new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       switch(v.getId()){ 
         case R.id.btnStart:{ 
           AppLog.logString("Start Recording"); 
           currentTime = System.currentTimeMillis(); 

           enableButtons(true); 
           startRecording(); 

           break; 
         } 
         case R.id.btnStop:{ 
           AppLog.logString("Start Recording"); 

           enableButtons(false); 
           stopRecording(); 

           break; 
         } 
       } 
     } 
    }; 
} 
+0

我们可以直接从MIC养活数据时

mucsicg库只是正常工作比较2的声音?像FingerprintSimilarity fps = w1.getFingerprintSimilarity(INPUT.FromMIC); – 2015-07-07 13:41:18

0

private static final int RECORDER_SAMPLERATE = 8000;使用采样速率为8000 Hz