SlideShare a Scribd company logo
1 of 90
Core Audio in iOS 6
                            Chris Adamson • @invalidname
                                  CocoaConf Raleigh
                                  December 1, 2012



                            Sides and code available on my blog:
                               http://www.subfurther.com/blog

Sunday, December 2, 12
Plug!




Sunday, December 2, 12
The Reviews Are In!




Sunday, December 2, 12
The Reviews Are In!




Sunday, December 2, 12
The Reviews Are In!




Sunday, December 2, 12
The Reviews Are In!




Sunday, December 2, 12
Legitimate copies!
                   • Amazon (paper or Kindle)
                   • Barnes & Noble (paper or Nook)
                   • Apple (iBooks)
                   • Direct from InformIT (paper, eBook [.epub
                         + .mobi + .pdf], or Bundle)
                         • 35% off with code COREAUDIO3174
Sunday, December 2, 12
What You’ll Learn

                   • What Core Audio does and doesn’t do
                   • When to use and not use it
                   • What’s new in Core Audio for iOS 6


Sunday, December 2, 12
Sunday, December 2, 12
Simple things should be simple,
                         complex things should be possible.
                                      –Alan Kay




Sunday, December 2, 12
AV Foundation,
      Media Player

                           Simple things should be simple,
                         complex things should be possible.
                                      –Alan Kay




Sunday, December 2, 12
AV Foundation,
      Media Player

                           Simple things should be simple,
                         complex things should be possible.
                                      –Alan Kay
                                                   Core Audio




Sunday, December 2, 12
Core Audio

                   • Low-level C framework for processing
                         audio
                         • Capture, play-out, real-time or off-line
                           processing
                   • The “complex things should be possible”
                         part of audio on OS X and iOS



Sunday, December 2, 12
Chris’ CA Taxonomy
                   • Engines: process streams of audio
                    • Capture, play-out, mixing, effects
                          processing
                   • Helpers: deal with formats, encodings, etc.
                    • File I/O, stream I/O, format conversion,
                          iOS “session” management


Sunday, December 2, 12
Helpers: Audio File

                   • Read from / write to multiple audio file
                         types (.aiff, .wav, .caf, .m4a, .mp3) in a
                         content-agnostic way
                   • Get metadata (data format, duration,
                         iTunes/ID3 info)




Sunday, December 2, 12
Helpers: Audio File
                                Stream

                   • Read audio from non-random-access
                         source like a network stream
                   • Discover encoding and encapsulation on
                         the fly, then deliver audio packets to client
                         application




Sunday, December 2, 12
Helpers: Converters

                   • Convert buffers of audio to and from
                         different encodings
                   • One side must be in an uncompressed
                         format (i.e., Linear PCM)




Sunday, December 2, 12
Helpers: ExtAudioFile

                   • Combine file I/O and format conversion
                   • Read a compressed file into PCM buffers
                   • Write PCM buffers into a compressed file


Sunday, December 2, 12
Helpers: Audio Session
                   • iOS-only API to negotiate use of audio
                         resources with the rest of the system
                   • Deetermine whether your app mixes with
                         other apps’ audio, honors ring/silent
                         switch, can play in background, etc.
                   • Gets notified of audio interruptions
                   • See also AVAudioSession
Sunday, December 2, 12
Engines: Audio Units

                   • Low-latency (~10ms) processing of
                         capture/play-out audio data
                   • Effects, mixing, etc.
                   • Connect units manually or via an AUGraph
                   • Much more on this topic momentarily…

Sunday, December 2, 12
Engines: Audio Queue
                   • Convenience API for recording or play-out,
                         built atop audio units
                   • Rather than processing on-demand and on
                         Core Audio’s thread, your callback provides
                         or receives buffers of audio (at whatever size
                         is convenient to you)
                   • Higher latency, naturally
                   • Supports compressed formats (MP3, AAC)
Sunday, December 2, 12
Engines: Open AL

                   • API for 3D spatialized audio, implemented
                         atop audio units
                   • Set a source’s properties (x/y/z
                         coordinates, orientation, audio buffer, etc.),
                         OpenAL renders what it sounds like to the
                         listener from that location



Sunday, December 2, 12
Engines and Helpers
                   •     Audio Units   •   Audio File

                   •     Audio Queue   •   Audio File Stream

                   •     Open AL       •   Audio Converter

                                       •   ExtAudioFile

                                       •   Audio Session




Sunday, December 2, 12
Audio Units



Sunday, December 2, 12
Audio Unit


                           AUSomething




Sunday, December 2, 12
Types of Audio Units
                   • Output (which also do input)
                   • Generator
                   • Converter
                   • Effect
                   • Mixer
                   • Music
Sunday, December 2, 12
Pull Model


                          AUSomething




Sunday, December 2, 12
Pull Model


                          AUSomething
                                        AudioUnitRender()




Sunday, December 2, 12
Pull Model



                         AUSomethingElse   AUSomething




Sunday, December 2, 12
Buses (aka, Elements)

                            AUSomethingElse




                                              AUSomething




                            AUSomethingElse




Sunday, December 2, 12
AUGraph

                         AUSomethingElse




                                           AUSomething




                         AUSomethingElse




Sunday, December 2, 12
Render Callbacks
                OSStatus converterInputRenderCallback (void *inRefCon,
                                                        AudioUnitRenderActionFlags *ioActionFlags,
                                                        const AudioTimeStamp *inTimeStamp,
                                                        UInt32 inBusNumber,
                                                        UInt32 inNumberFrames,
                                                        AudioBufferList * ioData) {
                       CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inRefCon;

                         // read from buffer
                         ioData->mBuffers[0].mData = player.preRenderData;

                         return noErr;
                }



                                                                                                     AUSomething




                                                                             AUSomethingElse




Sunday, December 2, 12
AURemoteIO
                   • Output unit used for play-out, capture
                   • A Core Audio thread repeatedly and
                         automatically calls AudioUnitRender()
                   • Must set EnableIO property to explicitly
                         enable capture and/or play-out
                         • Capture requires setting appropriate
                           AudioSession category


Sunday, December 2, 12
Create AURemoteIO
      CheckError(NewAUGraph(&_auGraph),
      ! !     "couldn't create au graph");
      !
      CheckError(AUGraphOpen(_auGraph),
      ! !     "couldn't open au graph");
      !
      AudioComponentDescription componentDesc;
      componentDesc.componentType = kAudioUnitType_Output;
      componentDesc.componentSubType = kAudioUnitSubType_RemoteIO;
      componentDesc.componentManufacturer =
                   kAudioUnitManufacturer_Apple;
      !
      AUNode remoteIONode;
      CheckError(AUGraphAddNode(_auGraph,
      ! ! ! ! ! !      &componentDesc,
      ! ! ! ! ! !      &remoteIONode),
      ! !     "couldn't add remote io node");



