Files
swift-mirror/stdlib/objc/CoreAudio/CoreAudio.swift
Dmitri Hrybenko 1ca5bc414e stdlib: add an overlay for AudioBufferList
AudioBufferList contains a fake flexible array member, and is not
imported in a useable way.

rdar://18536929

Swift SVN r24843
2015-01-30 04:17:49 +00:00

171 lines
6.1 KiB
Swift

//===----------------------------------------------------------------------===//
//
// 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<T>` 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<T>(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<T>(
audioBuffer: AudioBuffer) -> UnsafeBufferPointer<T> {
return UnsafeBufferPointer(audioBuffer)
}
extension UnsafeMutableBufferPointer {
/// Initialize an `UnsafeMutableBufferPointer<T>` 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<T>(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<T>(
audioBuffer: AudioBuffer) -> UnsafeMutableBufferPointer<T> {
return UnsafeMutableBufferPointer(audioBuffer)
}
extension AudioBuffer {
/// Initialize an `AudioBuffer` from an `UnsafeMutableBufferPointer<T>`.
public init<T>(
_ typedBuffer: UnsafeMutableBufferPointer<T>, numberOfChannels: Int) {
self.mNumberChannels = UInt32(numberOfChannels)
self.mData = UnsafeMutablePointer<Void>(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<AudioBufferList>(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<AudioBufferList>) {
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<AudioBuffer> {
// 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<AudioBuffer>(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<AudioBufferList> {
return UnsafePointer(unsafeMutablePointer)
}
/// The pointer to the wrapped `AudioBufferList`.
public var unsafeMutablePointer: UnsafeMutablePointer<AudioBufferList>
}
extension UnsafeMutableAudioBufferListPointer : MutableCollectionType {
public func generate()
-> IndexingGenerator<UnsafeMutableAudioBufferListPointer> {
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
}
}
}