2017-06-24 20 views
1

このコードは、オーディオをエミュレートされたストレージに保存されたwavファイルに記録します。どうすればこのwavファイルを取得し、生のオーディオデータの配列を取得できますか?androidのwavファイルから生データを読み取る

コードはそれが言うbuttonDecodeセクションに下がるでしょうに:wavファイルから //読み生データ

package com.example.wesle.noisemachine; 

import android.content.Intent; 
import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioRecord; 
import android.net.Uri; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.media.MediaPlayer; 
import android.media.MediaRecorder; 
import android.os.Environment; 
import android.widget.Toast; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.*; 

public class ReceiveScreen extends AppCompatActivity { 

    private Button buttonStart, buttonStop, buttonDecode, buttonPlay; 
    private String filePath; 

    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 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_receive_screen); 


     //final MediaPlayer wavRecording = MediaPlayer.create(this, "/storage/emulated/0"); 
     buttonStart = (Button) findViewById(R.id.buttonStart); 
     buttonStop = (Button) findViewById(R.id.buttonStop); 
     buttonPlay = (Button) findViewById(R.id.buttonPlay); 
     buttonDecode = (Button) findViewById(R.id.buttonDecode); 
     buttonStop.setEnabled(false); 
     buttonDecode.setEnabled(false); 
     buttonPlay.setEnabled(false); 
     //outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp"; 
     //System.out.println(outputFile); 

     bufferSize = AudioRecord.getMinBufferSize 
       (RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING)*3; 
     audioData = new short [bufferSize]; 


     buttonStart.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       buttonStart.setEnabled(false); 
       buttonDecode.setEnabled(false); 
       buttonPlay.setEnabled(false); 
       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(); 

       buttonStop.setEnabled(true); 

       Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show(); 

      } 
     }); 

     buttonStop.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       buttonStop.setEnabled(false); 
       if (null != recorder){ 
        isRecording = false; 

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

        recorder = null; 
        recordingThread = null; 
       } 
       filePath = getFilename(); 
       copyWaveFile(getTempFilename(),filePath); 
       deleteTempFile(); 

       Toast.makeText(getApplicationContext(), "Recording Completed", Toast.LENGTH_LONG).show(); 
       buttonStart.setEnabled(true); 
       buttonPlay.setEnabled(true); 
       buttonDecode.setEnabled(true); 
      } 
     }); 

     buttonPlay.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       buttonStart.setEnabled(false); 
       buttonDecode.setEnabled(false); 
       buttonPlay.setEnabled(false); 
       Toast.makeText(getApplicationContext(), "Recording Playing", Toast.LENGTH_LONG).show(); 

       //play code 
       File wavfile = new File(filePath); 
       Uri myUri1 = Uri.fromFile(wavfile); 
       final MediaPlayer mPlayer = new MediaPlayer(); 
       mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

       try { 
        mPlayer.setDataSource(getApplicationContext(), myUri1); 
       } catch (IllegalArgumentException e) { 
        Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); 
       } catch (SecurityException e) { 
        Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); 
       } catch (IllegalStateException e) { 
        Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       try { 
        mPlayer.prepare(); 
       } catch (IllegalStateException e) { 
        Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); 
       } catch (IOException e) { 
        Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show(); 
       } 

       mPlayer.start(); 

       buttonStart.setEnabled(true); 
       buttonDecode.setEnabled(true); 
       buttonPlay.setEnabled(true); 
      } 
     }); 

     buttonDecode.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       buttonStart.setEnabled(false); 
       buttonDecode.setEnabled(false); 
       buttonPlay.setEnabled(false); 

       //read raw data from wav file 

       buttonStart.setEnabled(true); 
       buttonDecode.setEnabled(true); 
       buttonPlay.setEnabled(true); 
      } 
     }); 

     //Code for the back button 
     Button backbuttonR = (Button) findViewById(R.id.backbuttonR); 
     backbuttonR.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       startActivity(new Intent(ReceiveScreen.this, MainActivity.class)); 
      } 
     }); 

    } 

    private String getFilename(){ 
     String filepath = Environment.getExternalStorageDirectory().getPath(); 
     File file = new File(filepath,AUDIO_RECORDER_FOLDER); 
     System.out.println(file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV); 
     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 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 (read > 0){ 
       } 

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

      System.out.println("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); 
    } 

    /*public class SoundPoolPlayer { 
     private SoundPool mShortPlayer= null; 
     private HashMap mSounds = new HashMap(); 

     public SoundPoolPlayer(Context pContext) 
     { 
      // setup Soundpool 
      this.mShortPlayer = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); 


      mSounds.put(R.raw.<sound_1_name>, this.mShortPlayer.load(pContext, R.raw.<sound_1_name>, 1)); 
      mSounds.put(R.raw.<sound_2_name>, this.mShortPlayer.load(pContext, R.raw.<sound_2_name>, 1)); 
     } 

     public void playShortResource(int piResource) { 
      int iSoundId = (Integer) mSounds.get(piResource); 
      this.mShortPlayer.play(iSoundId, 0.99f, 0.99f, 0, 0, 1); 
     } 

     // Cleanup 
     public void release() { 
      // Cleanup 
      this.mShortPlayer.release(); 
      this.mShortPlayer = null; 
     } 
    }*/ 

    public static final class Complex { 
     // The number stored is x+I*y. 
     final private double x, y; 
     // I don't want to allow anyone to access these numbers so I've labeled 
     // them private. 

     /** Construct a point from real and imaginary parts. */ 
     public Complex(double real_part, double imaginary_part) { 
      x=real_part; 
      y=imaginary_part; 
     } 

     /** Construct a real number. */ 
     public Complex(double real_part) { 
      x=real_part; 
      y=0; 
     } 

     // A static constructor. 

     /** Construct a complex number from the given polar coordinates. */ 
     public static Complex fromPolar(double r, double theta) { 
      return new Complex(r*Math.cos(theta), r*Math.sin(theta)); 
     } 

     // Basic operations on Complex numbers. 

     /** Return the real part. */ 
     public double re(){ 
      return x; 
     } 

     /** Return the imaginary part. */ 
     public double im(){ 
      return y; 
     } 

     /** Return the complex conjugate */ 
     public Complex conj() { 
      return new Complex(x,-y); 
     } 

     /** Return the square of the absolute value. */ 
     public double absSquared() { 
      return x*x+y*y; 
     } 

     /** Return the absolute value. */ 
     public double abs() { 
      // The java.lang.Math package contains many useful mathematical functions, 
      // including the square root function. 
      return Math.sqrt(absSquared()); 
     } 

     // ARITHMETIC 

     /** Add a complex number to this one. 
     * 
     * @param z The complex number to be added. 
     * @return A new complex number which is the sum. 
     */ 
     public Complex add(Complex z) { 
      return new Complex(x+z.x, y+z.y); 
     } 

     /** Subtract a complex number from this one. 
     * 
     * @param z The complex number to be subtracted. 
     * @return A new complex number which is the sum. 
     */ 
     public Complex minus(Complex z) { 
      return new Complex(x-z.x, y-z.y); 
     } 

     /** Negate this complex number. 
     * 
     * @return The negation. 
     */ 
     public Complex neg() { 
      return new Complex(-x, -y); 
     } 

     /** Compute the product of two complex numbers 
     * 
     * @param z The complex number to be multiplied. 
     * @return A new complex number which is the product. 
     */ 
     public Complex mult(Complex z) { 
      return new Complex(x*z.x-y*z.y, x*z.y+z.x*y); 
     } 

     /** Divide this complex number by a real number. 
     * 
     * @param q The number to divide by. 
     * @return A new complex number representing the quotient. 
     */ 
     public Complex div(double q) { 
      return new Complex(x/q,y/q); 
     } 

     /** Return the multiplicative inverse. */ 
     public Complex inv() { 
      // find the square of the absolute value of this complex number. 
      double abs_squared=absSquared(); 
      return new Complex(x/abs_squared, -y/abs_squared); 
     } 

     /** Compute the quotient of two complex numbers. 
     * 
     * @param z The complex number to divide this one by. 
     * @return A new complex number which is the quotient. 
     */ 
     public Complex div(Complex z) { 
      return mult(z.inv()); 
     } 

     /** Return the complex exponential of this complex number. */ 
     public Complex exp() { 
      return new Complex(Math.exp(x)*Math.cos(y),Math.exp(x)*Math.sin(y)); 
     } 


     // FUNCTIONS WHICH KEEP JAVA HAPPY: 

     /** Returns this point as a string. 
     * The main purpose of this function is for printing the string out, 
     * so we return a string in a (fairly) human readable format. 
     */ 
     // The _optional_ override directive "@Override" below just says we are 
     // overriding a function defined in a parent class. In this case, the 
     // parent is java.lang.Object. All classes in Java have the Object class 
     // as a superclass. 
     @Override 
     public String toString() { 
      // Comments: 
      // 1) "" represents the empty string. 
      // 2) If you add something to a string, it converts the thing you 
      // are adding to a string, and then concatentates it with the string. 

      // We do some voodoo to make sure the number is displayed reasonably. 
      if (y==0) { 
       return ""+x; 
      } 
      if (y>0) { 
       return ""+x+"+"+y+"*I"; 
      } 
      // otherwise y<0. 
      return ""+x+"-"+(-y)+"*I"; 
     } 

     /** Return true if the object is a complex number which is equal to this complex number. */ 
     @Override 
     public boolean equals(Object obj) { 
      // Return false if the object is null 
      if (obj == null) { 
       return false; 
      } 
      // Return false if the object is not a Complex number 
      if (!(obj instanceof Complex)) { 
       return false; 
      } 

      // Now the object must be a Complex number, so we can convert it to a 
      // Complex number. 
      Complex other = (Complex) obj; 

      // If the x-coordinates are not equal, then return false. 
      if (x != other.x) { 
       return false; 
      } 
      // If the y-coordinates are not equal, then return false. 
      if (y != other.y) { 
       return false; 
      } 
      // Both parts are equal, so return true. 
      return true; 
     } 

     // Remark: In Java, we should really override the hashcode function 
     // whenever we override the equals function. But, I don't want to 
     // get into this for a light introduction to programming in java. 
     // Hash codes are necessary for various of Java's collections. See HashSet for instance. 
     // The following was generated by Netbeans. 
     @Override 
     public int hashCode() { 
      int hash = 3; 
      hash = 83 * hash + (int) (Double.doubleToLongBits(this.x)^(Double.doubleToLongBits(this.x) >>> 32)); 
      hash = 83 * hash + (int) (Double.doubleToLongBits(this.y)^(Double.doubleToLongBits(this.y) >>> 32)); 
      return hash; 
     } 
    } 
} 