Sunday, December 2, 12
Getting an AudioUnit
                            from AUNode

                !    CheckError(AUGraphNodeInfo(self.auGraph,
                !    ! ! ! ! ! !       remoteIONode,
                !    ! ! ! ! ! !       NULL,
                !    ! ! ! ! ! !       &_remoteIOUnit),
                !    ! !     "couldn't get remote io unit from node");




Sunday, December 2, 12
AURemoteIO Buses


                              AURemoteIO




Sunday, December 2, 12
AURemoteIO Buses


                              AURemoteIO
                                                bus 0
                                           to output H/W




Sunday, December 2, 12
AURemoteIO Buses


                              AURemoteIO
        bus 0                                   bus 0
      from app                             to output H/W




Sunday, December 2, 12
AURemoteIO Buses

     bus 1
from input H/W
                              AURemoteIO
        bus 0                                   bus 0
      from app                             to output H/W




Sunday, December 2, 12
AURemoteIO Buses

     bus 1                                     bus 1
from input H/W                                to app
                              AURemoteIO
        bus 0                                   bus 0
      from app                             to output H/W




Sunday, December 2, 12
EnableIO
         !    UInt32 oneFlag = 1;
         !    UInt32 busZero = 0;
         !    CheckError(AudioUnitSetProperty(self.remoteIOUnit,
         !    ! ! ! ! ! ! ! ! kAudioOutputUnitProperty_EnableIO,
         !    ! ! ! ! ! ! ! ! kAudioUnitScope_Output,
         !    ! ! ! ! ! ! ! ! busZero,
         !    ! ! ! ! ! ! ! ! &oneFlag,
         !    ! ! ! ! ! ! ! ! sizeof(oneFlag)),
         !    ! !     "couldn't enable remote io output");
         !    UInt32 busOne = 1;
         !    CheckError(AudioUnitSetProperty(self.remoteIOUnit,
         !    ! ! ! ! ! ! ! ! kAudioOutputUnitProperty_EnableIO,
         !    ! ! ! ! ! ! ! ! kAudioUnitScope_Input,
         !    ! ! ! ! ! ! ! ! busOne,
         !    ! ! ! ! ! ! ! ! &oneFlag,
         !    ! ! ! ! ! ! ! ! sizeof(oneFlag)),
         !    ! !     "couldn't enable remote io input");



Sunday, December 2, 12
Pass Through

                              bus 1
                         from input H/W
                                          AURemoteIO
                                                            bus 0
                                                       to output H/W




Sunday, December 2, 12
Connect In to Out
            !    UInt32 busZero = 0;
            !    UInt32 busOne = 1;
            !    CheckError(AUGraphConnectNodeInput(self.auGraph,
            !    ! ! ! ! ! ! ! !        remoteIONode,
            !    ! ! ! ! ! ! ! !        busOne,
            !    ! ! ! ! ! ! ! !        remoteIONode,
            !    ! ! ! ! ! ! ! !        busZero),
            !    ! !     "couldn't connect remote io bus 1 to 0");




Sunday, December 2, 12
Pass-Through with Effect

                                           AUEffect




                              bus 1
                         from input H/W
                                          AURemoteIO
                                                            bus 0
                                                       to output H/W



Sunday, December 2, 12
Demo: Delay Effect
                               New in iOS 6!




Sunday, December 2, 12
Creating the AUDelay
      ! componentDesc.componentType = kAudioUnitType_Effect;
      ! componentDesc.componentSubType = kAudioUnitSubType_Delay;
      ! componentDesc.componentManufacturer =
                 kAudioUnitManufacturer_Apple;
      !
      ! AUNode effectNode;
      ! CheckError(AUGraphAddNode(self.auGraph,
      ! ! ! ! ! ! !      &componentDesc,
      ! ! ! ! ! ! !      &effectNode),
      ! ! !     "couldn't create effect node");
      ! AudioUnit effectUnit;
      ! CheckError(AUGraphNodeInfo(self.auGraph,
      ! ! ! ! ! ! !        effectNode,
      ! ! ! ! ! ! !        NULL,
      ! ! ! ! ! ! !        &effectUnit),
      ! ! !     "couldn't get effect unit from node");



Sunday, December 2, 12
The problem with effect
                           units
                   • Audio Units available since iPhone OS 2.0
                         prefer int formats
                   • Effect units arrived with iOS 5 (arm7 era)
                         and only work with float format
                   • Have to set the AUEffect unit’s format on
                         AURemoteIO



Sunday, December 2, 12
Setting formats
       !    AudioStreamBasicDescription effectDataFormat;
       !    UInt32 propSize = sizeof (effectDataFormat);
       !    CheckError(AudioUnitGetProperty(effectUnit,
       !    ! ! ! ! ! ! ! ! kAudioUnitProperty_StreamFormat,
       !    ! ! ! ! ! ! ! ! kAudioUnitScope_Output,
       !    ! ! ! ! ! ! ! ! busZero,
       !    ! ! ! ! ! ! ! ! &effectDataFormat,
       !    ! ! ! ! ! ! ! ! &propSize),
       !    ! !     "couldn't read effect format");
       !    CheckError(AudioUnitSetProperty(self.remoteIOUnit,
       !    ! ! ! ! ! ! ! ! kAudioUnitProperty_StreamFormat,
       !    ! ! ! ! ! ! ! ! kAudioUnitScope_Output,
       !    ! ! ! ! ! ! ! ! busOne,
       !    ! ! ! ! ! ! ! ! &effectDataFormat,
       !    ! ! ! ! ! ! ! ! propSize),
       !    ! !     "couldn't set bus one output format");

           Then repeat AudioUnitSetProperty() for input scope / bus 0
Sunday, December 2, 12
AUNewTimePitch

                   • New in iOS 6!
                   • Allows you to change pitch independent of
                         time, or time independent of pitch
                   • How do you use it?


Sunday, December 2, 12
AUTimePitch
   !   AudioComponentDescription effectcd = {0};
   !   effectcd.componentType = kAudioUnitType_FormatConverter;
   !   effectcd.componentSubType = kAudioUnitSubType_NewTimePitch;
   !   effectcd.componentManufacturer = kAudioUnitManufacturer_Apple;
   !
   !   AUNode effectNode;
   !   CheckError(AUGraphAddNode(self.auGraph,
   !   ! ! ! ! ! !       &effectcd,
   !   ! ! ! ! ! !       &effectNode),
   !   ! !      "couldn't get effect node [time/pitch]");




        Notice the type is AUFormatConverter, not AUEffect
