Improvements to TAAE in version 1.4.8

Hi folks,

I've just released version 1.4.8 of The Amazing Audio Engine, and thought I'd let you know about two main changes.

Audio Unit Filter/Channel Updates

I've refactored initialization of AEAudioUnitFilter and AEAudioUnitChannel; it's no longer necessary to pass in a reference to AEAudioController. If you're using either class, you'll get a build error until you update the init call. Easy update, though, and both classes are now more robust.

I've also made some changes that make both classes much easier to subclass, with a formalised setup procedure that can be overloaded and direct access to the audio unit from the realtime thread.

Measurement Mode

There's a significant change in the way Measurement Mode is handled when audio input is coming through the built-in microphone. We discovered recently that an iPad Air 2 bug causes playthrough latency to be extremely high unless Measurement Mode is enabled.

You can enable Measurement Mode in TAAE by setting useMeasurementMode to YES. I recommend it, as it resolves the latency problem - and boosts the bass response too.

However, because Measurement Mode disables iOS's automatic gain control, input gain through the built-in mic is very low, even with the input gain setting at max. Previous versions of TAAE simply disabled Measurement Mode with the built-in mic for this reason, but the iPad Air 2 latency bug means this is no longer the right call.

So now TAAE will automatically boost the incoming signal by a factor of about 20dB when in Measurement Mode with the built-in mic, unless you set the boostBuiltInMicGainInMeasurementMode property to NO. This is an attempt to approximate the same power levels. Of course, it's a bit of a hack as it's not proper auto gain, and the value was determined entirely experimentally, but it seems to work fine, and the bass response is really nice. Be sure to check out the inputGain property, too, which operates independently of the aforementioned boost.

Feedback is very welcome.

As always, you can get the update via CocoaPods, or from GitHub.

Other stuff coming soon

There're a couple of exciting things in the works: Jeremy Huff and Ryan King of Hello World Engineering have been working on a streaming replacement for AEAudioFilePlayer which I'll be merging in soon. I've been wanting to replace the memory-heavy AEAudioFilePlayer for ages, so this is very welcome. Stay tuned.

Also, Steve Rubin's put together an OS X port of TAAE which is currently sitting in a feature branch. It's waiting for audio input support and a working sample app, but once that's done, TAAE will officially support the Mac!

Happy audio programming!

