问题描述
我正在制作一个简单的android应用程序,在其中录制智能手机麦克风中的内容,将其保存在文件中,然后播放该文件。
现在,我想对该音频文件应用高通滤波器,但是要这样做,我需要先将音频文件转换为float数组。 有人可以帮我解决这个问题。
谢谢
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);
}
}
1楼
字节到浮点转换的详细信息将取决于您用于音频文件的文件格式。 我无法从您的代码中得知该格式是什么。 如果您的文件是WAV,44100 fps,16位,小尾数立体声(这是标准Java,“ CD质量”格式),则可以尝试使用我编写的以下代码。 关键的转换点是将两个字节连接起来并转换为一个数字时(其中“缓冲区”包含从音频文件中读取的数据):
float audioVal = ( buffer[bufferIdx++] & 0xff )
| ( buffer[bufferIdx++] << 8 );
如果是大字节序,则反转移位顺序。 如果是24或32位,那么您将分别进行<< <<和<< 24的移位。 对于16位,结果将利用short的范围,因此需要除以32767才能将结果归一化为[-1..1]。
我已经在Java上下文中使用以下内容一段时间了,但是没有问题,但是我不知道Android是否支持javax.sound.sampled.AudioInputStream等。也许在文件上下文中查看转换还是有用的读? 该代码假定我们具有“ CD Quality”音频格式,并且该音频文件的长度不超过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;
}