2017-02-10 74 views
1

我正在制作一个简单的android应用程序,用于从智能手机麦克风录制某些内容,将其保存在文件中,然后播放该文件。Android: - 将录制的音频文件转换为浮点阵列

现在我想对该音频文件应用高通滤波器,但要这样做,我需要先将音频文件转换为浮点数组。有人能帮助我吗?

感谢

package abc.com.please; 

import android.content.pm.PackageManager; 
import android.media.MediaPlayer; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.os.Environment; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 


public class MainActivity extends AppCompatActivity { 

private static MediaRecorder mediaRecorder = new MediaRecorder(); 
private static MediaPlayer mediaPlayer; 

private static String audioFilePath; 
private static Button stopButton; 
private static Button playButton; 
private static Button recordButton; 

private boolean isRecording = false; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    recordButton = (Button) findViewById(R.id.recordButton); 
    playButton = (Button) findViewById(R.id.playButton); 
    stopButton = (Button) findViewById(R.id.stopButton); 

    if (!hasMicrophone()) 
    { 
     stopButton.setEnabled(false); 
     playButton.setEnabled(false); 
     recordButton.setEnabled(false); 
    } else { 
     playButton.setEnabled(false); 
     stopButton.setEnabled(false); 
    } 

    audioFilePath = 
      Environment.getExternalStorageDirectory().getAbsolutePath() 
        + "/myaudio.3gp"; 


    recordButton.setOnClickListener(new View.OnClickListener(){ 

     public void onClick (View v) 
     { 

      isRecording = true; 
      stopButton.setEnabled(true); 
      playButton.setEnabled(false); 
      recordButton.setEnabled(false); 

      try { 
       mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
       mediaRecorder.setOutputFile(audioFilePath); 
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
       mediaRecorder.prepare(); 
       mediaRecorder.start(); 
      }catch (Exception e) { 
       e.printStackTrace(); 

      } 



     } 
    }); 

    stopButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick (View view) 
     { 

      stopButton.setEnabled(false); 
      playButton.setEnabled(true); 
      if (isRecording) 
      { 
       recordButton.setEnabled(false); 
       isRecording = false; 
       mediaRecorder.stop(); 
       mediaRecorder.release(); 
       recordButton.setEnabled(true); 
      } 
      else 
      { 
       Toast.makeText(getApplicationContext(),"No recording going  on",Toast.LENGTH_SHORT).show(); 
      } 
     }}); 

    playButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) 

     { 

      playButton.setEnabled(false); 
      recordButton.setEnabled(false); 
      stopButton.setEnabled(true); 
      try { 
       mediaPlayer = new MediaPlayer(); 
       mediaPlayer.setDataSource(audioFilePath); 
       mediaPlayer.prepare(); 
       mediaPlayer.start(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    }); 
} 

protected boolean hasMicrophone() { 
    PackageManager pmanager = this.getPackageManager(); 
    return pmanager.hasSystemFeature(
      PackageManager.FEATURE_MICROPHONE); 
} 








} 
+0

入住这 [堆栈溢出问题] [1] [1]:http://stackoverflow.com/questions/6235016/convert-wav-audio-format-byte-array-to-浮点 –

回答

1

字节到浮充转换的细节将取决于您使用的音频文件的文件格式。我无法确定代码中的格式。如果您的文件是WAV,44100 fps,16位,小端,立体声(这是一种标准的Java,“CD质量”格式),您可以尝试使用我编写的以下代码。密钥变换点是当两个字节被连接并转换为单个数字(其中,“缓冲液”包含数据被从音频文件中读取:

float audioVal = (buffer[bufferIdx++] & 0xff) 
         | (buffer[bufferIdx++] << 8); 

如果是大端,扭转偏移的顺序。如果是24位或32位,那么你将分别在<和< 16和< 24位上进行或运算,结果将使用一个短的范围,所以除以32767需要进行归一化结果为[-1..1]

我一直在Java上下文中使用以下一段时间没有问题,但我不知道Android是否支持javax.sound.sampled.Aud ioInputStream等等。也许在读取文件的上下文中看到转换仍然有用吗?该代码假定我们具有“CD质量”音频格式,并且音频文件不超过Integer.MAX帧数。

public float[] loadSoundFileURL(URL url) throws UnsupportedAudioFileException, 
     IOException 
{ 
    AudioInputStream ais = AudioSystem.getAudioInputStream(url); 

    int framesCount = (int)ais.getFrameLength(); 

    // assuming stereo format, so two entries per frame 
    float[] temp = new float[framesCount * 2]; 
    long tempCountdown = temp.length; 

    int bytesRead = 0; 
    int bufferIdx; 
    int clipIdx = 0; 
    byte[] buffer = new byte[1024]; 
    while((bytesRead = ais.read(buffer, 0, 1024)) != -1) 
    { 
     bufferIdx = 0; 
     for (int i = 0, n = (bytesRead >> 1); i < n; i ++) 
     { 
      if (tempCountdown-- >= 0) 
      { 
       temp[clipIdx++] = 
         (buffer[bufferIdx++] & 0xff) 
         | (buffer[bufferIdx++] << 8) ; 
      } 
     } 
    } 

    // QUESTION: better to do following in above loop? 
    for (int i = 0; i < temp.length; i++) 
    { 
     temp[i] = temp[i]/32767f; 
    } 

    return temp; 
}