//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// @exported import CoreAudio // Clang module extension UnsafeBufferPointer { /// Initialize an `UnsafeBufferPointer` from an `AudioBuffer`. init(_ audioBuffer: AudioBuffer) { // FIXME: this API should be public, but it can't be because of a compiler // limitation: can't declare a public extension on a generic type from // another module. rdar://16974298 self.init( start: UnsafePointer(audioBuffer.mData), count: Int(audioBuffer.mDataByteSize) / strideof(T)) } } // The API above can't be public yet. We expose it through this function for // the sake of testing so that the code does not bitrot. public // @testable func _convertAudioBufferToUnsafeBufferPointer( audioBuffer: AudioBuffer) -> UnsafeBufferPointer { return UnsafeBufferPointer(audioBuffer) } extension UnsafeMutableBufferPointer { /// Initialize an `UnsafeMutableBufferPointer` from an `AudioBuffer`. init(_ audioBuffer: AudioBuffer) { // FIXME: this API should be public, but it can't be because of a compiler // limitation: can't declare a public extension on a generic type from // another module. rdar://16974298 self.init( start: UnsafeMutablePointer(audioBuffer.mData), count: Int(audioBuffer.mDataByteSize) / strideof(T)) } } // The API above can't be public yet. We expose it through this function for // the sake of testing so that the code does not bitrot. public // @testable func _convertAudioBufferToUnsafeMutableBufferPointer( audioBuffer: AudioBuffer) -> UnsafeMutableBufferPointer { return UnsafeMutableBufferPointer(audioBuffer) } extension AudioBuffer { /// Initialize an `AudioBuffer` from an `UnsafeMutableBufferPointer`. public init( _ typedBuffer: UnsafeMutableBufferPointer, numberOfChannels: Int) { self.mNumberChannels = UInt32(numberOfChannels) self.mData = UnsafeMutablePointer(typedBuffer.baseAddress) self.mDataByteSize = UInt32(typedBuffer.count * strideof(T)) } } extension AudioBufferList { /// :returns: the size in bytes of an `AudioBufferList` that can hold up to /// `maximumBuffers` `AudioBuffer`\ s. public static func sizeInBytes(#maximumBuffers: Int) -> Int { _precondition(maximumBuffers >= 1, "AudioBufferList should contain at least one AudioBuffer") return sizeof(AudioBufferList) + (maximumBuffers - 1) * strideof(AudioBuffer) } /// Allocate an `AudioBufferList` with a capacity for the specified number of /// `AudioBuffer`\ s. /// /// The `count` property of the new `AudioBufferList` is initialized to /// `maximumBuffers`. /// /// The memory should be freed with `free()`. public static func allocate(#maximumBuffers: Int) -> UnsafeMutableAudioBufferListPointer { let byteSize = UInt(sizeInBytes(maximumBuffers: maximumBuffers)) let ablMemory = calloc(byteSize, 1) _precondition(ablMemory != nil, "failed to allocate memory for an AudioBufferList") let abl = UnsafeMutableAudioBufferListPointer( UnsafeMutablePointer(ablMemory)) abl.count = maximumBuffers return abl } } /// A wrapper for a pointer to an `AudioBufferList`. /// /// Like `UnsafeMutablePointer`, this type provides no automated memory /// management and the user must therefore take care to allocate and free /// memory appropriately. public struct UnsafeMutableAudioBufferListPointer { /// Construct from an `AudioBufferList` pointer. public init(_ p: UnsafeMutablePointer) { unsafeMutablePointer = p } /// The number of `AudioBuffer`\ s in the `AudioBufferList` /// (`mNumberBuffers`). public var count: Int { get { return Int(unsafeMutablePointer.memory.mNumberBuffers) } nonmutating set(newValue) { unsafeMutablePointer.memory.mNumberBuffers = UInt32(newValue) } } /// The pointer to the first `AudioBuffer` in this `AudioBufferList`. internal var _audioBuffersPointer: UnsafeMutablePointer { // AudioBufferList has one AudioBuffer in a "flexible array member". // Position the pointer after that, and skip one AudioBuffer back. This // brings us to the start of AudioBuffer array. return UnsafeMutablePointer(unsafeMutablePointer + 1) - 1 } // FIXME: the properties 'unsafePointer' and 'unsafeMutablePointer' should // be initializers on UnsafePointer and UnsafeMutablePointer, but they can't // because of a compiler limitation: can't declare a public extension on a // generic type from another module. rdar://16974298 /// The pointer to the wrapped `AudioBufferList`. public var unsafePointer: UnsafePointer { return UnsafePointer(unsafeMutablePointer) } /// The pointer to the wrapped `AudioBufferList`. public var unsafeMutablePointer: UnsafeMutablePointer } extension UnsafeMutableAudioBufferListPointer : MutableCollectionType { public func generate() -> IndexingGenerator { return IndexingGenerator(self) } /// Always zero, which is the index of the first `AudioBuffer`. public var startIndex: Int { return 0 } /// The "past the end" position; always identical to `count`. public var endIndex: Int { return count } /// Access an indexed `AudioBuffer` (`mBuffers[i]`). public subscript(index: Int) -> AudioBuffer { get { _precondition(index >= 0 && index < self.count, "subscript index out of range") return (_audioBuffersPointer + index).memory } nonmutating set(newValue) { _precondition(index >= 0 && index < self.count, "subscript index out of range") (_audioBuffersPointer + index).memory = newValue } } }