• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Coreaudio-api Digest, Vol 13, Issue 74
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Prev by Date: re: more midi woes...
  • Next by Date: Re: pthread_cond_signal and priority inversion
  • Previous by thread: Audio artifacts with HALLab's File Player
  • Next by thread: Re: pthread_cond_signal and priority inversion
  • Index(es):
    • Date
    • Thread