Hi,

A few things come to my mind, not sure if it's related or not to your problems:

A MIDI packet can have multiple MIDI events. This often happens if the
source plays two notes exactly at the same time, etc.

The packet timestamp can be 0 in some cases, depending on the source,
meaning "play this packet as soon as possible".

In the stackoverflow question, you produce the actual samples on the
MIDI thread. I think it's better to put the events on a thread-safe
queue and process them on the audio thread.

/Jonatan

> Date: Tue, 17 May 2016 01:48:06 -0700 (PDT)
> From: "Patrick J. Collins" <[email protected]>
> To: [email protected]
> Subject: more midi woes...
> Message-ID: <[email protected]>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> Hi everyone,
>
> So I have spent a good 4 painful days trying to get midi playback to
> work, and I am about ready to give up.  It's so depressing, what should
> be so easy has proven to be so incredibly difficult and frustrating.
> The worst part is, I can't even figure out what is happening.  I've
> tried rewriting my code in a billion different ways, and every time it
> results in something "wrong", just in a different way.
>
> I guess the first question to ask here is:
>
> Do we really, really, really know that the MidiReadProc is reliable and
> actually works?
>
> I am doing what seems like the simplest of simple:  Send midi events to
> an instrument if they are for a particular channel.
>
>   static void midiReadProc(const MIDIPacketList *pktlist,
>                            void *refCon,
>                            void *connRefCon) {
>
>       struct MidiData *midiData = (struct MidiData *)refCon;
>
>       MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
>       for (int i = 0; i < pktlist->numPackets; i++) {
>           NSUInteger channel = packet->data[0] & 0xf;
>           FMInstrument *fmInstrument = midiData->fmInstruments[channel];
>           if (fmInstrument && channel == 6) [fmInstrument 
> writePacketWithObservedTimestamps:*packet];
>           packet = MIDIPacketNext(packet);
>       }
>   }
>
> ...
>
> Then in my FMInstrument class, I am just doing:
>
>   -(void)writePacketWithObservedTimestamps:(MIDIPacket)packet {
>       _ringBuffer->Write(packet.data, packet.length);
>
>       MIDITimeStamp now = packet.timeStamp;
>       if (self.lastReadAt) {
>           NSNumber *delta = [NSNumber numberWithDouble:convertToSeconds(now) 
> - convertToSeconds(self.lastReadAt)];
>           [self.deltas insertObject:delta atIndex:0];
>       }
>       self.lastReadAt = now;
>   }
>
> And i've dispatched a thread to do:
>
>   -(void)startPolling {
>       while (_shouldPoll) {
>           @autoreleasepool {
>               if (![self.deltas count]) continue;
>
>               NSUInteger numberOfSamplesToGenerate = ceil([self sampleRate] * 
> [[self.deltas lastObject] doubleValue]);
>               [self.deltas removeLastObject];
>               short *tempBuffer = (short *)malloc(sizeof(short) * 
> numberOfSamplesToGenerate);
>               _synthUnit->GetSamples(numberOfSamplesToGenerate, tempBuffer);
>
>               for (int i = 0; i < numberOfSamplesToGenerate; i++) {
>                   _generatedSamples[_bufferWriteIndex] = tempBuffer[i];
>                   _bufferWriteIndex += 1;
>                   if (_bufferWriteIndex > _maxBufferIndex) _bufferWriteIndex 
> = 0; // _maxBufferIndex is samplerate * duration of sequence
>               }
>               free(tempBuffer);
>           }
>       }
>   }
>
> Just as a test, I am letting the MidiReadProc process the entire midi file,
> after its done, then I let OpenAL stream the buffer, and the timing of all the
> midi events is just, pure insanity.  All over the place..  Total nonsense..
> notes that should not sound until way later happen immediately.  It's as if
> MidiReadProc is giving me totally incorrect timestamps, and delivering the
> events in the wrong order...  But that's not possible right?
>
> The only thing left for me to try is to not use the MidiReadProc, but rather
> iterator through all the midi events in all the tracks..  I was trying to 
> avoid
> having to do that because it's no fun, and I thought Midi was a solved problem
> and that certainly it would be trivial to have midi playback with fm 
> synthesis...
>
> I'm depressed.
>
> Patrick J. Collins
> http://collinatorstudios.com

-- 
/Jonatan
http://kymatica.com
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to