Sunday, December 2, 12
AudioUnitParameters.h
                  // Parameters for AUNewTimePitch
                  enum {
                  ! ! // Global, rate, 1/32 -> 32.0, 1.0
                  ! kNewTimePitchParam_Rate! ! ! ! ! ! =
                                           !                  0,
                  ! ! // Global, Cents, -2400 -> 2400, 1.0
                  ! kNewTimePitchParam_Pitch! ! ! ! ! ! =     1,
                  ! ! // Global, generic, 3.0 -> 32.0, 8.0
                  ! kNewTimePitchParam_Overlap! ! ! ! ! !     = 4,
                  ! ! // Global, Boolean, 0->1, 1
                  ! kNewTimePitchParam_EnablePeakLocking! !   ! = 6
                  };



  This is the entire documentation for the AUNewTimePitch parameters


Sunday, December 2, 12
AUNewTimePitch
                              parameters
                   • Rate: kNewTimePitchParam_Rate takes a
                         Float32 rate from 1/32 speed to 32x
                         speed.
                         • Use powers of 2: 1/32, 1/16, …, 2, 4, 8…
                   • Pitch: kNewTimePitchParam_Pitch takes
                         a Float32 representing cents, meaning
                         1/100 of a musical semitone


Sunday, December 2, 12
Pitch shifting


                   • Pitch can vary, time does not
                   • Suitable for real-time sources, such as audio
                         capture




Sunday, December 2, 12
Demo: Pitch Shift
                              New in iOS 6!




Sunday, December 2, 12
Rate shifting
                   • Rate can vary, pitch does not
                    • Think of 1.5x and 2x speed modes in
                           Podcasts app
                   • Not suitable for real-time sources, as data
                         will be consumed faster. Files work well.
                         • Sources must be able to map time
                           systems with
                           kAudioUnitProperty_InputSamplesInOutput


Sunday, December 2, 12
Demo: Rate Shift
                              New in iOS 6!




Sunday, December 2, 12
AUSplitter

                                            AUSomethingElse




                         AUSplitter



                                            AUSomethingElse




                                  New in iOS 6!
Sunday, December 2, 12
AUMatrixMixer
                         AUSomethingElse



                                                              AUSomethingElse




                         AUSomethingElse      AUMatrixMixer



                                                              AUSomethingElse




                         AUSomethingElse




                                           New in iOS 6!
Sunday, December 2, 12
Audio Queues
                    (and the APIs that help them)




Sunday, December 2, 12
AudioQueue
                   • Easier than AURemoteIO - provide data
                         when you want to, less time pressure, can
                         accept or provide compressed formats
                         (MP3, AAC)
                   • Recording queue - receive buffers of
                         captured audio in a callback
                   • Play-out queue - enqueue buffers of audio
                         to play, optionally refill in a callback


Sunday, December 2, 12
AudioQueue


                            2   1   0




Sunday, December 2, 12
Common AQ scenarios
                   • File player - Read from file and “prime”
                         queue buffers, start queue, when called
                         back with used buffer, refill from next part
                         of file
                   • Synthesis - Maintain state in your own
                         code, write raw samples into buffers during
                         callbacks


Sunday, December 2, 12
Web Radio

                   • Thursday class’ third project
                   • Use Audio File Stream Services to pick out
                         audio data from a network stream
                   • Enqueue these packets as new AQ buffers
                   • Dispose used buffers in callback

Sunday, December 2, 12
Parsing web radio




Sunday, December 2, 12
Parsing web radio
   NSURLConnection delivers
   NSData buffers, containing audio
   and framing info. We pass it to              NSData                 NSData
   Audio File Services.               Packets      Packets   Packets   Packets   Packets




Sunday, December 2, 12
Parsing web radio
   NSURLConnection delivers
   NSData buffers, containing audio
   and framing info. We pass it to                NSData                         NSData
   Audio File Services.                 Packets        Packets         Packets   Packets   Packets




                                        Packets   Packets
   Audio File Services calls us back
   with parsed packets of audio data.   Packets   Packets    Packets




Sunday, December 2, 12
Parsing web radio
   NSURLConnection delivers
   NSData buffers, containing audio
   and framing info. We pass it to                NSData                                  NSData
   Audio File Services.                 Packets        Packets              Packets       Packets   Packets




                                        Packets   Packets
   Audio File Services calls us back
   with parsed packets of audio data.   Packets   Packets       Packets




 We create an AudioQueueBuffer
                                                   Packets                      Packets
 with those packets and enqueue it                   Packets
                                                       2          Packets
                                                                    1              0
 for play-out.
                                                      Packets                   Packets




Sunday, December 2, 12
A complex thing!

                   • What if we want to see that data after it’s
                         been decoded to PCM and is about to be
                         played?
                         • e.g., spectrum analysis, effects, visualizers
                   • AudioQueue design is “fire-and-forget”

Sunday, December 2, 12
AudioQueue Tap!




                         http://www.last.fm/music/Spinal+Tap
Sunday, December 2, 12
AudioQueueProcessingTap

                   • Set as a property on the Audio Queue
                   • Calls back to your function with decoded
                         (PCM) audio data
                   • Three types: pre- or post- effects (that the
                         AQ performs), or siphon. First two can
                         modify the data.
                   • Only documentation is in AudioQueue.h
Sunday, December 2, 12
Creating an AQ Tap
   !    !      // create the tap
   !    !      UInt32 maxFrames = 0;
   !    !      AudioStreamBasicDescription tapFormat = {0};
   !    !      AudioQueueProcessingTapRef tapRef;
   !    !      CheckError(AudioQueueProcessingTapNew(audioQueue,
   !    !      ! ! ! ! ! ! ! ! !       tapProc,
   !    !      ! ! ! ! ! ! ! ! !       (__bridge void *)(player),
   !    !      ! ! ! ! ! ! ! ! !       kAudioQueueProcessingTap_PreEffects,
   !    !      ! ! ! ! ! ! ! ! !       &maxFrames,
   !    !      ! ! ! ! ! ! ! ! !       &tapFormat,
   !    !      ! ! ! ! ! ! ! ! !       &tapRef),
   !    !      ! !     "couldn't create AQ tap");



            Notice that you receive maxFrames and tapFormat. These do not appear to be settable.