答えて

0

これは動作するはずです。 入力ストリームなどからバイトを連結するには、より良い方法があるかもしれませんが、改善するための実例です。それがうまくいくことを望みます。 MediaPlayerの代わりにAudioTrackを使用します。ホープこれはあなたのために動作します。

InputStream is = mContext.getResources().openRawResource(R.raw.bell); 
    byte []musicBytes=new byte[512]; 
    byte []fullMusicBytes=new byte[512]; 
    byte []tempMusicBytes=new byte[512]; 

    try { 
     while (is.available() > 0) { 
      is.read(musicBytes); 
      if(fullMusicBytes!=null) 
      { 
       tempMusicBytes = new byte[fullMusicBytes.length + musicBytes.length]; 
       System.arraycopy(fullMusicBytes, 0, tempMusicBytes, 0, fullMusicBytes.length); 
       System.arraycopy(musicBytes, 0, tempMusicBytes, fullMusicBytes.length, musicBytes.length); 
       fullMusicBytes=tempMusicBytes; 
      } 
      else 
      { 
       fullMusicBytes=musicBytes; 
      } 

     } 
     is.close(); 
    }catch(Exception e) 
    { 

    } 
    int buffsize = AudioTrack.getMinBufferSize(sr, 
      AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT); 
    // create an audiotrack object 
    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
      sr, AudioFormat.CHANNEL_OUT_STEREO, 
      AudioFormat.ENCODING_PCM_16BIT, buffsize, 
      AudioTrack.MODE_STREAM); 
    audioTrack.play(); 

    int buffNr=0; 

    while(fullMusicBytes.length>=buffNr) { 
     audioTrack.write(fullMusicBytes, buffNr, buffsize); 
     buffNr+=buffsize; 
    } 
+0

私はそう思っています。私は多くのことを知らないので、私はバイトで信号処理を行うことができますか? –

+0

bytearrayはwavefileのサウンドバイトであり、バイト単位で処理できます。ステレオサウンドでは、配列の2バイトごとに右と左または他のいずれかが覚えていません。 wavファイルのbytearrayはヘッダ情報(サンプラート、ステレオ/モノ等)のバイトで始まります。残りは健全な –

+0

ですが、どうすれば生データをバイト[]配列に取り出すことができますか? –

関連する問題