示例#1
0
//- loading -------------------------------------------------------------------

        //read in a midi seqence from a standard midi file
        public static Sequence readMidiFile(String filename)
        {
            MidiInStream stream = new MidiInStream(filename);

            //read midi file header
            String sig        = stream.getString(4);
            uint   hdrsize    = stream.getFour();
            int    fileFormat = stream.getTwo();
            int    trackCount = stream.getTwo();
            int    division   = stream.getTwo();

            if (!sig.Equals("MThd") || hdrsize != 6)
            {
                throw new MidiFileException(filename + " is not a valid MIDI file ", 0);
            }

            Sequence seq = new Sequence(division);

            loadTrackZeroData(stream, seq);

            //read midi track data
            for (int trackNum = 1; trackNum < trackCount; trackNum++)
            {
                curTrackNum = trackNum;
                loadTrackData(stream, seq, trackNum);
            }

            finalizeTracks(seq);
            return(seq);
        }
示例#2
0
        //read data from a single track chunk
        private static void loadTrackData(MidiInStream stream, Sequence seq, int trackNum)
        {
            //read track header
            String trackSig        = stream.getString(4);
            uint   trackDataLength = stream.getFour();

            if (!trackSig.Equals("MTrk"))
            {
                throw new MidiFileException(stream.filename + " has an invalid track at ", stream.getDataPos() - 8);
            }

            Track track = seq.addTrack();                           //get new track from sequence

            track.setName("Track " + trackNum.ToString());

            int currentTime = 0;                //event time in ticks

            runningStatus = 0;
            sysexCont     = false;
            prevSysEx     = null;
            Event evt = null;

            int startpos = stream.getDataPos();

            while ((stream.getDataPos() - startpos) < trackDataLength)
            {
                currentTime += (int)stream.getVariableLengthVal();      //add delta time to current num of ticks
                evt          = loadEventData(stream);
                if ((evt != null) && !(evt is EndofTrackEvent ||
                                       evt is MarkerEvent || evt is CuePointEvent || //these are ignored in tracks other than track 0
                                       evt is TempoEvent || evt is SMPTEOffsetEvent ||
                                       evt is TimeSignatureEvent || evt is KeySignatureEvent))
                {
                    track.addEvent(evt, currentTime);
                }
            }

            //last event in track must be an "end of track" event
            if ((evt != null) && !(evt is EndofTrackEvent))
            {
                throw new MidiFileException(stream.filename + ": track " + curTrackNum.ToString() +
                                            "missing end of track event at ", stream.getDataPos() - 8);
            }
        }
示例#3
0
        //build the tempo, meter and marker maps from tempo message from track 0
        private static void loadTrackZeroData(MidiInStream stream, Sequence seq)
        {
            //read track header
            String trackSig        = stream.getString(4);
            uint   trackDataLength = stream.getFour();

            if (!trackSig.Equals("MTrk"))
            {
                throw new MidiFileException(stream.filename + " has an invalid track 0 at ", stream.getDataPos() - 8);
            }

            int currentTime = 0;        //event time in ticks

            runningStatus = 0;
            sysexCont     = false;
            prevSysEx     = null;
            Event evt;

            Meter prevMeter = null;

            int startpos = stream.getDataPos();

            while ((stream.getDataPos() - startpos) < trackDataLength)
            {
                currentTime += (int)stream.getVariableLengthVal();      //add delta time to current num of ticks
                evt          = loadEventData(stream);

                if (evt is TempoEvent)
                {
                    Tempo tempo = new Tempo(currentTime, ((TempoEvent)evt).tempo);
                    seq.tempoMap.addTempo(tempo);
                }
                else if (evt is SMPTEOffsetEvent)       //not handling smpte timing yet
                {
                }
                else if (evt is TimeSignatureEvent)
                {
                    int   keysig = (prevMeter != null) ? prevMeter.keysig : 0;
                    Meter meter  = new Meter(currentTime, ((TimeSignatureEvent)evt).numer, ((TimeSignatureEvent)evt).denom, keysig);
                    seq.meterMap.addMeter(meter);
                    prevMeter = meter;
                }
                else if (evt is KeySignatureEvent)
                {
                    int numer = 4;
                    int denom = 4;
                    if (prevMeter != null)
                    {
                        numer = prevMeter.numer;
                        denom = prevMeter.denom;
                    }
                    Meter meter = new Meter(currentTime, numer, denom, ((KeySignatureEvent)evt).keySig);
                    seq.meterMap.addMeter(meter);
                    prevMeter = meter;
                }
                else if (evt is MarkerEvent)
                {
                }
                else if (evt is CuePointEvent)
                {
                }
            }
        }