我正在使用适用于 Android 的 JFugue,并且我已经能够生成 Midi 文件,这些文件随后使用 MediaPlayer 进行复制。我的代码如下:
我的问题是我只能在第一次按下 UI 上的播放按钮时创建 MIDI 文件。第二次按Play,方法
MidiFileManager.savePatternToMidi (. Rhythm.getPattern () setTempo (tempo) REPEAT (repeat), file),
保持冻结状态,程序不再响应。
我再也想不出如何解决这个问题了。
我的代码如下:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.android.midicreator.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play"
android:id="@+id/play_button"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="126dp"
android:onClick="play" />
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ritmos_spinner"
android:background="@android:drawable/btn_dropdown"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:spinnerMode="dropdown" />
</RelativeLayout>
MainActivity.java
package com.example.android.midicreator;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import org.jfugue.midi.MidiFileManager;
import org.jfugue.player.Player;
import org.jfugue.rhythm.Rhythm;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private Rhythm rhythm;
private File file;
private MediaPlayer mediaPlayer;
SharedPreferences sharedPref;
private Ritmos ritmos;
private String music;
private int tempo, repeat;
int i = 1;
Spinner ritmos_spinner;
String[] ritmos_list;
ArrayAdapter<String> spinnerRitmosAdapter;
public static Map<Character, String> Instruments = new HashMap<Character, String>() {
private static final long serialVersionUID = 1L;
{
put('x', "[LO_BONGO]i");
put('o', "[BASS_DRUM]i");
put('.', "Ri");
}};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rhythm = new Rhythm(Instruments);
sharedPref = getSharedPreferences("Ritmos", this.MODE_PRIVATE);
ritmos = new Ritmos(sharedPref);
file = new File(this.getFilesDir(),"OutputMidi.mid");
//////////
// Botones
//////////
ritmos_spinner = (Spinner) findViewById(R.id.ritmos_spinner);
ritmos_list = ritmos.getRitmos().keySet().toArray(new String[ritmos.getRitmos().keySet().size()]);
spinnerRitmosAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, ritmos_list);
spinnerRitmosAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ritmos_spinner.setAdapter(spinnerRitmosAdapter);
file = new File(this.getFilesDir(),"OutputMidi.mid");
}
public void play(View view){
music = ritmos.getRitmo(ritmos_spinner.getSelectedItem().toString());
tempo = 120;
repeat = 1;
rhythm.addLayer(music);
try {
MidiFileManager.savePatternToMidi(rhythm.getPattern().setTempo(tempo).repeat(repeat),file);
} catch (Exception ex) {
ex.getStackTrace();
}
mediaPlayer = MediaPlayer.create(this, Uri.fromFile(file));
mediaPlayer.start();
}
}
Ritmos.java
package com.example.android.midicreator;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Map;
import static android.provider.Settings.Global.getString;
public class Ritmos {
private SharedPreferences sharedPref;
// Constructor
public Ritmos(SharedPreferences sharedPref){
this.sharedPref = sharedPref;
FirstInit();
}
private void FirstInit(){
if(sharedPref.getString("INI","Y").compareTo("Y") == 0){
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("INI","N");
editor.putString("Alegría", "xxx.o.x.x.o.xxo.xxo.x.o.");
editor.putString("Bulería", "x.x.o.x.x.o.xxo.xxo.x.o.");
editor.putString("Soleá", ".xx.o..xx.o..xo..xo.x.o.");
editor.putString("Sevillanas", "x.x.o.x.x.o.");
editor.putString("Tangos", "xxx.x...");
editor.commit();
}
}
public boolean setRitmo(String name, String ritmo){
if(validateRitmo(ritmo)){
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(name, ritmo.toLowerCase());
editor.commit();
return true;
}
else{
return false;
}
}
private boolean validateRitmo(String ritmo){
boolean validate = false;
for(char c : ritmo.toLowerCase().toCharArray()){
if(c != 'x' || c != 'o' || c != '.'){
break;
}
validate = true;
}
return validate;
}
public Map<String, ?> getRitmos(){
Map<String, ?> ritmos = sharedPref.getAll();
ritmos.remove("INI");
return ritmos;
}
public String getRitmo(String name){
return sharedPref.getString(name,"xox");
}
}
build.gradle(模块:应用程序)
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.android.midicreator"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
maven { url 'https://github.com/kshoji/javax.sound.midi-for-Android/raw/master/javax.sound.midi/repository'}
maven { url 'https://github.com/kshoji/JFugue-for-Android/raw/master/jfugue-android/snapshot' }
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'jp.kshoji:javax-sound-midi:0.0.3:@aar'
compile 'jp.kshoji:jfugue-android:5.0.1.201503:@aar'
}