SlideShare une entreprise Scribd logo
1  sur  85
Télécharger pour lire hors ligne
Media Frameworks and
Swift:
This is Fine
Chris Adamson • @invalidname
Forward Swift, March 2017
Who the what, now?
@invalidname
import Cocoa
import AVFoundation
import CoreMediaIO
if let devices = AVCaptureDevice.devices(),
let avDevices = devices.filter(
{$0 is AVCaptureDevice}) as? [AVCaptureDevice] {
for device in avDevices {
print("(device.description)")
}
}
<AVCaptureHALDevice: 0x100b16ab0 [Loopback Simulator][com.rogueamoeba.Loopback:E8577B20-0806-4472-A5E6-426CABCD6C8E]>
<AVCaptureHALDevice: 0x100c1a7c0 [Loopback Line-In][com.rogueamoeba.Loopback:A00F38FD-C2B6-43FD-98B7-23BAA6FACB03]>
<AVCaptureHALDevice: 0x100c16910 [iMic USB audio system][AppleUSBAudioEngine:Griffin Technology, Inc:iMic USB audio system:220000:2,1]>
<AVCaptureHALDevice: 0x100d13900 [Loopback Keynote][com.rogueamoeba.Loopback:1936D2A3-6D0B-428E-899E-0ABE46628EA4]>
<AVCaptureHALDevice: 0x100a26850 [Soundflower (64ch)][SoundflowerEngine:1]>
<AVCaptureHALDevice: 0x100a26310 [HD Pro Webcam C920][AppleUSBAudioEngine:Unknown Manufacturer:HD Pro Webcam C920:1218B05F:3]>
<AVCaptureHALDevice: 0x100d13660 [Soundflower (2ch)][SoundflowerEngine:0]>
<AVCaptureDALDevice: 0x100a348f0 [iGlasses][iGlasses]>
<AVCaptureDALDevice: 0x100a28d00 [HD Pro Webcam C920][0x244000046d082d]>
Program ended with exit code: 0
CMIOObjectPropertyAddress prop =
{ kCMIOHardwarePropertyAllowScreenCaptureDevices,
kCMIOObjectPropertyScopeGlobal,
kCMIOObjectPropertyElementMaster };
UInt32 allow = 1;
CMIOObjectSetPropertyData( kCMIOObjectSystemObject,
&prop, 0, NULL, sizeof(allow), &allow );
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices),
mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(
kCMIOObjectPropertyElementMaster))
var allow : UInt32 = 1
CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject),
&prop,
0,
nil,
UInt32(MemoryLayout<UInt32>.size),
&allow)
CMIOObjectPropertyAddress prop =
{ kCMIOHardwarePropertyAllowScreenCaptureDevices,
kCMIOObjectPropertyScopeGlobal,
kCMIOObjectPropertyElementMaster };
UInt32 allow = 1;
CMIOObjectSetPropertyData( kCMIOObjectSystemObject,
&prop, 0, NULL, sizeof(allow), &allow );
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices),
mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(
kCMIOObjectPropertyElementMaster))
var allow : UInt32 = 1
CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject),
&prop,
0,
nil,
UInt32(MemoryLayout<UInt32>.size),
&allow)
This
is
fine
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices),
mScope: CMIOObjectPropertyScope(
kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(
kCMIOObjectPropertyElementMaster))
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices),
mScope: CMIOObjectPropertyScope(
kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(
kCMIOObjectPropertyElementMaster))
public typealias CMIOObjectPropertySelector = UInt32
public typealias CMIOObjectPropertyScope = UInt32
public typealias CMIOObjectPropertyElement = UInt32
public struct CMIOObjectPropertyAddress {
public var mSelector: CMIOObjectPropertySelector
public var mScope: CMIOObjectPropertyScope
public var mElement: CMIOObjectPropertyElement
public init()
public init(mSelector: CMIOObjectPropertySelector,
mScope: CMIOObjectPropertyScope,
mElement: CMIOObjectPropertyElement)
}
extension CMIOObjectPropertySelector {
static let allowScreenCaptureDevices = CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices)
}
extension CMIOObjectPropertyScope {
static let global = CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal)
}
extension CMIOObjectPropertyElement {
static let master = CMIOObjectPropertyElement(kCMIOObjectPropertyElementMaster)
}
var prop = CMIOObjectPropertyAddress(
mSelector: .allowScreenCaptureDevices,
mScope: .global,
mElement: .master)
var prop = CMIOObjectPropertyAddress(
mSelector: CMIOObjectPropertySelector(
kCMIOHardwarePropertyAllowScreenCaptureDevices),
mScope: CMIOObjectPropertyScope(
kCMIOObjectPropertyScopeGlobal),
mElement: CMIOObjectPropertyElement(
kCMIOObjectPropertyElementMaster))
Demo
http://github.com/invalidstream/audio-reverser
Reversing Audio
1. Decode the MP3/AAC to LPCM2. Grab a buffer from the end3. Reverse its samples in memory4. Write it to the front of a new file5. Repeat until fully baked
API Needs
• Convert from MP3/AAC to LPCM
• Write sequentially to audio file (.caf, .aif, .wav)
• Random-access read from audio file
Plan A (Swift)
• AV Foundation
• AVAssetReader/Writer can do format conversion
while reading/writing audio files
• Can’t (easily) read from arbitrary packet offsets;
meant to process everything forward
Plan B (C, Swift?)
• Audio Toolbox (part of Core Audio)
• ExtAudioFile can do format conversions while
reading/writing audio files
• AudioFile can read from arbitrary packet offset
// declare LPCM format we are converting to
AudioStreamBasicDescription format = {0};
format.mSampleRate = 44100.0;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kAudioFormatFlagIsPacked |
kAudioFormatFlagIsSignedInteger;
format.mBitsPerChannel = 16;
format.mChannelsPerFrame = 2;
format.mBytesPerFrame = 4;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = 4;
// declare LPCM format we are converting to
var format = AudioStreamBasicDescription(
mSampleRate: 44100.0,
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: kAudioFormatFlagIsPacked +
kAudioFormatFlagIsSignedInteger,
mBytesPerPacket: 4,
mFramesPerPacket: 1,
mBytesPerFrame: 4,
mChannelsPerFrame: 2,
mBitsPerChannel: 16,
mReserved: 0)
// open AudioFile for output
AudioFileID forwardAudioFile;
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
kAudioFileFlags_EraseFile,
&forwardAudioFile);
IF_ERR_RETURN
#define IF_ERR_RETURN if (err != noErr) { return err; }
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
1. Uses a free function, rather than a method on AudioFile
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
2. Errors are communicated via the return value, rather than
throws
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
3. Some parameters are UInt32 constants, some are enums
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
4. Audio format is passed as an
UnsafePointer<AudioStreamBasicDescription>
// open AudioFile for output
var forwardAudioFile: AudioFileID?
err = AudioFileCreateWithURL(forwardURL,
kAudioFileCAFType,
&format,
AudioFileFlags.eraseFile,
&forwardAudioFile)
if err != noErr { return err }
5. Created object is returned via an in-out parameter
To say nothing of…
Pointer arithmetic!
// swap packets inside transfer buffer
for i in 0..<packetsToTransfer/2 {
let swapSrc = transferBuffer.advanced(by: Int(i) * Int(format.mBytesPerPacket))
let swapDst = transferBuffer.advanced(by: transferBufferSize -
(Int(i+1) * Int(format.mBytesPerPacket)))
memcpy(swapBuffer, swapSrc, Int(format.mBytesPerPacket))
memcpy(swapSrc, swapDst, Int(format.mBytesPerPacket))
memcpy(swapDst, swapBuffer, Int(format.mBytesPerPacket))
}
Couldn’t you just…
extension AudioFileID {
init? (url: URL, fileType: UInt32,
format: AudioStreamBasicDescription, flags: AudioFileFlags) {
var fileId : AudioFileID?
var format = format
let err = AudioFileCreateWithURL(url as CFURL,
fileType,
&format,
flags,
&fileId)
guard err != noErr, let createdFile = fileId else { return nil }
self = createdFile
}
}
Been there, done that
• The Amazing Audio Engine 💀
• Novocaine (💀?)
• EZAudio 💀
• AudioKit
• Superpowered
• etc…
/**
Convert a source audio file (using any Core Audio-supported codec) and create LPCM .caf
files for its forward and backward versions.
- parameter sourceURL: A file URL containing the source audio to be read from
- parameter forwardURL: A file URL with the destination to write the decompressed (LPCM) forward file
- parameter backwardURL: A file URL with the destination to write the backward file
*/
OSStatus convertAndReverse(CFURLRef sourceURL, CFURLRef forwardURL, CFURLRef backwardURL);
AudioReversingC.h
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <CoreFoundation/CoreFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
OSStatus convertAndReverse(CFURLRef sourceURL, CFURLRef forwardURL, CFURLRef backwardURL);
AudioReverser-Bridging-Header.h
if USE_SWIFT_CONVERTER {
err = convertAndReverseSwift(sourceURL: source as CFURL,
forwardURL: self.forwardURL as! CFURL,
backwardURL: self.backwardURL as! CFURL)
} else {
err = convertAndReverse(source as! CFURL,
self.forwardURL as! CFURL,
self.backwardURL as! CFURL)
}
C APIs on iOS/macOS
• Core Foundation
• Core Audio
• Core Media
• Video Toolbox
• Keychain
• IOKit
• OpenGL
• SQLite
• Accelerate
• XPC
• BSD, Mach
• etc…
Going deeper…
Audio Units
• Discrete software objects for working with audio
• Generators, I/O, Filters/Effects, Mixers,
Converters
• Typically combined in a “graph” model
• Used by Garage Band, Logic, etc.
Wait, what?
-(instancetype)initWithComponentDescription:(AudioComponentDescription)componentDescription

options:(AudioComponentInstantiationOptions)options

error:(NSError **)outError {
self = [super initWithComponentDescription:componentDescription

options:options
error:outError];
if (self == nil) {
return nil;
}
// ...
return self;
}
MyAudioUnit.m
XPC
(macOS only)
Swift 3Swift 4
https://github.com/apple/swift/blob/master/docs/
ABIStabilityManifesto.md
“Given the importance of getting the core ABI and the
related fundamentals correct, we are going to defer the
declaration of ABI stability out of Swift 4 while still
focusing the majority of effort to get to the point where
the ABI can be declared stable.”
—Ted Kremenek, Feb. 16, 2017

“Swift 4, stage 2 starts now”
https://lists.swift.org/pipermail/swift-evolution/Week-of-
Mon-20170213/032116.html
// Block which subclassers must provide to implement rendering.
- (AUInternalRenderBlock)internalRenderBlock {
// Capture in locals to avoid Obj-C member lookups.
// If "self" is captured in render, we're doing it wrong. See sample code.
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags *actionFlags,
const AudioTimeStamp *timestamp,
AVAudioFrameCount frameCount,
NSInteger outputBusNumber,
AudioBufferList *outputData,
const AURenderEvent *realtimeEventListHead,
AURenderPullInputBlock pullInputBlock) {
// Do event handling and signal processing here.
return noErr;
};
}
Don’t do this
• An audio unit’s render block is called on a
realtime thread
• Therefore it cannot perform any action that could
block:
• I/O (file or network)
• Waiting on a mutex or semaphore
Also, don’t do this
• Call objc_msg_send()
• Capture any Objective-C or Swift object
• Allocate memory
Basically, if you touch anything in the block other than a pre-
allocated C struct, you’re asking for trouble.
https://github.com/apple/swift/blob/master/docs/
OwnershipManifesto.md
Certain kinds of low-level programming
require stricter performance guarantees.
Often these guarantees are less about
absolute performance than predictable
performance. For example, keeping up with
an audio stream is not a taxing job for a
modern processor, even with significant per-
sample overheads, but any sort of
unexpected hiccup is immediately noticeable
by users.
—“Swift Ownership Manifesto”,

February 2017
We believe that these problems can be addressed with an opt-in set of
features that we collectively call ownership. […]
Swift already has an ownership system, but it's "under the covers": it's an
implementation detail that programmers have little ability to influence. What
we are proposing here is easy to summarize:
• We should add a core rule to the ownership system, called the Law of
Exclusivity […]
• We should add features to give programmers more control over the
ownership system […]
• We should add features to allow programmers to express types with
unique ownership […]
And yet…
“[Swift] is the first industrial-quality systems
programming language that is as expressive and
enjoyable as a scripting language.”
https://developer.apple.com/library/content/documentation/
Swift/Conceptual/Swift_Programming_Language/
So… when?
Waiting…
• ABI stability — will not be in Swift 4
• Ownership — unclear
• Are these traits sufficient?
Strategies
• Use AV Foundation if you can
• Learn to balance C and Swift
• “Render undo Caesar what is Caesar’s…”
• The goal is to have idiomatic Swift, not Swift
that may work but looks like C
Media Frameworks and
Swift:
This is Fine
Chris Adamson • @invalidname
Forward Swift, March 2017

Contenu connexe

Tendances

Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDKChris Adamson
 
A slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightA slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightAlexy Joseph
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Netcetera
 
Morpheus configuration engine (slides from Saint Perl-2 conference)
Morpheus configuration engine (slides from Saint Perl-2 conference)Morpheus configuration engine (slides from Saint Perl-2 conference)
Morpheus configuration engine (slides from Saint Perl-2 conference)Vyacheslav Matyukhin
 
Web Audio API + AngularJS
Web Audio API + AngularJSWeb Audio API + AngularJS
Web Audio API + AngularJSChris Bateman
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go ProgrammingLin Yo-An
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebFabio Akita
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet
 
php & performance
 php & performance php & performance
php & performancesimon8410
 
Creating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaCreating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaMark Gardner
 
How we use and deploy Varnish at Opera
How we use and deploy Varnish at OperaHow we use and deploy Varnish at Opera
How we use and deploy Varnish at OperaCosimo Streppone
 
VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareCosimo Streppone
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Elizabeth Smith
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...frank2
 
HipHop Virtual Machine
HipHop Virtual MachineHipHop Virtual Machine
HipHop Virtual MachineRadu Murzea
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In SantosFabio Akita
 
PHP & Performance
PHP & PerformancePHP & Performance
PHP & Performance毅 吕
 

Tendances (20)

Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDK
 
A slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightA slightly deeper dive into Stagefright
A slightly deeper dive into Stagefright
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)
 
Morpheus configuration engine (slides from Saint Perl-2 conference)
Morpheus configuration engine (slides from Saint Perl-2 conference)Morpheus configuration engine (slides from Saint Perl-2 conference)
Morpheus configuration engine (slides from Saint Perl-2 conference)
 
Web Audio API + AngularJS
Web Audio API + AngularJSWeb Audio API + AngularJS
Web Audio API + AngularJS
 
Dart on server - Meetup 18/05/2017
Dart on server - Meetup 18/05/2017Dart on server - Meetup 18/05/2017
Dart on server - Meetup 18/05/2017
 
AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017AngularDart - Meetup 15/03/2017
AngularDart - Meetup 15/03/2017
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações Web
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
 
php & performance
 php & performance php & performance
php & performance
 
Creating Perl modules with Dist::Zilla
Creating Perl modules with Dist::ZillaCreating Perl modules with Dist::Zilla
Creating Perl modules with Dist::Zilla
 
How we use and deploy Varnish at Opera
How we use and deploy Varnish at OperaHow we use and deploy Varnish at Opera
How we use and deploy Varnish at Opera
 
VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera Software
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...
Binary Obfuscation from the Top Down: Obfuscation Executables without Writing...
 
HipHop Virtual Machine
HipHop Virtual MachineHipHop Virtual Machine
HipHop Virtual Machine
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos
 
PHP & Performance
PHP & PerformancePHP & Performance
PHP & Performance
 

En vedette

Análisis entre el neoclasicismo y impresionismo
Análisis entre el neoclasicismo y impresionismo Análisis entre el neoclasicismo y impresionismo
Análisis entre el neoclasicismo y impresionismo Ana Santiago Monsalve
 
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
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV FoundationBob McCune
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationBob McCune
 
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
 
Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Chris Adamson
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Chris Adamson
 
Webinar: Is Your Storage Ready for Disaster?
Webinar: Is Your Storage Ready for Disaster?Webinar: Is Your Storage Ready for Disaster?
Webinar: Is Your Storage Ready for Disaster?Storage Switzerland
 
Creating Container View Controllers
Creating Container View ControllersCreating Container View Controllers
Creating Container View ControllersBob McCune
 
Video streaming on e-lab
Video streaming on e-labVideo streaming on e-lab
Video streaming on e-labrneto11
 
Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV FoundationChris Adamson
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV FoundationChris Adamson
 
Beyond 2017 Trends
Beyond 2017 TrendsBeyond 2017 Trends
Beyond 2017 Trendssoul2life
 
Histone 2b paper
Histone 2b paperHistone 2b paper
Histone 2b paperNyaz Jaff
 
DREAM 2017 | Faculty as Drivers of College Reform Efforts
DREAM 2017 | Faculty as Drivers of College Reform EffortsDREAM 2017 | Faculty as Drivers of College Reform Efforts
DREAM 2017 | Faculty as Drivers of College Reform EffortsAchieving the Dream
 
GEOMETRIA II U1 t2 a1
 GEOMETRIA II U1 t2 a1 GEOMETRIA II U1 t2 a1
GEOMETRIA II U1 t2 a1Pathy Romero
 
Efficiency of protein utilisation ppt
Efficiency of protein utilisation pptEfficiency of protein utilisation ppt
Efficiency of protein utilisation pptDr. Akshay Sonawane
 
Hacking and Securing iOS Apps : Part 1
Hacking and Securing iOS Apps : Part 1Hacking and Securing iOS Apps : Part 1
Hacking and Securing iOS Apps : Part 1Subhransu Behera
 

En vedette (20)

Análisis entre el neoclasicismo y impresionismo
Análisis entre el neoclasicismo y impresionismo Análisis entre el neoclasicismo y impresionismo
Análisis entre el neoclasicismo y impresionismo
 
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
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV Foundation
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV Foundation
 
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...
 
Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)Advanced AV Foundation (CocoaConf, Aug '11)
Advanced AV Foundation (CocoaConf, Aug '11)
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
Webinar: Is Your Storage Ready for Disaster?
Webinar: Is Your Storage Ready for Disaster?Webinar: Is Your Storage Ready for Disaster?
Webinar: Is Your Storage Ready for Disaster?
 
Creating Container View Controllers
Creating Container View ControllersCreating Container View Controllers
Creating Container View Controllers
 
Video streaming on e-lab
Video streaming on e-labVideo streaming on e-lab
Video streaming on e-lab
 
Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV Foundation
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV Foundation
 
Beyond 2017 Trends
Beyond 2017 TrendsBeyond 2017 Trends
Beyond 2017 Trends
 
Histone 2b paper
Histone 2b paperHistone 2b paper
Histone 2b paper
 
Tutorial hotspot
Tutorial hotspotTutorial hotspot
Tutorial hotspot
 
DREAM 2017 | Faculty as Drivers of College Reform Efforts
DREAM 2017 | Faculty as Drivers of College Reform EffortsDREAM 2017 | Faculty as Drivers of College Reform Efforts
DREAM 2017 | Faculty as Drivers of College Reform Efforts
 
Excel vba講座
Excel vba講座Excel vba講座
Excel vba講座
 
GEOMETRIA II U1 t2 a1
 GEOMETRIA II U1 t2 a1 GEOMETRIA II U1 t2 a1
GEOMETRIA II U1 t2 a1
 
Efficiency of protein utilisation ppt
Efficiency of protein utilisation pptEfficiency of protein utilisation ppt
Efficiency of protein utilisation ppt
 
Hacking and Securing iOS Apps : Part 1
Hacking and Securing iOS Apps : Part 1Hacking and Securing iOS Apps : Part 1
Hacking and Securing iOS Apps : Part 1
 

Similaire à Forward Swift 2017: Media Frameworks and Swift: This Is Fine

OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL Suraj Bang
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioKevin Avila
 
Stream or not to Stream?

Stream or not to Stream?
Stream or not to Stream?

Stream or not to Stream?
Lukasz Byczynski
 
Xke - Introduction to Apache Camel
Xke - Introduction to Apache CamelXke - Introduction to Apache Camel
Xke - Introduction to Apache CamelAlexis Kinsella
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenchesJordi Gerona
 
Lec 47.48 - stream-files
Lec 47.48 - stream-filesLec 47.48 - stream-files
Lec 47.48 - stream-filesPrincess Sam
 
Web Template Mechanisms in SOC Verification - DVCon.pdf
Web Template Mechanisms in SOC Verification - DVCon.pdfWeb Template Mechanisms in SOC Verification - DVCon.pdf
Web Template Mechanisms in SOC Verification - DVCon.pdfSamHoney6
 
Input/Output Exploring java.io
Input/Output Exploring java.ioInput/Output Exploring java.io
Input/Output Exploring java.ioNilaNila16
 
swift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientswift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientShinya Mochida
 
programming language in c&c++
programming language in c&c++programming language in c&c++
programming language in c&c++Haripritha
 
Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Samuel Lampa
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble AppPebble Technology
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoMatt Stine
 
06 - ELF format, knowing your friend
06 - ELF format, knowing your friend06 - ELF format, knowing your friend
06 - ELF format, knowing your friendAlexandre Moneger
 
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupCachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupAbel Muíño
 
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...Provectus
 

Similaire à Forward Swift 2017: Media Frameworks and Swift: This Is Fine (20)

FFmpeg
FFmpegFFmpeg
FFmpeg
 
Twig Templating
Twig TemplatingTwig Templating
Twig Templating
 
Introduction to Apache Beam
Introduction to Apache BeamIntroduction to Apache Beam
Introduction to Apache Beam
 
OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL OWB11gR2 - Extending ETL
OWB11gR2 - Extending ETL
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core Audio
 
Stream or not to Stream?

Stream or not to Stream?
Stream or not to Stream?

Stream or not to Stream?

 
Xke - Introduction to Apache Camel
Xke - Introduction to Apache CamelXke - Introduction to Apache Camel
Xke - Introduction to Apache Camel
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
 
Lec 47.48 - stream-files
Lec 47.48 - stream-filesLec 47.48 - stream-files
Lec 47.48 - stream-files
 
Web Template Mechanisms in SOC Verification - DVCon.pdf
Web Template Mechanisms in SOC Verification - DVCon.pdfWeb Template Mechanisms in SOC Verification - DVCon.pdf
Web Template Mechanisms in SOC Verification - DVCon.pdf
 
Input/Output Exploring java.io
Input/Output Exploring java.ioInput/Output Exploring java.io
Input/Output Exploring java.io
 
swift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClientswift-nio のアーキテクチャーと RxHttpClient
swift-nio のアーキテクチャーと RxHttpClient
 
programming language in c&c++
programming language in c&c++programming language in c&c++
programming language in c&c++
 
Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
06 - ELF format, knowing your friend
06 - ELF format, knowing your friend06 - ELF format, knowing your friend
06 - ELF format, knowing your friend
 
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupCachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
 
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...
Data Summer Conf 2018, “Building unified Batch and Stream processing pipeline...
 

Plus de 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
 
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
 
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
 
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 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
 
Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Chris Adamson
 
Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Chris Adamson
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Chris Adamson
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)Chris Adamson
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Chris Adamson
 
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
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Chris Adamson
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Chris Adamson
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Chris Adamson
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Chris Adamson
 

Plus de Chris Adamson (19)

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)
 
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...
 
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)
 
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 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)
 
Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)Get On The Audiobus (CocoaConf Atlanta, November 2013)
Get On The Audiobus (CocoaConf Atlanta, November 2013)
 
Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)Get On The Audiobus (CocoaConf Boston, October 2013)
Get On The Audiobus (CocoaConf Boston, October 2013)
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 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)
Core Audio in iOS 6 (CocoaConf DC, March 2013)
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
 

Dernier

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
 
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
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
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
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
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
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Dernier (20)

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
 
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
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
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
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
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
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Forward Swift 2017: Media Frameworks and Swift: This Is Fine

  • 1. Media Frameworks and Swift: This is Fine Chris Adamson • @invalidname Forward Swift, March 2017
  • 2. Who the what, now? @invalidname
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16. import Cocoa import AVFoundation import CoreMediaIO if let devices = AVCaptureDevice.devices(), let avDevices = devices.filter( {$0 is AVCaptureDevice}) as? [AVCaptureDevice] { for device in avDevices { print("(device.description)") } }
  • 17. <AVCaptureHALDevice: 0x100b16ab0 [Loopback Simulator][com.rogueamoeba.Loopback:E8577B20-0806-4472-A5E6-426CABCD6C8E]> <AVCaptureHALDevice: 0x100c1a7c0 [Loopback Line-In][com.rogueamoeba.Loopback:A00F38FD-C2B6-43FD-98B7-23BAA6FACB03]> <AVCaptureHALDevice: 0x100c16910 [iMic USB audio system][AppleUSBAudioEngine:Griffin Technology, Inc:iMic USB audio system:220000:2,1]> <AVCaptureHALDevice: 0x100d13900 [Loopback Keynote][com.rogueamoeba.Loopback:1936D2A3-6D0B-428E-899E-0ABE46628EA4]> <AVCaptureHALDevice: 0x100a26850 [Soundflower (64ch)][SoundflowerEngine:1]> <AVCaptureHALDevice: 0x100a26310 [HD Pro Webcam C920][AppleUSBAudioEngine:Unknown Manufacturer:HD Pro Webcam C920:1218B05F:3]> <AVCaptureHALDevice: 0x100d13660 [Soundflower (2ch)][SoundflowerEngine:0]> <AVCaptureDALDevice: 0x100a348f0 [iGlasses][iGlasses]> <AVCaptureDALDevice: 0x100a28d00 [HD Pro Webcam C920][0x244000046d082d]> Program ended with exit code: 0
  • 18.
  • 19. CMIOObjectPropertyAddress prop = { kCMIOHardwarePropertyAllowScreenCaptureDevices, kCMIOObjectPropertyScopeGlobal, kCMIOObjectPropertyElementMaster }; UInt32 allow = 1; CMIOObjectSetPropertyData( kCMIOObjectSystemObject, &prop, 0, NULL, sizeof(allow), &allow );
  • 20. var prop = CMIOObjectPropertyAddress( mSelector: CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement( kCMIOObjectPropertyElementMaster)) var allow : UInt32 = 1 CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &prop, 0, nil, UInt32(MemoryLayout<UInt32>.size), &allow)
  • 21. CMIOObjectPropertyAddress prop = { kCMIOHardwarePropertyAllowScreenCaptureDevices, kCMIOObjectPropertyScopeGlobal, kCMIOObjectPropertyElementMaster }; UInt32 allow = 1; CMIOObjectSetPropertyData( kCMIOObjectSystemObject, &prop, 0, NULL, sizeof(allow), &allow ); var prop = CMIOObjectPropertyAddress( mSelector: CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement( kCMIOObjectPropertyElementMaster)) var allow : UInt32 = 1 CMIOObjectSetPropertyData(CMIOObjectID(kCMIOObjectSystemObject), &prop, 0, nil, UInt32(MemoryLayout<UInt32>.size), &allow) This is fine
  • 22.
  • 23. var prop = CMIOObjectPropertyAddress( mSelector: CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope( kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement( kCMIOObjectPropertyElementMaster)) var prop = CMIOObjectPropertyAddress( mSelector: CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope( kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement( kCMIOObjectPropertyElementMaster))
  • 24.
  • 25.
  • 26. public typealias CMIOObjectPropertySelector = UInt32 public typealias CMIOObjectPropertyScope = UInt32 public typealias CMIOObjectPropertyElement = UInt32 public struct CMIOObjectPropertyAddress { public var mSelector: CMIOObjectPropertySelector public var mScope: CMIOObjectPropertyScope public var mElement: CMIOObjectPropertyElement public init() public init(mSelector: CMIOObjectPropertySelector, mScope: CMIOObjectPropertyScope, mElement: CMIOObjectPropertyElement) }
  • 27. extension CMIOObjectPropertySelector { static let allowScreenCaptureDevices = CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices) } extension CMIOObjectPropertyScope { static let global = CMIOObjectPropertyScope(kCMIOObjectPropertyScopeGlobal) } extension CMIOObjectPropertyElement { static let master = CMIOObjectPropertyElement(kCMIOObjectPropertyElementMaster) }
  • 28. var prop = CMIOObjectPropertyAddress( mSelector: .allowScreenCaptureDevices, mScope: .global, mElement: .master) var prop = CMIOObjectPropertyAddress( mSelector: CMIOObjectPropertySelector( kCMIOHardwarePropertyAllowScreenCaptureDevices), mScope: CMIOObjectPropertyScope( kCMIOObjectPropertyScopeGlobal), mElement: CMIOObjectPropertyElement( kCMIOObjectPropertyElementMaster))
  • 29.
  • 31. Reversing Audio 1. Decode the MP3/AAC to LPCM2. Grab a buffer from the end3. Reverse its samples in memory4. Write it to the front of a new file5. Repeat until fully baked
  • 32. API Needs • Convert from MP3/AAC to LPCM • Write sequentially to audio file (.caf, .aif, .wav) • Random-access read from audio file
  • 33. Plan A (Swift) • AV Foundation • AVAssetReader/Writer can do format conversion while reading/writing audio files • Can’t (easily) read from arbitrary packet offsets; meant to process everything forward
  • 34. Plan B (C, Swift?) • Audio Toolbox (part of Core Audio) • ExtAudioFile can do format conversions while reading/writing audio files • AudioFile can read from arbitrary packet offset
  • 35.
  • 36. // declare LPCM format we are converting to AudioStreamBasicDescription format = {0}; format.mSampleRate = 44100.0; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; format.mBitsPerChannel = 16; format.mChannelsPerFrame = 2; format.mBytesPerFrame = 4; format.mFramesPerPacket = 1; format.mBytesPerPacket = 4;
  • 37. // declare LPCM format we are converting to var format = AudioStreamBasicDescription( mSampleRate: 44100.0, mFormatID: kAudioFormatLinearPCM, mFormatFlags: kAudioFormatFlagIsPacked + kAudioFormatFlagIsSignedInteger, mBytesPerPacket: 4, mFramesPerPacket: 1, mBytesPerFrame: 4, mChannelsPerFrame: 2, mBitsPerChannel: 16, mReserved: 0)
  • 38. // open AudioFile for output AudioFileID forwardAudioFile; err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, kAudioFileFlags_EraseFile, &forwardAudioFile); IF_ERR_RETURN #define IF_ERR_RETURN if (err != noErr) { return err; }
  • 39. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err }
  • 40.
  • 41. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err }
  • 42. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err } 1. Uses a free function, rather than a method on AudioFile
  • 43. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err } 2. Errors are communicated via the return value, rather than throws
  • 44. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err } 3. Some parameters are UInt32 constants, some are enums
  • 45. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err } 4. Audio format is passed as an UnsafePointer<AudioStreamBasicDescription>
  • 46. // open AudioFile for output var forwardAudioFile: AudioFileID? err = AudioFileCreateWithURL(forwardURL, kAudioFileCAFType, &format, AudioFileFlags.eraseFile, &forwardAudioFile) if err != noErr { return err } 5. Created object is returned via an in-out parameter
  • 47. To say nothing of…
  • 48. Pointer arithmetic! // swap packets inside transfer buffer for i in 0..<packetsToTransfer/2 { let swapSrc = transferBuffer.advanced(by: Int(i) * Int(format.mBytesPerPacket)) let swapDst = transferBuffer.advanced(by: transferBufferSize - (Int(i+1) * Int(format.mBytesPerPacket))) memcpy(swapBuffer, swapSrc, Int(format.mBytesPerPacket)) memcpy(swapSrc, swapDst, Int(format.mBytesPerPacket)) memcpy(swapDst, swapBuffer, Int(format.mBytesPerPacket)) }
  • 49.
  • 51. extension AudioFileID { init? (url: URL, fileType: UInt32, format: AudioStreamBasicDescription, flags: AudioFileFlags) { var fileId : AudioFileID? var format = format let err = AudioFileCreateWithURL(url as CFURL, fileType, &format, flags, &fileId) guard err != noErr, let createdFile = fileId else { return nil } self = createdFile } }
  • 52. Been there, done that • The Amazing Audio Engine 💀 • Novocaine (💀?) • EZAudio 💀 • AudioKit • Superpowered • etc…
  • 53.
  • 54. /** Convert a source audio file (using any Core Audio-supported codec) and create LPCM .caf files for its forward and backward versions. - parameter sourceURL: A file URL containing the source audio to be read from - parameter forwardURL: A file URL with the destination to write the decompressed (LPCM) forward file - parameter backwardURL: A file URL with the destination to write the backward file */ OSStatus convertAndReverse(CFURLRef sourceURL, CFURLRef forwardURL, CFURLRef backwardURL); AudioReversingC.h // // Use this file to import your target's public headers that you would like to expose to Swift. // #import <CoreFoundation/CoreFoundation.h> #import <AudioToolbox/AudioToolbox.h> OSStatus convertAndReverse(CFURLRef sourceURL, CFURLRef forwardURL, CFURLRef backwardURL); AudioReverser-Bridging-Header.h
  • 55. if USE_SWIFT_CONVERTER { err = convertAndReverseSwift(sourceURL: source as CFURL, forwardURL: self.forwardURL as! CFURL, backwardURL: self.backwardURL as! CFURL) } else { err = convertAndReverse(source as! CFURL, self.forwardURL as! CFURL, self.backwardURL as! CFURL) }
  • 56. C APIs on iOS/macOS • Core Foundation • Core Audio • Core Media • Video Toolbox • Keychain • IOKit • OpenGL • SQLite • Accelerate • XPC • BSD, Mach • etc…
  • 58.
  • 59. Audio Units • Discrete software objects for working with audio • Generators, I/O, Filters/Effects, Mixers, Converters • Typically combined in a “graph” model • Used by Garage Band, Logic, etc.
  • 60.
  • 61.
  • 63. -(instancetype)initWithComponentDescription:(AudioComponentDescription)componentDescription
 options:(AudioComponentInstantiationOptions)options
 error:(NSError **)outError { self = [super initWithComponentDescription:componentDescription
 options:options error:outError]; if (self == nil) { return nil; } // ... return self; } MyAudioUnit.m
  • 64.
  • 68. “Given the importance of getting the core ABI and the related fundamentals correct, we are going to defer the declaration of ABI stability out of Swift 4 while still focusing the majority of effort to get to the point where the ABI can be declared stable.” —Ted Kremenek, Feb. 16, 2017
 “Swift 4, stage 2 starts now” https://lists.swift.org/pipermail/swift-evolution/Week-of- Mon-20170213/032116.html
  • 69.
  • 70.
  • 71.
  • 72. // Block which subclassers must provide to implement rendering. - (AUInternalRenderBlock)internalRenderBlock { // Capture in locals to avoid Obj-C member lookups. // If "self" is captured in render, we're doing it wrong. See sample code. return ^AUAudioUnitStatus(AudioUnitRenderActionFlags *actionFlags, const AudioTimeStamp *timestamp, AVAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList *outputData, const AURenderEvent *realtimeEventListHead, AURenderPullInputBlock pullInputBlock) { // Do event handling and signal processing here. return noErr; }; }
  • 73. Don’t do this • An audio unit’s render block is called on a realtime thread • Therefore it cannot perform any action that could block: • I/O (file or network) • Waiting on a mutex or semaphore
  • 74. Also, don’t do this • Call objc_msg_send() • Capture any Objective-C or Swift object • Allocate memory Basically, if you touch anything in the block other than a pre- allocated C struct, you’re asking for trouble.
  • 76. Certain kinds of low-level programming require stricter performance guarantees. Often these guarantees are less about absolute performance than predictable performance. For example, keeping up with an audio stream is not a taxing job for a modern processor, even with significant per- sample overheads, but any sort of unexpected hiccup is immediately noticeable by users. —“Swift Ownership Manifesto”,
 February 2017
  • 77. We believe that these problems can be addressed with an opt-in set of features that we collectively call ownership. […] Swift already has an ownership system, but it's "under the covers": it's an implementation detail that programmers have little ability to influence. What we are proposing here is easy to summarize: • We should add a core rule to the ownership system, called the Law of Exclusivity […] • We should add features to give programmers more control over the ownership system […] • We should add features to allow programmers to express types with unique ownership […]
  • 79. “[Swift] is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language.” https://developer.apple.com/library/content/documentation/ Swift/Conceptual/Swift_Programming_Language/
  • 81. Waiting… • ABI stability — will not be in Swift 4 • Ownership — unclear • Are these traits sufficient?
  • 82.
  • 83.
  • 84. Strategies • Use AV Foundation if you can • Learn to balance C and Swift • “Render undo Caesar what is Caesar’s…” • The goal is to have idiomatic Swift, not Swift that may work but looks like C
  • 85. Media Frameworks and Swift: This is Fine Chris Adamson • @invalidname Forward Swift, March 2017