Sunday, December 2, 12
AQ Tap Proc
       void tapProc (void *                            inClientData,
       ! ! !     AudioQueueProcessingTapRef       inAQTap,
       ! ! !     UInt32                           inNumberFrames,
       ! ! !     AudioTimeStamp *                 ioTimeStamp,
       ! ! !     UInt32 *                         ioFlags,
       ! ! !     UInt32 *                         outNumberFrames,
       ! ! !     AudioBufferList *                ioData) {
       ! CCFWebRadioPlayer *player =
               (__bridge CCFWebRadioPlayer*) inClientData;
       ! UInt32 getSourceFlags = 0;
       ! UInt32 getSourceFrames = 0;
       ! AudioQueueProcessingTapGetSourceAudio(inAQTap,
       ! ! ! ! ! ! ! ! ! !         inNumberFrames,
       ! ! ! ! ! ! ! ! ! !         ioTimeStamp,
       ! ! ! ! ! ! ! ! ! !         &getSourceFlags,
       ! ! ! ! ! ! ! ! ! !         &getSourceFrames,
       ! ! ! ! ! ! ! ! ! !         ioData);
         // then do something with ioData
         // ...
Sunday, December 2, 12
So what should we do
                            with the audio?




Sunday, December 2, 12
So what should we do
                            with the audio?


                           Let’s apply our pitch-shift effect




Sunday, December 2, 12
Shouldn’t this work?


                                AUEffect




Sunday, December 2, 12
Shouldn’t this work?


                                AUEffect
                                           AudioUnitRender()




Sunday, December 2, 12
AudioUnitRender()
                   • Last argument is an AudioBufferList, whose
                         AudioBuffer members have mData pointers
                         • If mData != NULL, audio unit does its
                           thing with those samples
                         • If mData == NULL, audio data pulls from
                           whatever it’s connected to
                   • So we just call with AudioBufferList ioData
                         we got from tap callback, right?


Sunday, December 2, 12
Psych!

                   • AQ tap provides data as signed ints
                   • Effect units only work with floating point
                   • We need to do an on-the-spot format
                         conversion




Sunday, December 2, 12
invalidname’s convert-
                            and-effect recipe
                          OSStatus converterInputRenderCallback (void *inRefCon,
                                                                  AudioUnitRenderActionFlags *ioActionFlags,
                                                                  const AudioTimeStamp *inTimeStamp,
                                                                  UInt32 inBusNumber,
                                                                  UInt32 inNumberFrames,
                                                                  AudioBufferList * ioData) {
                                 CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inRefCon;

                                // read from buffer
                                ioData->mBuffers[0].mData = player.preRenderData;

                                return noErr;
                          }




                                   AUConverter                               AUEffect                          AUConverter   AUGenericOutput




               Note: red arrows are float format, yellow arrows are int

Sunday, December 2, 12
How it works

                   • AUGraph: AUConverter → AUEffect →
                         AUConverter → AUGenericOutput
                   • Top AUConverter is connected to a render
                         callback function




Sunday, December 2, 12
The trick!
                   • Copy mData pointer to a state variable and
                         NULL it in ioData
                   • Call AudioQueueRender() on output unit.
                         The NULL makes it pull from the graph.
                   • Top of the graph pulls on render callback,
                         which gives it back the mData we copied
                         off.


Sunday, December 2, 12
Yes, really
                         This is the rest of tapProc()
               ! // copy off the ioData so the graph can read from it
                 // in render callback
               ! player.preRenderData = ioData->mBuffers[0].mData;
               ! ioData->mBuffers[0].mData = NULL;
               !
               ! OSStatus renderErr = noErr;
               ! AudioUnitRenderActionFlags actionFlags = 0;
               ! renderErr = AudioUnitRender(player.genericOutputUnit,
               ! ! ! ! ! ! ! ! &actionFlags,
               ! ! ! ! ! ! ! ! player.renderTimeStamp,
               ! ! ! ! ! ! ! ! 0,
               ! ! ! ! ! ! ! ! inNumberFrames,
               ! ! ! ! ! ! ! ! ioData);
               ! NSLog (@"AudioUnitRender, renderErr = %ld",renderErr);
               }
Sunday, December 2, 12
Yes, really
           This is the render callback that supplies data to the int→float converter

    OSStatus converterInputRenderCallback (void *inRefCon,
    ! ! ! ! ! ! ! ! !        AudioUnitRenderActionFlags *ioActionFlags,
    ! ! ! ! ! ! ! ! !        const AudioTimeStamp *inTimeStamp,
    ! ! ! ! ! ! ! ! !        UInt32 inBusNumber,
    ! ! ! ! ! ! ! ! !        UInt32 inNumberFrames,
    ! ! ! ! ! ! ! ! !        AudioBufferList * ioData) {
    ! CCFWebRadioPlayer *player =
                   (__bridge CCFWebRadioPlayer*) inRefCon;
    !
    ! // read from buffer
    ! ioData->mBuffers[0].mData = player.preRenderData;

    ! return noErr;
    }


Sunday, December 2, 12
Demo: AQ Tap +
                         AUNewTimePitch
                              New in iOS 6!




Sunday, December 2, 12
Sunday, December 2, 12
Other new stuff



Sunday, December 2, 12
Multi-Route
                   • Ordinarily, one input or output is active:
                         earpiece, speaker, headphones, dock-
                         connected device
                         • “Last in wins”
                   • With AV Session “multi-route” category,
                         you can use several at once
                   • WWDC 2012 session 505
Sunday, December 2, 12
Utility classes moved
                                 again
                   • C++ utilities, including the CARingBuffer
                    • < Xcode 4.3, installed into /Developer
                    • Xcode 4.3-4.4, optional download from
                           developer.apple.com
                         • ≧ Xcode 4.5, sample code project “Core
                           Audio Utility Classes”


Sunday, December 2, 12
Takeaways
                   • Core Audio fundamentals never change
                   • New stuff is added as properties, typedefs,
                         enums, etc.
                   • Watch the SDK API diffs document to find
                         the new stuff
                   • Hope you like header files and
                         experimentation


Sunday, December 2, 12
Q&A
                   • Slides will be posted to slideshare.net/
                         invalidname
                   • Code will be linked from there and my blog
                   • Watch CocoaConf RDU glassboard,
                         @invalidname on Twitter/ADN, or [Time
                         code]; blog for announcement
                   • Thanks!
Sunday, December 2, 12

More Related Content

Similar to Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)

Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Chris Adamson
 
Interfaces Inteligentes para Android
Interfaces Inteligentes para AndroidInterfaces Inteligentes para Android
Interfaces Inteligentes para AndroidNelson Glauber Leal
 
Creating Killer content
Creating Killer contentCreating Killer content
Creating Killer contentMike Henderson
 
