Bläddra i källkod

修改单声轨的midi不需要静音

Pq 2 år sedan
förälder
incheckning
2867a37635

+ 49 - 2
midiplaylib/src/main/java/com/jinmingyunle/midiplaylib/MidiPlayerUtils.java

@@ -15,8 +15,13 @@ import com.jinmingyunle.midiplaylib.midifile.MidiFile;
 import com.jinmingyunle.midiplaylib.midifile.MidiFileException;
 import com.jinmingyunle.midiplaylib.midifile.MidiFileReader;
 import com.jinmingyunle.midiplaylib.midifile.MidiTrack;
+import com.jinmingyunle.midiplaylib.utils.Utils;
+import com.un4seen.bass.BASS;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import static com.jinmingyunle.midiplaylib.midifile.MidiFile.EventChannelPressure;
 import static com.jinmingyunle.midiplaylib.midifile.MidiFile.EventControlChange;
@@ -333,7 +338,10 @@ public class MidiPlayerUtils {
         if (tracks == null) {
             return false;
         }
-        Log.i("pq","原始id:"+id);
+        if (isSingleTracks()) {
+            return false;
+        }
+        Log.i("pq", "原始id:" + id);
         boolean isPianoId = isPianoId(id);
         if (isPianoId) {
             for (int i = 0; i < PIANO_IDS.length; i++) {
@@ -347,7 +355,7 @@ public class MidiPlayerUtils {
     }
 
     public boolean updateTrackVolumeById(int targetId, float volume) {
-        Log.i("pq","目标id:"+targetId);
+        Log.i("pq", "目标id:" + targetId);
         for (int i = 0; i < tracks.size(); i++) {
             MidiTrack midiTrack = tracks.get(i);
             if (midiTrack != null) {
@@ -360,6 +368,45 @@ public class MidiPlayerUtils {
         return false;
     }
 
+    public boolean isSingleTracks() {
+        if (tracks == null) {
+            return true;
+        }
+        Log.i("pq", "tracksSize:" + tracks.size());
+        if (tracks.size() == 1) {
+            return true;
+        }
+        for (int i = 0; i < tracks.size(); i++) {
+            MidiTrack midiTrack = tracks.get(i);
+            Log.i("pq", "去重前元素:" + midiTrack.getInstrument());
+        }
+        //去重
+        List<MidiTrack> distinct = Utils.distinct(tracks);
+        //删除主音轨id标记为-1的
+        for (int i = 0; i < distinct.size(); i++) {
+            MidiTrack midiTrack = distinct.get(i);
+            if (midiTrack.getInstrument() == -1) {
+                distinct.remove(midiTrack);
+            }
+        }
+        for (int i = 0; i < distinct.size(); i++) {
+            MidiTrack midiTrack = distinct.get(i);
+            Log.i("pq", "去重后元素:" + midiTrack.getInstrument());
+        }
+        if (distinct.size() == 1) {
+            return true;
+        }
+        for (int i = 0; i < distinct.size(); i++) {
+            MidiTrack midiTrack = distinct.get(i);
+            int instrument = midiTrack.getInstrument();
+            if (instrument > 7 || instrument < 0) {
+                Log.i("pq", "非单声轨,当前:" + instrument);
+                return false;
+            }
+        }
+        return true;
+    }
+
     public boolean isPianoId(int id) {
         for (int i = 0; i < PIANO_IDS.length; i++) {
             int pianoId = PIANO_IDS[i];

+ 99 - 48
midiplaylib/src/main/java/com/jinmingyunle/midiplaylib/midifile/MidiTrack.java

@@ -11,20 +11,22 @@
  */
 
 
-
 package com.jinmingyunle.midiplaylib.midifile;
 
+import android.util.Log;
+
 import java.util.ArrayList;
 
 
-/** @class MidiTrack
+/**
+ * @class MidiTrack
  * MidiTrack将曲目的原始middievents作为输入,并获取:
  * The MidiTrack takes as input the raw MidiEvents for the track, and gets:
  * * -曲目中midi音符的列表。
  * - The list of midi notes in the track.
  * * -在轨道上使用的第一个乐器。
  * - The first instrument used in the track.
- *对于midi文件中的每个NoteOn事件,都会创建一个新的MidiNote
+ * 对于midi文件中的每个NoteOn事件,都会创建一个新的MidiNote
  * For each NoteOn event in the midi file, a new MidiNote is created
  * 和添加到轨道,使用AddNote()方法。
  * and added to the track, using the AddNote() method.
@@ -32,60 +34,74 @@ import java.util.ArrayList;
  * The NoteOff() method is called when a NoteOff event is encountered,
  * 以更新MidiNote的持续时间
  * in order to update the duration of the MidiNote.
- */ 
-public class MidiTrack {
-    private int tracknum;                 /** The track number 音轨数量*/
-    private ArrayList<MidiNote> notes;    /** List of Midi notes  音符集合*/
-    private int instrument;               /** Instrument for this track 乐器  音轨*/
-    private String trackName;           /**  声道名称 */
-    private ArrayList<MidiEvent> lyrics;  /** The lyrics歌词 in this track */
+ */
+public class MidiTrack implements Comparable<MidiTrack> {
+    private int tracknum;
+    /**
+     * The track number 音轨数量
+     */
+    private ArrayList<MidiNote> notes;
+    /**
+     * List of Midi notes  音符集合
+     */
+    private int instrument;
+    /**
+     * Instrument for this track 乐器  音轨
+     */
+    private String trackName;
+    /**
+     * 声道名称
+     */
+    private ArrayList<MidiEvent> lyrics;
+    /**
+     * The lyrics歌词 in this track
+     */
     private int time = 0;
 
-    /** Create an empty MidiTrack.  Used by the Clone method */
+    /**
+     * Create an empty MidiTrack.  Used by the Clone method
+     */
     public MidiTrack(int tracknum) {
         this.tracknum = tracknum;
         notes = new ArrayList<MidiNote>(20);
         instrument = 0;
-    } 
+    }
 
-    /** Create a MidiTrack based on the Midi events.  Extract the NoteOn/NoteOff
-     *  events to gather the list of MidiNotes. 基于Midi事件创建MidiTrack。 提取NoteOn件/ NoteOff
+    /**
+     * Create a MidiTrack based on the Midi events.  Extract the NoteOn/NoteOff
+     * events to gather the list of MidiNotes. 基于Midi事件创建MidiTrack。 提取NoteOn件/ NoteOff
      * *事件收集MidiNotes列表
      */
     public MidiTrack(ArrayList<MidiEvent> events, int tracknum) {
         this.tracknum = tracknum;
         notes = new ArrayList<MidiNote>(events.size());
-        instrument = 0;
+        instrument = -1;
         time = 0;
-        time = events.get(events.size() - 1).StartTime+events.get(events.size() - 1).DeltaTime;
- 
+        time = events.get(events.size() - 1).StartTime + events.get(events.size() - 1).DeltaTime;
+
         for (MidiEvent mevent : events) {
             if (mevent.EventFlag == MidiFile.EventNoteOn && mevent.Velocity > 0) {
                 MidiNote note = new MidiNote(mevent.StartTime, mevent.Channel, mevent.Notenumber, 0);
                 AddNote(note);
-            }
-            else if (mevent.EventFlag == MidiFile.EventNoteOn && mevent.Velocity == 0) {
+            } else if (mevent.EventFlag == MidiFile.EventNoteOn && mevent.Velocity == 0) {
                 NoteOff(mevent.Channel, mevent.Notenumber, mevent.StartTime);
-            }
-            else if (mevent.EventFlag == MidiFile.EventNoteOff) {
+            } else if (mevent.EventFlag == MidiFile.EventNoteOff) {
                 NoteOff(mevent.Channel, mevent.Notenumber, mevent.StartTime);
-            }
-            else if (mevent.EventFlag == MidiFile.EventProgramChange) {
+            } else if (mevent.EventFlag == MidiFile.EventProgramChange) {
                 instrument = mevent.Instrument;
-            }
-            else if (mevent.Metaevent == MidiFile.MetaEventLyric) {
+            } else if (mevent.Metaevent == MidiFile.MetaEventLyric) {
                 AddLyric(mevent);
                 if (lyrics == null) {
                     lyrics = new ArrayList<MidiEvent>();
                 }
                 lyrics.add(mevent);
-            } else if(mevent.Metaevent == MidiFile.MetaEventSequenceName) {
+            } else if (mevent.Metaevent == MidiFile.MetaEventSequenceName) {
                 trackName = new String(mevent.Value);
-            } else if(mevent.Metaevent == MidiFile.MetaEventInstrument) {
+            } else if (mevent.Metaevent == MidiFile.MetaEventInstrument) {
 //                trackName = new String(mevent.Value);
             }
         }
-        if (notes.size() > 0 && notes.get(0).getChannel() == 9)  {
+        if (notes.size() > 0 && notes.get(0).getChannel() == 9) {
             instrument = 128;  /* Percussion */
         }
     }
@@ -106,56 +122,78 @@ public class MidiTrack {
         this.trackName = trackName;
     }
 
-    public int trackNumber() { return tracknum; }
+    public int trackNumber() {
+        return tracknum;
+    }
 
-    public ArrayList<MidiNote> getNotes() { return notes; }
+    public ArrayList<MidiNote> getNotes() {
+        return notes;
+    }
+
+    public int getInstrument() {
+        return instrument;
+    }
+
+    public void setInstrument(int value) {
+        instrument = value;
+    }
 
-    public int getInstrument() { return instrument; }
-    public void setInstrument(int value) { instrument = value; }
+    public ArrayList<MidiEvent> getLyrics() {
+        return lyrics;
+    }
 
-    public ArrayList<MidiEvent> getLyrics() { return lyrics; }
-    public void setLyrics(ArrayList<MidiEvent> value) { lyrics = value; }
+    public void setLyrics(ArrayList<MidiEvent> value) {
+        lyrics = value;
+    }
 
 
-    public String getInstrumentName() { if (instrument >= 0 && instrument <= 128)
-                  return MidiFile.Instruments[instrument];
-              else
-                  return "";
-            }
+    public String getInstrumentName() {
+        if (instrument >= 0 && instrument <= 128)
+            return MidiFile.Instruments[instrument];
+        else
+            return "";
+    }
 
-    /** Add a MidiNote to this track.  This is called for each NoteOn event */
+    /**
+     * Add a MidiNote to this track.  This is called for each NoteOn event
+     */
     public void AddNote(MidiNote m) {
         notes.add(m);
     }
 
-    /** A NoteOff event occured.  Find the MidiNote of the corresponding
+    /**
+     * A NoteOff event occured.  Find the MidiNote of the corresponding
      * NoteOn event, and update the duration of the MidiNote.
      */
     public void NoteOff(int channel, int notenumber, int endtime) {
-        for (int i = notes.size()-1; i >= 0; i--) {
+        for (int i = notes.size() - 1; i >= 0; i--) {
             MidiNote note = notes.get(i);
             if (note.getChannel() == channel && note.getNumber() == notenumber &&
-                note.getDuration() == 0) {
+                    note.getDuration() == 0) {
                 note.NoteOff(endtime);
                 return;
             }
         }
     }
 
-    /** Add a lyric event to this track */
-    public void AddLyric(MidiEvent mevent) { 
+    /**
+     * Add a lyric event to this track
+     */
+    public void AddLyric(MidiEvent mevent) {
         if (lyrics == null) {
             lyrics = new ArrayList<MidiEvent>();
         }
         lyrics.add(mevent);
     }
 
-    /** Return a deep copy clone of this MidiTrack. */
+    /**
+     * Return a deep copy clone of this MidiTrack.
+     */
     public MidiTrack Clone() {
         MidiTrack track = new MidiTrack(trackNumber());
         track.instrument = instrument;
         for (MidiNote note : notes) {
-            track.notes.add( note.Clone() );
+            track.notes.add(note.Clone());
         }
         if (lyrics != null) {
             track.lyrics = new ArrayList<MidiEvent>();
@@ -170,11 +208,24 @@ public class MidiTrack {
     public String toString() {
         String result = "Track number=" + tracknum + " instrument=" + instrument + "\n";
         for (MidiNote n : notes) {
-           result = result + n + "\n";
+            result = result + n + "\n";
         }
         result += "End Track\n";
         return result;
     }
+
+    @Override
+    public int compareTo(MidiTrack o) {
+        int original = getInstrument();
+        int target = o.getInstrument();
+        if (original > target) {
+            return 1;
+        } else if (original < target) {
+            return -1;
+        } else {
+            return 0;
+        }
+    }
 }
 
 

+ 21 - 0
midiplaylib/src/main/java/com/jinmingyunle/midiplaylib/utils/Utils.java

@@ -1,5 +1,12 @@
 package com.jinmingyunle.midiplaylib.utils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
 public class Utils {
     public static String bytes2hex(byte[] bytes) {
         StringBuilder sb = new StringBuilder();
@@ -15,4 +22,18 @@ public class Utils {
         return sb.toString();
 
     }
+
+    /**
+     * 集合去重
+     * @param datas
+     * @param <T>
+     * @return
+     */
+    public static <T> List<T> distinct(Collection<T> datas) {
+        if(datas == null){
+            return new ArrayList<>();
+        }
+        Set<T> set = new TreeSet<>(datas);//使用HashSet构造方法去重
+        return new ArrayList<>(set);
+    }
 }