谁能帮助我如何以编程方式将.mid
文件转换为任何音频格式.wav
或.mp3
格式。
1 回答
我认为可以使用 AudioRecorder 直接从 MediaPlayer 录制,将 Mediaplayer 设置为录音机的音频源,但似乎没有办法做到这一点。所以,我想了两种非常不干净的方法:
1- 大多数设备都有一个 3.5 毫米插孔,3 个通道,2 个用于立体声输出,1 个用于麦克风输入。您需要的是一根将三个信号分开的电缆,这样您就可以将立体声输出连接到输入,以某种短路的形式,并从麦克风输入录制 midi。我用它来将音频流源传递给手机,对其进行详细说明,然后将其发送到第三个设备。我所说的线与带有立体声音频+视频的 RCA 连接器非常相似,我知道这听起来很疯狂,但这取决于你在做什么。
2-假设您在实际播放时不需要录制midi,您可以读取midi文件然后自己合成声音。这真的很难,特别是当必须处理不同乐器(弦乐、鼓等)的声音时,使用样本可能会减少工作量。
我知道这不是预期的答案,但总比没有好,如果您如此渴望尝试其中一种方法,我可以提供一些示例代码和链接。
编辑:
好吧,那是疯了。我找到了另一种方法,使用Visualizer类。可视化器的目的不是让PCM记录它,而是(令人惊讶地)可视化声波,因此可能存在一些质量问题。但是,您可以将 PCM 保存为波形格式,为此,您必须在原始 PCM 数组中添加一个标头。对于波形文件格式,请查看此处。这是一个示例,它仅显示了从 TextView 中的 MediaPlayer 获取的字节数组,但它似乎可以工作......!
android.permission.RECORD_AUDIO
android.permission.MODIFY_AUDIO_SETTINGS
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</ScrollView>
MainActivity.java
package com.example.midify;
import java.util.Arrays;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
MediaPlayer mp;
TextView tv;
Visualizer mVisualizer;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
tv.setText((String) msg.obj);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp = MediaPlayer.create(this, R.raw.midi);
Button btn = (Button) findViewById(R.id.btn);
Button btn2 = (Button) findViewById(R.id.btn2);
tv = (TextView) findViewById(R.id.textview);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (!mp.isPlaying()) {
mp.start();
init_visualizer();
}
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (mp.isPlaying()) {
mp.pause();
mVisualizer.release();
}
}
});
}
@Override
public void finish() {
mp.release();
mVisualizer.release();
super.finish();
}
private void PassData(byte[] data) {
String txt = Arrays.toString(data);
Message msg = handler.obtainMessage();
msg.obj = txt;
handler.sendMessage(msg);
}
public void init_visualizer() {
mVisualizer = new Visualizer(mp.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer,
byte[] bytes, int samplingRate) {
PassData(bytes);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate) {
}
};
mVisualizer.setDataCaptureListener(captureListener,
Visualizer.getMaxCaptureRate(), true, false);
mVisualizer.setEnabled(true);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mVisualizer.setEnabled(false);
}
});
}
}