Zookeeper at the bigdata roundtable
Zookeeper at the bigdata roundtableZookeeper at the bigdata roundtable
Zookeeper at the bigdata roundtableTobias Schlottke
 
Sound recording glossary - IMPROVED
Sound recording glossary - IMPROVEDSound recording glossary - IMPROVED
Sound recording glossary - IMPROVEDPaulinaKucharska
 
Producing a Killer Podcast
Producing a Killer PodcastProducing a Killer Podcast
Producing a Killer PodcastEric Andrade
 
The Next-Gen Dynamic Sound System of Killzone Shadow Fall
The Next-Gen Dynamic Sound System of Killzone Shadow FallThe Next-Gen Dynamic Sound System of Killzone Shadow Fall
The Next-Gen Dynamic Sound System of Killzone Shadow FallGuerrilla
 
Image and Music: Processing plus Pure Data with libpd library
Image and Music: Processing plus Pure Data with libpd libraryImage and Music: Processing plus Pure Data with libpd library
Image and Music: Processing plus Pure Data with libpd libraryPETER KIRN
 

Similar to Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12) (9)

Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)
 
Interfaces Inteligentes para Android
Interfaces Inteligentes para AndroidInterfaces Inteligentes para Android
Interfaces Inteligentes para Android
 
Creating Killer content
Creating Killer contentCreating Killer content
Creating Killer content
 
Zookeeper at the bigdata roundtable
Zookeeper at the bigdata roundtableZookeeper at the bigdata roundtable
Zookeeper at the bigdata roundtable
 
Sound recording glossary - IMPROVED
Sound recording glossary - IMPROVEDSound recording glossary - IMPROVED
Sound recording glossary - IMPROVED
 
Producing a Killer Podcast
Producing a Killer PodcastProducing a Killer Podcast
Producing a Killer Podcast
 
The Next-Gen Dynamic Sound System of Killzone Shadow Fall
The Next-Gen Dynamic Sound System of Killzone Shadow FallThe Next-Gen Dynamic Sound System of Killzone Shadow Fall
The Next-Gen Dynamic Sound System of Killzone Shadow Fall
 
Image and Music: Processing plus Pure Data with libpd library
Image and Music: Processing plus Pure Data with libpd libraryImage and Music: Processing plus Pure Data with libpd library
Image and Music: Processing plus Pure Data with libpd library
 
iOS & Arduino
iOS & ArduinoiOS & Arduino
iOS & Arduino
 

More from Chris Adamson

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Chris Adamson
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Chris Adamson
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Chris Adamson
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Chris Adamson
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineChris Adamson
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineChris Adamson
 
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Chris Adamson
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Chris Adamson
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Chris Adamson
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Chris Adamson
 
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Chris Adamson
 
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Chris Adamson
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Chris Adamson
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Chris Adamson
 
Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Chris Adamson
 
Stupid Video Tricks, CocoaConf Las Vegas
Stupid Video Tricks, CocoaConf Las VegasStupid Video Tricks, CocoaConf Las Vegas
Stupid Video Tricks, CocoaConf Las VegasChris Adamson
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Chris Adamson
 
Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Chris Adamson
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDKChris Adamson
 

More from Chris Adamson (20)

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
 
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
 
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
 
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
 
Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014
 
Stupid Video Tricks, CocoaConf Las Vegas
Stupid Video Tricks, CocoaConf Las VegasStupid Video Tricks, CocoaConf Las Vegas
Stupid Video Tricks, CocoaConf Las Vegas
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
 
Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)
 
Stupid Video Tricks
Stupid Video TricksStupid Video Tricks
Stupid Video Tricks
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDK
 

Recently uploaded

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 

