matsune / MidiParser

Read/Write SMF(Standard Midi Files) in Swift for iOS/macOS
MIT License
84 stars 36 forks source link

The time stamp is not correct for some midi file #6

Open zhouhao27 opened 4 years ago

zhouhao27 commented 4 years ago

For example, I convert my midi in https://tonejs.github.io/Midi/ to this:

{
  "header": {
    "keySignatures": [],
    "meta": [
      {
        "ticks": 0,
        "type": "sequencerSpecific"
      },
      {
        "ticks": 0,
        "type": "sequencerSpecific"
      },
      {
        "ticks": 0,
        "type": "sequencerSpecific"
      }
    ],
    "name": "",
    "ppq": 960,
    "tempos": [
      {
        "bpm": 109.99990833340972,
        "ticks": 0
      }
    ],
    "timeSignatures": [
      {
        "ticks": 0,
        "timeSignature": [
          4,
          4
        ],
        "measures": 0
      }
    ]
  },
  "tracks": [
    {
      "channel": 0,
      "controlChanges": {},
      "pitchBends": [],
      "instrument": {
        "family": "piano",
        "name": "acoustic grand piano",
        "number": 0
      },
      "name": "Track 1",
      "notes": [
        {
          "duration": 0.27272750000000023,
          "durationTicks": 480,
          "midi": 74,
          "name": "D5",
          "ticks": 2640,
          "time": 1.50000125,
          "velocity": 0.5039370078740157
        },
        {
          "duration": 0.2727274999999998,
          "durationTicks": 480,
          "midi": 70,
          "name": "A#4",
          "ticks": 4080,
          "time": 2.31818375,
          "velocity": 0.5039370078740157
        },
        {
          "duration": 0.27272750000000023,
          "durationTicks": 480,
          "midi": 77,
          "name": "F5",
          "ticks": 5280,
          "time": 3.0000025,
          "velocity": 0.5039370078740157
        },
        {
          "duration": 0.2727274999999998,
          "durationTicks": 480,
          "midi": 67,
          "name": "G4",
          "ticks": 6960,
          "time": 3.9545487500000003,
          "velocity": 0.5039370078740157
        },
        {
          "duration": 0.545455,
          "durationTicks": 960,
          "midi": 71,
          "name": "B4",
          "ticks": 6960,
          "time": 3.9545487500000003,
          "velocity": 0.5039370078740157
        },
        {
          "duration": 0.27272750000000023,
          "durationTicks": 480,
          "midi": 75,
          "name": "D#5",
          "ticks": 8160,
          "time": 4.6363675,
          "velocity": 0.5039370078740157
        }
      ]
    }
  ]
}

But the time is not correct after parsing with MidiParser. Here is the result:

Name time duration
--------------------
D6      2.75     0.5
A#5   4.25      0.5
F6      5.5        0.5
G5     7.25      0.5
B5     7.25      1.0
D#6  8.5        0.5

Here is my code:

    let midi = MidiData()
    if let data = try? Data(contentsOf: URL(fileURLWithPath: file)) {

      midi.load(data: data)

      for track in midi.noteTracks {
        if track.notes.count == 0 {
          continue
        }

        for note in track.notes {
          print(converToNoteName(note.pitch),note.timeStamp,note.duration)
        }
      }
    }

What could be wrong? Thanks.

zhouhao27 commented 4 years ago

I think the calculation for time stamp and duration does not consider the tempo.