Sorry, I made a mistake: 10 x 10 AudioUnit instances was my old architecture. Now that I'm using AUMIDISynth instead of AUSampler, it's only 1 AudioUnit per "instrument". So there's only 10 synth AudioUnits in a 10-instrument document, each with 16 channels active. But the rest still applies.
On Fri, Jul 8, 2016 at 4:38 PM, Archagon <[email protected]> wrote: > Unless I'm doing something wrong (very possible), it seems there's a > pretty significant memory leak in AUMIDISynth. I have a document-based > music app that loads a number of instruments from an SF2 whenever a > document is opened, and then tears down the samplers and AUGraph when > the document is closed. In order to pitch-bend individual notes, each > "instrument" in the app loads up 10 individual AUMIDISynth instances. > > For a document with 10 "instruments" (and thus ~100 AUMIDISynth > instances pointing to 10 different patches in the SF2), I leak about > 6MB of memory every time I close and re-open a document. After 3 open > and close operations, the memory profiler trace looks like this: > > Leaked Object # Address Size Responsible Library Responsible Frame > NSMutableDictionary 17827 < multiple > 1.09 MiB AudioToolbox > EnvelopeState::Save(CACFDictionary&) const > NSMutableDictionary 11972 < multiple > 748.25 KiB AudioToolbox > LayerState::Save(CACFDictionary&) const > Malloc 112 Bytes 6829 < multiple > 746.92 KiB AudioToolbox > CACFDictionary::AddUInt32(__CFString const*, unsigned int) > Malloc 112 Bytes 6822 < multiple > 746.16 KiB AudioToolbox > CACFDictionary::AddUInt32(__CFString const*, unsigned int) > Malloc 112 Bytes 5139 < multiple > 562.08 KiB AudioToolbox > CACFDictionary::AddBool(__CFString const*, bool) > Malloc 112 Bytes 5138 < multiple > 561.97 KiB AudioToolbox > CACFDictionary::AddBool(__CFString const*, bool) > Malloc 32 Bytes 17819 < multiple > 556.84 KiB AudioToolbox > CACFDictionary::AddUInt32(__CFString const*, unsigned int) > Malloc 32 Bytes 17818 < multiple > 556.81 KiB AudioToolbox > CACFDictionary::AddUInt32(__CFString const*, unsigned int) > Malloc 144 Bytes 2550 < multiple > 358.59 KiB AudioToolbox > CACFArray::AppendDictionary(__CFDictionary const*) > __NSCFNumber 5800 < multiple > 181.25 KiB AudioToolbox > CACFDictionary::AddFloat32(__CFString const*, float) > Malloc 144 Bytes 1276 < multiple > 179.44 KiB AudioToolbox > CACFArray::AppendDictionary(__CFDictionary const*) > Malloc 192 Bytes 864 < multiple > 162.00 KiB AudioToolbox > CACFDictionary::AddFloat32(__CFString const*, float) > Malloc 192 Bytes 857 < multiple > 160.69 KiB AudioToolbox > CACFDictionary::AddFloat32(__CFString const*, float) > NSMutableDictionary 2553 < multiple > 159.56 KiB AudioToolbox > LayerState::Save(CACFDictionary&) const > NSMutableDictionary 2553 < multiple > 159.56 KiB AudioToolbox > LayerState::Save(CACFDictionary&) const > Malloc 192 Bytes 723 < multiple > 135.56 KiB AudioToolbox > CACFDictionary::AddArray(__CFString const*, __CFArray const*) > Malloc 192 Bytes 722 < multiple > 135.38 KiB AudioToolbox > CACFDictionary::AddArray(__CFString const*, __CFArray const*) > __NSCFArray 2551 < multiple > 119.58 KiB AudioToolbox > EnvelopeState::Save(CACFDictionary&) const > Malloc 80 Bytes 1278 < multiple > 99.84 KiB AudioToolbox > CACFArray::AppendDictionary(__CFDictionary const*) > Malloc 80 Bytes 1277 < multiple > 99.77 KiB AudioToolbox > CACFArray::AppendDictionary(__CFDictionary const*) > NSMutableDictionary 1452 < multiple > 90.75 KiB AudioToolbox > LayerState::Save(CACFDictionary&) const > Malloc < varying sizes > 433 < multiple > 81.11 KiB AudioToolbox > CACFDictionary::AddArray(__CFString const*, __CFArray const*) > Malloc < varying sizes > 433 < multiple > 81.11 KiB AudioToolbox > CACFDictionary::AddArray(__CFString const*, __CFArray const*) > Malloc 192 Bytes 432 < multiple > 81.00 KiB AudioToolbox > CACFDictionary::AddFloat32(__CFString const*, float) > Malloc 192 Bytes 432 < multiple > 81.00 KiB AudioToolbox > CACFDictionary::AddFloat32(__CFString const*, float) > > ...and so on, down quite a long ways. Mostly metadata stuff (?) in > AudioToolbox, from the looks of it. > > I tried clearing the state of my samplers in any way I could: running > kAUMIDISynthProperty_EnablePreload with no instruments selected, > setting the kMusicDeviceProperty_SoundBankURL to nothing, running > AudioUnitReset on every possible scope. No dice. > > For the record, here's how I load my samples: > > -(void) setInstrument:(int)actualPreset withSF2URL:(NSURL*)url > forSampler:(AudioUnit)sampler > { > // load soundfont > { > CFURLRef cfUrl = CFBridgingRetain(url); > AudioUnitSetProperty(sampler, > kMusicDeviceProperty_SoundBankURL, > kAudioUnitScope_Global, > 0, > &cfUrl, > sizeof(cfUrl)); > CFBridgingRelease(url); > } > > // load instruments > { > for (int i = 0; i < kMIDI_MaxChannels; i++) { > UInt32 enabled = 1; > AudioUnitSetProperty(sampler, > kAUMIDISynthProperty_EnablePreload, kAudioUnitScope_Global, 0, > &enabled, sizeof(enabled)); > MusicDeviceMIDIEvent(sampler, kMIDIMessage_Patch | i, > (UInt32)actualPreset, 0, 0); > > enabled = 0; > AudioUnitSetProperty(sampler, > kAUMIDISynthProperty_EnablePreload, kAudioUnitScope_Global, 0, > &enabled, sizeof(enabled)); > MusicDeviceMIDIEvent(sampler, kMIDIMessage_Patch | i, > (UInt32)actualPreset, 0, 0); > } > } > > Notably, even if I avoid using kAUMIDISynthProperty_EnablePreload, and > no matter how many channels I load, the memory leak is always exactly > the same size. But if I never send a MusicDeviceMIDIEvent message, > there's no more leak. > > Is there anything I could do about this? > > Thank you, > -Alexei B. _______________________________________________ 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]