Recently uploaded (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 

Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)

  • 1. Core Audio in iOS 6 Chris Adamson • @invalidname CocoaConf Raleigh December 1, 2012 Sides and code available on my blog: http://www.subfurther.com/blog Sunday, December 2, 12
  • 3. The Reviews Are In! Sunday, December 2, 12
  • 4. The Reviews Are In! Sunday, December 2, 12
  • 5. The Reviews Are In! Sunday, December 2, 12
  • 6. The Reviews Are In! Sunday, December 2, 12
  • 7. Legitimate copies! • Amazon (paper or Kindle) • Barnes & Noble (paper or Nook) • Apple (iBooks) • Direct from InformIT (paper, eBook [.epub + .mobi + .pdf], or Bundle) • 35% off with code COREAUDIO3174 Sunday, December 2, 12
  • 8. What You’ll Learn • What Core Audio does and doesn’t do • When to use and not use it • What’s new in Core Audio for iOS 6 Sunday, December 2, 12
  • 10. Simple things should be simple, complex things should be possible. –Alan Kay Sunday, December 2, 12
  • 11. AV Foundation, Media Player Simple things should be simple, complex things should be possible. –Alan Kay Sunday, December 2, 12
  • 12. AV Foundation, Media Player Simple things should be simple, complex things should be possible. –Alan Kay Core Audio Sunday, December 2, 12
  • 13. Core Audio • Low-level C framework for processing audio • Capture, play-out, real-time or off-line processing • The “complex things should be possible” part of audio on OS X and iOS Sunday, December 2, 12
  • 14. Chris’ CA Taxonomy • Engines: process streams of audio • Capture, play-out, mixing, effects processing • Helpers: deal with formats, encodings, etc. • File I/O, stream I/O, format conversion, iOS “session” management Sunday, December 2, 12
  • 15. Helpers: Audio File • Read from / write to multiple audio file types (.aiff, .wav, .caf, .m4a, .mp3) in a content-agnostic way • Get metadata (data format, duration, iTunes/ID3 info) Sunday, December 2, 12
  • 16. Helpers: Audio File Stream • Read audio from non-random-access source like a network stream • Discover encoding and encapsulation on the fly, then deliver audio packets to client application Sunday, December 2, 12
  • 17. Helpers: Converters • Convert buffers of audio to and from different encodings • One side must be in an uncompressed format (i.e., Linear PCM) Sunday, December 2, 12
  • 18. Helpers: ExtAudioFile • Combine file I/O and format conversion • Read a compressed file into PCM buffers • Write PCM buffers into a compressed file Sunday, December 2, 12
  • 19. Helpers: Audio Session • iOS-only API to negotiate use of audio resources with the rest of the system • Deetermine whether your app mixes with other apps’ audio, honors ring/silent switch, can play in background, etc. • Gets notified of audio interruptions • See also AVAudioSession Sunday, December 2, 12
  • 20. Engines: Audio Units • Low-latency (~10ms) processing of capture/play-out audio data • Effects, mixing, etc. • Connect units manually or via an AUGraph • Much more on this topic momentarily… Sunday, December 2, 12
  • 21. Engines: Audio Queue • Convenience API for recording or play-out, built atop audio units • Rather than processing on-demand and on Core Audio’s thread, your callback provides or receives buffers of audio (at whatever size is convenient to you) • Higher latency, naturally • Supports compressed formats (MP3, AAC) Sunday, December 2, 12
  • 22. Engines: Open AL • API for 3D spatialized audio, implemented atop audio units • Set a source’s properties (x/y/z coordinates, orientation, audio buffer, etc.), OpenAL renders what it sounds like to the listener from that location Sunday, December 2, 12
  • 23. Engines and Helpers • Audio Units • Audio File • Audio Queue • Audio File Stream • Open AL • Audio Converter • ExtAudioFile • Audio Session Sunday, December 2, 12
  • 25. Audio Unit AUSomething Sunday, December 2, 12
  • 26. Types of Audio Units • Output (which also do input) • Generator • Converter • Effect • Mixer • Music Sunday, December 2, 12
  • 27. Pull Model AUSomething Sunday, December 2, 12
  • 28. Pull Model AUSomething AudioUnitRender() Sunday, December 2, 12
  • 29. Pull Model AUSomethingElse AUSomething Sunday, December 2, 12
  • 30. Buses (aka, Elements) AUSomethingElse AUSomething AUSomethingElse Sunday, December 2, 12
  • 31. AUGraph AUSomethingElse AUSomething AUSomethingElse Sunday, December 2, 12
  • 32. Render Callbacks OSStatus converterInputRenderCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData) { CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inRefCon; // read from buffer ioData->mBuffers[0].mData = player.preRenderData; return noErr; } AUSomething AUSomethingElse Sunday, December 2, 12
  • 33. AURemoteIO • Output unit used for play-out, capture • A Core Audio thread repeatedly and automatically calls AudioUnitRender() • Must set EnableIO property to explicitly enable capture and/or play-out • Capture requires setting appropriate AudioSession category Sunday, December 2, 12
  • 34. Create AURemoteIO CheckError(NewAUGraph(&_auGraph), ! ! "couldn't create au graph"); ! CheckError(AUGraphOpen(_auGraph), ! ! "couldn't open au graph"); ! AudioComponentDescription componentDesc; componentDesc.componentType = kAudioUnitType_Output; componentDesc.componentSubType = kAudioUnitSubType_RemoteIO; componentDesc.componentManufacturer = kAudioUnitManufacturer_Apple; ! AUNode remoteIONode; CheckError(AUGraphAddNode(_auGraph, ! ! ! ! ! ! &componentDesc, ! ! ! ! ! ! &remoteIONode), ! ! "couldn't add remote io node"); Sunday, December 2, 12
  • 35. Getting an AudioUnit from AUNode ! CheckError(AUGraphNodeInfo(self.auGraph, ! ! ! ! ! ! ! remoteIONode, ! ! ! ! ! ! ! NULL, ! ! ! ! ! ! ! &_remoteIOUnit), ! ! ! "couldn't get remote io unit from node"); Sunday, December 2, 12
  • 36. AURemoteIO Buses AURemoteIO Sunday, December 2, 12
  • 37. AURemoteIO Buses AURemoteIO bus 0 to output H/W Sunday, December 2, 12
  • 38. AURemoteIO Buses AURemoteIO bus 0 bus 0 from app to output H/W Sunday, December 2, 12
  • 39. AURemoteIO Buses bus 1 from input H/W AURemoteIO bus 0 bus 0 from app to output H/W Sunday, December 2, 12
  • 40. AURemoteIO Buses bus 1 bus 1 from input H/W to app AURemoteIO bus 0 bus 0 from app to output H/W Sunday, December 2, 12
  • 41. EnableIO ! UInt32 oneFlag = 1; ! UInt32 busZero = 0; ! CheckError(AudioUnitSetProperty(self.remoteIOUnit, ! ! ! ! ! ! ! ! ! kAudioOutputUnitProperty_EnableIO, ! ! ! ! ! ! ! ! ! kAudioUnitScope_Output, ! ! ! ! ! ! ! ! ! busZero, ! ! ! ! ! ! ! ! ! &oneFlag, ! ! ! ! ! ! ! ! ! sizeof(oneFlag)), ! ! ! "couldn't enable remote io output"); ! UInt32 busOne = 1; ! CheckError(AudioUnitSetProperty(self.remoteIOUnit, ! ! ! ! ! ! ! ! ! kAudioOutputUnitProperty_EnableIO, ! ! ! ! ! ! ! ! ! kAudioUnitScope_Input, ! ! ! ! ! ! ! ! ! busOne, ! ! ! ! ! ! ! ! ! &oneFlag, ! ! ! ! ! ! ! ! ! sizeof(oneFlag)), ! ! ! "couldn't enable remote io input"); Sunday, December 2, 12
  • 42. Pass Through bus 1 from input H/W AURemoteIO bus 0 to output H/W Sunday, December 2, 12
  • 43. Connect In to Out ! UInt32 busZero = 0; ! UInt32 busOne = 1; ! CheckError(AUGraphConnectNodeInput(self.auGraph, ! ! ! ! ! ! ! ! ! remoteIONode, ! ! ! ! ! ! ! ! ! busOne, ! ! ! ! ! ! ! ! ! remoteIONode, ! ! ! ! ! ! ! ! ! busZero), ! ! ! "couldn't connect remote io bus 1 to 0"); Sunday, December 2, 12
  • 44. Pass-Through with Effect AUEffect bus 1 from input H/W AURemoteIO bus 0 to output H/W Sunday, December 2, 12
  • 45. Demo: Delay Effect New in iOS 6! Sunday, December 2, 12
  • 46. Creating the AUDelay ! componentDesc.componentType = kAudioUnitType_Effect; ! componentDesc.componentSubType = kAudioUnitSubType_Delay; ! componentDesc.componentManufacturer = kAudioUnitManufacturer_Apple; ! ! AUNode effectNode; ! CheckError(AUGraphAddNode(self.auGraph, ! ! ! ! ! ! ! &componentDesc, ! ! ! ! ! ! ! &effectNode), ! ! ! "couldn't create effect node"); ! AudioUnit effectUnit; ! CheckError(AUGraphNodeInfo(self.auGraph, ! ! ! ! ! ! ! effectNode, ! ! ! ! ! ! ! NULL, ! ! ! ! ! ! ! &effectUnit), ! ! ! "couldn't get effect unit from node"); Sunday, December 2, 12
  • 47. The problem with effect units • Audio Units available since iPhone OS 2.0 prefer int formats • Effect units arrived with iOS 5 (arm7 era) and only work with float format • Have to set the AUEffect unit’s format on AURemoteIO Sunday, December 2, 12
  • 48. Setting formats ! AudioStreamBasicDescription effectDataFormat; ! UInt32 propSize = sizeof (effectDataFormat); ! CheckError(AudioUnitGetProperty(effectUnit, ! ! ! ! ! ! ! ! ! kAudioUnitProperty_StreamFormat, ! ! ! ! ! ! ! ! ! kAudioUnitScope_Output, ! ! ! ! ! ! ! ! ! busZero, ! ! ! ! ! ! ! ! ! &effectDataFormat, ! ! ! ! ! ! ! ! ! &propSize), ! ! ! "couldn't read effect format"); ! CheckError(AudioUnitSetProperty(self.remoteIOUnit, ! ! ! ! ! ! ! ! ! kAudioUnitProperty_StreamFormat, ! ! ! ! ! ! ! ! ! kAudioUnitScope_Output, ! ! ! ! ! ! ! ! ! busOne, ! ! ! ! ! ! ! ! ! &effectDataFormat, ! ! ! ! ! ! ! ! ! propSize), ! ! ! "couldn't set bus one output format"); Then repeat AudioUnitSetProperty() for input scope / bus 0 Sunday, December 2, 12
  • 49. AUNewTimePitch • New in iOS 6! • Allows you to change pitch independent of time, or time independent of pitch • How do you use it? Sunday, December 2, 12
  • 50. AUTimePitch ! AudioComponentDescription effectcd = {0}; ! effectcd.componentType = kAudioUnitType_FormatConverter; ! effectcd.componentSubType = kAudioUnitSubType_NewTimePitch; ! effectcd.componentManufacturer = kAudioUnitManufacturer_Apple; ! ! AUNode effectNode; ! CheckError(AUGraphAddNode(self.auGraph, ! ! ! ! ! ! ! &effectcd, ! ! ! ! ! ! ! &effectNode), ! ! ! "couldn't get effect node [time/pitch]"); Notice the type is AUFormatConverter, not AUEffect Sunday, December 2, 12
  • 51. AudioUnitParameters.h // Parameters for AUNewTimePitch enum { ! ! // Global, rate, 1/32 -> 32.0, 1.0 ! kNewTimePitchParam_Rate! ! ! ! ! ! = ! 0, ! ! // Global, Cents, -2400 -> 2400, 1.0 ! kNewTimePitchParam_Pitch! ! ! ! ! ! = 1, ! ! // Global, generic, 3.0 -> 32.0, 8.0 ! kNewTimePitchParam_Overlap! ! ! ! ! ! = 4, ! ! // Global, Boolean, 0->1, 1 ! kNewTimePitchParam_EnablePeakLocking! ! ! = 6 }; This is the entire documentation for the AUNewTimePitch parameters Sunday, December 2, 12
  • 52. AUNewTimePitch parameters • Rate: kNewTimePitchParam_Rate takes a Float32 rate from 1/32 speed to 32x speed. • Use powers of 2: 1/32, 1/16, …, 2, 4, 8… • Pitch: kNewTimePitchParam_Pitch takes a Float32 representing cents, meaning 1/100 of a musical semitone Sunday, December 2, 12
  • 53. Pitch shifting • Pitch can vary, time does not • Suitable for real-time sources, such as audio capture Sunday, December 2, 12
  • 54. Demo: Pitch Shift New in iOS 6! Sunday, December 2, 12
  • 55. Rate shifting • Rate can vary, pitch does not • Think of 1.5x and 2x speed modes in Podcasts app • Not suitable for real-time sources, as data will be consumed faster. Files work well. • Sources must be able to map time systems with kAudioUnitProperty_InputSamplesInOutput Sunday, December 2, 12
  • 56. Demo: Rate Shift New in iOS 6! Sunday, December 2, 12
  • 57. AUSplitter AUSomethingElse AUSplitter AUSomethingElse New in iOS 6! Sunday, December 2, 12
  • 58. AUMatrixMixer AUSomethingElse AUSomethingElse AUSomethingElse AUMatrixMixer AUSomethingElse AUSomethingElse New in iOS 6! Sunday, December 2, 12
  • 59. Audio Queues (and the APIs that help them) Sunday, December 2, 12
  • 60. AudioQueue • Easier than AURemoteIO - provide data when you want to, less time pressure, can accept or provide compressed formats (MP3, AAC) • Recording queue - receive buffers of captured audio in a callback • Play-out queue - enqueue buffers of audio to play, optionally refill in a callback Sunday, December 2, 12
  • 61. AudioQueue 2 1 0 Sunday, December 2, 12
  • 62. Common AQ scenarios • File player - Read from file and “prime” queue buffers, start queue, when called back with used buffer, refill from next part of file • Synthesis - Maintain state in your own code, write raw samples into buffers during callbacks Sunday, December 2, 12
  • 63. Web Radio • Thursday class’ third project • Use Audio File Stream Services to pick out audio data from a network stream • Enqueue these packets as new AQ buffers • Dispose used buffers in callback Sunday, December 2, 12
  • 64. Parsing web radio Sunday, December 2, 12
  • 65. Parsing web radio NSURLConnection delivers NSData buffers, containing audio and framing info. We pass it to NSData NSData Audio File Services. Packets Packets Packets Packets Packets Sunday, December 2, 12
  • 66. Parsing web radio NSURLConnection delivers NSData buffers, containing audio and framing info. We pass it to NSData NSData Audio File Services. Packets Packets Packets Packets Packets Packets Packets Audio File Services calls us back with parsed packets of audio data. Packets Packets Packets Sunday, December 2, 12
  • 67. Parsing web radio NSURLConnection delivers NSData buffers, containing audio and framing info. We pass it to NSData NSData Audio File Services. Packets Packets Packets Packets Packets Packets Packets Audio File Services calls us back with parsed packets of audio data. Packets Packets Packets We create an AudioQueueBuffer Packets Packets with those packets and enqueue it Packets 2 Packets 1 0 for play-out. Packets Packets Sunday, December 2, 12
  • 68. A complex thing! • What if we want to see that data after it’s been decoded to PCM and is about to be played? • e.g., spectrum analysis, effects, visualizers • AudioQueue design is “fire-and-forget” Sunday, December 2, 12
  • 69. AudioQueue Tap! http://www.last.fm/music/Spinal+Tap Sunday, December 2, 12
  • 70. AudioQueueProcessingTap • Set as a property on the Audio Queue • Calls back to your function with decoded (PCM) audio data • Three types: pre- or post- effects (that the AQ performs), or siphon. First two can modify the data. • Only documentation is in AudioQueue.h Sunday, December 2, 12
  • 71. Creating an AQ Tap ! ! // create the tap ! ! UInt32 maxFrames = 0; ! ! AudioStreamBasicDescription tapFormat = {0}; ! ! AudioQueueProcessingTapRef tapRef; ! ! CheckError(AudioQueueProcessingTapNew(audioQueue, ! ! ! ! ! ! ! ! ! ! ! tapProc, ! ! ! ! ! ! ! ! ! ! ! (__bridge void *)(player), ! ! ! ! ! ! ! ! ! ! ! kAudioQueueProcessingTap_PreEffects, ! ! ! ! ! ! ! ! ! ! ! &maxFrames, ! ! ! ! ! ! ! ! ! ! ! &tapFormat, ! ! ! ! ! ! ! ! ! ! ! &tapRef), ! ! ! ! "couldn't create AQ tap"); Notice that you receive maxFrames and tapFormat. These do not appear to be settable. Sunday, December 2, 12
  • 72. AQ Tap Proc void tapProc (void * inClientData, ! ! ! AudioQueueProcessingTapRef inAQTap, ! ! ! UInt32 inNumberFrames, ! ! ! AudioTimeStamp * ioTimeStamp, ! ! ! UInt32 * ioFlags, ! ! ! UInt32 * outNumberFrames, ! ! ! AudioBufferList * ioData) { ! CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inClientData; ! UInt32 getSourceFlags = 0; ! UInt32 getSourceFrames = 0; ! AudioQueueProcessingTapGetSourceAudio(inAQTap, ! ! ! ! ! ! ! ! ! ! inNumberFrames, ! ! ! ! ! ! ! ! ! ! ioTimeStamp, ! ! ! ! ! ! ! ! ! ! &getSourceFlags, ! ! ! ! ! ! ! ! ! ! &getSourceFrames, ! ! ! ! ! ! ! ! ! ! ioData); // then do something with ioData // ... Sunday, December 2, 12
  • 73. So what should we do with the audio? Sunday, December 2, 12
  • 74. So what should we do with the audio? Let’s apply our pitch-shift effect Sunday, December 2, 12
  • 75. Shouldn’t this work? AUEffect Sunday, December 2, 12
  • 76. Shouldn’t this work? AUEffect AudioUnitRender() Sunday, December 2, 12
  • 77. AudioUnitRender() • Last argument is an AudioBufferList, whose AudioBuffer members have mData pointers • If mData != NULL, audio unit does its thing with those samples • If mData == NULL, audio data pulls from whatever it’s connected to • So we just call with AudioBufferList ioData we got from tap callback, right? Sunday, December 2, 12
  • 78. Psych! • AQ tap provides data as signed ints • Effect units only work with floating point • We need to do an on-the-spot format conversion Sunday, December 2, 12
  • 79. invalidname’s convert- and-effect recipe OSStatus converterInputRenderCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData) { CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inRefCon; // read from buffer ioData->mBuffers[0].mData = player.preRenderData; return noErr; } AUConverter AUEffect AUConverter AUGenericOutput Note: red arrows are float format, yellow arrows are int Sunday, December 2, 12
  • 80. How it works • AUGraph: AUConverter → AUEffect → AUConverter → AUGenericOutput • Top AUConverter is connected to a render callback function Sunday, December 2, 12
  • 81. The trick! • Copy mData pointer to a state variable and NULL it in ioData • Call AudioQueueRender() on output unit. The NULL makes it pull from the graph. • Top of the graph pulls on render callback, which gives it back the mData we copied off. Sunday, December 2, 12
  • 82. Yes, really This is the rest of tapProc() ! // copy off the ioData so the graph can read from it // in render callback ! player.preRenderData = ioData->mBuffers[0].mData; ! ioData->mBuffers[0].mData = NULL; ! ! OSStatus renderErr = noErr; ! AudioUnitRenderActionFlags actionFlags = 0; ! renderErr = AudioUnitRender(player.genericOutputUnit, ! ! ! ! ! ! ! ! &actionFlags, ! ! ! ! ! ! ! ! player.renderTimeStamp, ! ! ! ! ! ! ! ! 0, ! ! ! ! ! ! ! ! inNumberFrames, ! ! ! ! ! ! ! ! ioData); ! NSLog (@"AudioUnitRender, renderErr = %ld",renderErr); } Sunday, December 2, 12
  • 83. Yes, really This is the render callback that supplies data to the int→float converter OSStatus converterInputRenderCallback (void *inRefCon, ! ! ! ! ! ! ! ! ! AudioUnitRenderActionFlags *ioActionFlags, ! ! ! ! ! ! ! ! ! const AudioTimeStamp *inTimeStamp, ! ! ! ! ! ! ! ! ! UInt32 inBusNumber, ! ! ! ! ! ! ! ! ! UInt32 inNumberFrames, ! ! ! ! ! ! ! ! ! AudioBufferList * ioData) { ! CCFWebRadioPlayer *player = (__bridge CCFWebRadioPlayer*) inRefCon; ! ! // read from buffer ! ioData->mBuffers[0].mData = player.preRenderData; ! return noErr; } Sunday, December 2, 12
  • 84. Demo: AQ Tap + AUNewTimePitch New in iOS 6! Sunday, December 2, 12
  • 86. Other new stuff Sunday, December 2, 12
  • 87. Multi-Route • Ordinarily, one input or output is active: earpiece, speaker, headphones, dock- connected device • “Last in wins” • With AV Session “multi-route” category, you can use several at once • WWDC 2012 session 505 Sunday, December 2, 12
  • 88. Utility classes moved again • C++ utilities, including the CARingBuffer • < Xcode 4.3, installed into /Developer • Xcode 4.3-4.4, optional download from developer.apple.com • ≧ Xcode 4.5, sample code project “Core Audio Utility Classes” Sunday, December 2, 12
  • 89. Takeaways • Core Audio fundamentals never change • New stuff is added as properties, typedefs, enums, etc. • Watch the SDK API diffs document to find the new stuff • Hope you like header files and experimentation Sunday, December 2, 12
  • 90. Q&A • Slides will be posted to slideshare.net/ invalidname • Code will be linked from there and my blog • Watch CocoaConf RDU glassboard, @invalidname on Twitter/ADN, or [Time code]; blog for announcement • Thanks! Sunday, December 2, 12