Re: Coreaudio-api Digest, Vol 13, Issue 74
Re: Coreaudio-api Digest, Vol 13, Issue 74
- Subject: Re: Coreaudio-api Digest, Vol 13, Issue 74
- From: Jonatan Liljedahl <email@hidden>
- Date: Wed, 18 May 2016 13:46:00 +0200
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@hidden>
> To: email@hidden
> Subject: more midi woes...
> Message-ID: <email@hidden>
> 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@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden