I am parsing a midi file and then sending midi events to connected synthesizer using MIKMIDI but I am getting the events timestamps rounded to an integral second rather than more specific milliseconds. I need help calculating the time accurately. Thanks. // defined earlier class Note { var symbol:String var octave:Int var midiValue:Int var duration:Float }
let BPM:Double = 75
// Ode to joy simplified
var song:[Note] = [
Note(symbol: "E", octave: 5),
Note(symbol: "E", octave: 5),
Note(symbol: "F", octave: 5),
Note(symbol: "G", octave: 5),
Note(symbol: "G", octave: 5),
Note(symbol: "F", octave: 5),
Note(symbol: "E", octave: 5),
Note(symbol: "D", octave: 5),
Note(symbol: "C", octave: 5),
Note(symbol: "C", octave: 5),
Note(symbol: "D", octave: 5),
Note(symbol: "E", octave: 5),
Note(symbol: "E", octave: 5, duration: 3/8),
Note(symbol: "D", octave: 5, duration: 1/8),
Note(symbol: "D", octave: 5, duration: 1/2)
]
let now = NSDate()
let totalDuration:Double = 0
for note:Note in song {
let fullNoteValue:Double = (60000 / BPM) * 0.001 * 4
let noteDuration:Double = fullNoteValue * Double(note.duration)
let timestamp = now.dateByAddingTimeInterval(noteDuration + totalDuration)
MidiDevice.sharedInstance().playNoteOn(note.midiValue, withTimestamp: timestamp)
totalDuration += noteDuration
}
MidiDevice playNoteOn definition
- (void)playNoteOn:(NSInteger)note withTimestamp:(MIDITimeStamp)timestamp {
MIKMutableMIDINoteOnCommand *noteOn = [MIKMutableMIDINoteOnCommand commandForCommandType:MIKMIDICommandTypeNoteOn];
noteOn.note = (NSUInteger) note;
noteOn.velocity = 100;
noteOn.timestamp = timestamp
// noteOn.midiTimestamp = timestamp;
NSMutableArray *destinations = [NSMutableArray array];
for (MIKMIDIDevice *device in [[MIKMIDIDeviceManager sharedDeviceManager] availableDevices]) {
for (MIKMIDIEntity *entity in [device.entities valueForKeyPath:@"@unionOfArrays.destinations"]) {
[destinations addObject:entity];
}
}
// NSArray *destinations = [self.device.entities valueForKeyPath:@"@unionOfArrays.destinations"];
if (![destinations count]) return;
for (MIKMIDIDestinationEndpoint *destination in destinations) {
NSError *error = nil;
if(![self.deviceManager sendCommands:@[noteOn] toEndpoint:destination error:&error]) {
NSLog(@"Unable to send command %@ to endpoint %@: %@", noteOn, destination, error);
}
}
}
How do I change this timestamp to an accurate one I can send using MIDISend() or MIKMIDI?