Comments

  • Any idea when the streaming replacement for AEAudioFilePlayer will arrive?

  • This week, @Planetpjs - I've just gotta review the pull request

  • Could you please keep the old version around as well? I have built my own (buggy) version of a streaming player that inserts commands in the audio circular buffer using magic timestamps, I'd be interested to see a proper approach, and to be able to tell what the battery usage implications of another solution are!

  • edited August 2015

    Hmm, I'm afraid not; it's simply not good enough, when a streaming approach is available. It was written as a demonstration of how to create channel data; was never meant to be used as it's being used.

    You can always find it in the repository's history, though, if you need it for some obscure reason =)

  • I'm using MusicPlayer to play MIDI files with kAudioUnitSubType_Sampler. Was working fine with 1.4.7 and below and now it won't play. Is it perhaps not finding the AUNode on this method: MusicSequenceSetAUGraph like it should because of the update to AEAudioUnitChannel? I also noticed you took away access to AEAudioUnitChannel.audioGraphNode, is this change permanent?

    Thanks.

  • Ah, MusicSequence, our old friend. Yes, the new stuff moves away from using the AUGraph (and creates the audio units directly) to address a couple of dependency/state reload difficulties. I did that not being aware of MusicSequence's dependency upon AUGraph, so I don't have a solid solution for that right now. With that said, Alejandro Santander's put together a MusicSequence-based sampler which I'm going to be rolling into TAAE; it uses a proxy to solve this problem - it'll be in as soon as I've had a look (been a busy week!).

    Till then...Not sure what to suggest, besides using the audioGraph property on AEAudioController to create the sampler audio unit yourself. Sorry about that.

  • No problem, I'll just roll back to 1.4.7 until the MusicSequence sampler is in place.

  • @jsonfellin, I've just moved back to AUGraph. It was easier than addressing the MusicSequencer limitation, and I resolved the other difficulties. So you should be good to go.

  • I have a class within I use the AEAudioUnitChannel-class to instantiate AUSampler and add to channel groups. This works fine in pre 1.4.8. In 1.4.8, when I remove the audiocontroller and error arguments it compiles, but floods the log with error "AudioUnitRender result -10867" and there's no sound.

    Any clue how to fix that?

    my code attached

  • Try using it with the latest version from the master branch, @okramis.

  • hey, this looks very wonderful for its potential for several of my projects. i started using it today, and almost have an app up and running! Anyway though, I see above that there's going to be a replacement soon for AEAudioFilePlayer? I assume that's not yet updated, as AEAudioFilePlayer was in the latest "TheEngineSample" app, which is what i'm using to model my stuff after. Please confirm. Also, will the new replacement class enable me to easily swap-out audio files? For example, if i'm playing "Southern Rock Organ.m4a" on Loop 1 and I wanted to change that to be "Northern Rock Rhodes.m4a" or something, and restart the loop (I don't need to do it in time on the fly, restart is ok). I didn't see this done anywhere in the sample to do this (all audio files are initialized at the beginning, and no new ones are added on the fly in the sample app). In playing with the code, i saw that i could add channels to the audiocontroller as i went along, but i didn't see how to gracefully remove an old channel and replace it with a new one-- the app kept crashing without any error message when i did this; perhaps i was not doing it correctly. is there a pattern to use for this? And if so, if this is all changing this week anyway, then I'll just wait until the new classes come out, but i'll still have to do the same use case. i hope this makes sense. great framework. cheers!

  • The new AEAudioFilePlayer is already in the master branch (not released on Cocoapods yet, but fully accessible from Github).

    No swapping out: you just need to create a new player for the new file.

    You should be able to add/remove channels at any time, though!

  • I see. Is there an issue if my m4a file is like 15 minutes long? I was seeing some lag when i instantiate these big files (about 5 seconds waiting on that line of code), and then, when i tried to create a new player with an equally large file after removing the old channel from the audiocontroller, the app would just crash on me while I wait. This didn't happen with the little 3-second long samples, but these big files it is. I did a "removeChannels" and passed an array containing only the one m4a, then I reset the player pointer to a new one that i created and tried to add it, and while it was running that line of code (which took 5 seconds the first time), the app just crashes without any breakpoints. Do I need to chunk out my files and use smaller files instead of 15 minute opuses?

  • Not any more!

  • @Michael said:
    Try using it with the latest version from the master branch, okramis.

    Thanks for reply, should the downloadable zip reflect the master branch?

  • Yup, that's right

  • @Michael said:
    Yup, that's right

    So then, thats what I have tested with --> "AudioUnitRender result -10867" and there's no sound.

  • edited August 2015

    so when was github updated with the latest version of AEAudioFilePlayer, because I downloaded the latest from github yesterday morning (sunday morning), and it was taking 5 seconds to instantiate an objecxt on a 15-minute m4a file. has it changed since then? maybe i somehow got an old version. i'll try again

  • It was about a week ago - are you definitely downloading the correct zip file? It's the "Download ZIP" button on the main project page.

  • When will this be configured for Cocoapods. I try to refrain from using 3rd party libraries without cocoapods.

  • Couple of weeks maybe? Once I'm satisfied it's sufficiently stable.

    You can use Cocoapods with any branch/tag without needing a release, you just need to provide the correct pod syntax - take a look at the docs for details (I dunno off the top of my head).

  • @Michael said:
    This week, Planetpjs - I've just gotta review the pull request

    I see the pull request was closed and not merged. I also see that there was another PR attempt to add an AudioUnit-based player that wasn't quite right.

    That latter one looks to be the approach you took with the new AEAudioFilePlayer. So does the new AEAudioFilePlayer allow streaming? If so, can I only stream from disk, or can I use a web URL?

  • I used a hybrid approach, but yep: it's done and in there now, and it can stream from disk.

    For playing from network sources, you'll need to use another tool which can manage the vagaries of network playback (bandwidth, jitter, etc).

  • indeed, i had an old version and the new one is much better. cheers!

This discussion has been closed.