// RUN: %target-run-simple-swift // REQUIRES: executable_test // REQUIRES: objc_interop // UNSUPPORTED: OS=watchos import StdlibUnittest import StdlibCollectionUnittest import CoreAudio // Used in tests below. extension AudioBuffer : Equatable {} public func == (lhs: AudioBuffer, rhs: AudioBuffer) -> Bool { return lhs.mNumberChannels == rhs.mNumberChannels && lhs.mDataByteSize == rhs.mDataByteSize && lhs.mData == rhs.mData } var CoreAudioTestSuite = TestSuite("CoreAudio") // The size of the non-flexible part of an AudioBufferList. #if arch(i386) || arch(arm) let ablHeaderSize = 4 #elseif arch(x86_64) || arch(arm64) let ablHeaderSize = 8 #endif CoreAudioTestSuite.test("UnsafeBufferPointer.init(_: AudioBuffer)") { do { let audioBuffer = AudioBuffer( mNumberChannels: 0, mDataByteSize: 0, mData: nil) let result: UnsafeBufferPointer = UnsafeBufferPointer(audioBuffer) expectEqual(nil, result.baseAddress) expectEqual(0, result.count) } do { let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678)) let result: UnsafeBufferPointer = UnsafeBufferPointer(audioBuffer) expectEqual(audioBuffer.mData, UnsafeRawPointer(result.baseAddress!)) expectEqual(256, result.count) } } CoreAudioTestSuite.test("UnsafeMutableBufferPointer.init(_: AudioBuffer)") { do { let audioBuffer = AudioBuffer( mNumberChannels: 0, mDataByteSize: 0, mData: nil) let result: UnsafeMutableBufferPointer = UnsafeMutableBufferPointer(audioBuffer) expectEqual(nil, result.baseAddress) expectEqual(0, result.count) } do { let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678)) let result: UnsafeMutableBufferPointer = UnsafeMutableBufferPointer(audioBuffer) expectEqual(audioBuffer.mData!, UnsafeMutableRawPointer(result.baseAddress!)) expectEqual(256, result.count) } } CoreAudioTestSuite.test( "AudioBuffer.init(_: UnsafeMutableBufferPointer, numberOfChannels: Int)") { do { // NULL pointer. let buffer = UnsafeMutableBufferPointer(start: nil, count: 0) let result = AudioBuffer(buffer, numberOfChannels: 2) expectEqual(2, result.mNumberChannels) expectEqual(0, result.mDataByteSize) expectEqual(nil, result.mData) } do { // Non-NULL pointer. let buffer = UnsafeMutableBufferPointer( start: UnsafeMutablePointer(bitPattern: 0x1234_5678), count: 0) let result = AudioBuffer(buffer, numberOfChannels: 2) expectEqual(2, result.mNumberChannels) expectEqual(0, result.mDataByteSize) expectEqual(buffer.baseAddress, result.mData) } } CoreAudioTestSuite.test( "AudioBuffer.init(_: UnsafeMutableBufferPointer, numberOfChannels: Int)/trap") { #if arch(i386) || arch(arm) let overflowingCount = Int.max #elseif arch(x86_64) || arch(arm64) let overflowingCount = Int(UInt32.max) #endif let buffer = UnsafeMutableBufferPointer( start: UnsafeMutablePointer(bitPattern: 0x1234_5678), count: overflowingCount) expectCrashLater() // An overflow happens when we try to compute the value for mDataByteSize. _ = AudioBuffer(buffer, numberOfChannels: 2) } CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)") { expectEqual(ablHeaderSize + strideof(AudioBuffer.self), AudioBufferList.sizeInBytes(maximumBuffers: 1)) expectEqual(ablHeaderSize + 16 * strideof(AudioBuffer.self), AudioBufferList.sizeInBytes(maximumBuffers: 16)) } CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/count<0") { expectCrashLater() _ = AudioBufferList.sizeInBytes(maximumBuffers: -1) } CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/count==0") { expectCrashLater() _ = AudioBufferList.sizeInBytes(maximumBuffers: -1) } CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/overflow") { expectCrashLater() _ = AudioBufferList.sizeInBytes(maximumBuffers: Int.max) } CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)") { do { let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 1) expectEqual(1, ablPtrWrapper.count) free(ablPtrWrapper.unsafeMutablePointer) } do { let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 16) expectEqual(16, ablPtrWrapper.count) free(ablPtrWrapper.unsafeMutablePointer) } } CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/count==0") { expectCrashLater() _ = AudioBufferList.allocate(maximumBuffers: 0) } CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/count<0") { expectCrashLater() _ = AudioBufferList.allocate(maximumBuffers: -1) } CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)/trap/overflow") { expectCrashLater() _ = AudioBufferList.allocate(maximumBuffers: Int.max) } CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer/AssociatedTypes") { typealias Subject = UnsafeMutableAudioBufferListPointer expectRandomAccessCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: IndexingIterator.self, subSequenceType: MutableRandomAccessSlice.self, indexType: Int.self, indexDistanceType: Int.self, indicesType: CountableRange.self) } CoreAudioTestSuite.test( "UnsafeMutableAudioBufferListPointer.init(_: UnsafeMutablePointer)," + "UnsafeMutableAudioBufferListPointer.unsafePointer," + "UnsafeMutableAudioBufferListPointer.unsafeMutablePointer") { do { let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(nil) expectEmpty(ablPtrWrapper) } do { let ablPtrWrapper = UnsafeMutableAudioBufferListPointer( UnsafeMutablePointer(bitPattern: 0x1234_5678)!) expectEqual( UnsafePointer(bitPattern: 0x1234_5678), ablPtrWrapper.unsafePointer) expectEqual( UnsafePointer(bitPattern: 0x1234_5678), ablPtrWrapper.unsafeMutablePointer) } do { let ablPtrWrapper = UnsafeMutableAudioBufferListPointer( UnsafeMutablePointer(bitPattern: 0x1234_5678)) expectNotEmpty(ablPtrWrapper) expectEqual( UnsafePointer(bitPattern: 0x1234_5678), ablPtrWrapper!.unsafePointer) expectEqual( UnsafePointer(bitPattern: 0x1234_5678), ablPtrWrapper!.unsafeMutablePointer) } } CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.count") { let sizeInBytes = AudioBufferList.sizeInBytes(maximumBuffers: 16) let rawPtr = UnsafeMutableRawPointer.allocate( bytes: sizeInBytes, alignedTo: alignof(AudioBufferList.self)) let ablPtr = rawPtr.bindMemory(to: AudioBufferList.self, capacity: sizeInBytes / strideof(AudioBufferList.self)) // It is important that 'ablPtrWrapper' is a 'let'. We are verifying that // the 'count' property has a nonmutating setter. let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(ablPtr) // Test getter. rawPtr.storeBytes(of: 0x1234_5678, as: UInt32.self) expectEqual(0x1234_5678, ablPtrWrapper.count) // Test setter. ablPtrWrapper.count = 0x7765_4321 expectEqual(0x7765_4321, rawPtr.load(as: UInt32.self)) rawPtr.deallocate( bytes: sizeInBytes, alignedTo: alignof(AudioBufferList.self)) } CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)") { let sizeInBytes = AudioBufferList.sizeInBytes(maximumBuffers: 16) let rawPtr = UnsafeMutableRawPointer.allocate( bytes: sizeInBytes, alignedTo: 1) let ablPtr = rawPtr.bindMemory( to: AudioBufferList.self, capacity: sizeInBytes / sizeof(AudioBufferList.self)) // It is important that 'ablPtrWrapper' is a 'let'. We are verifying that // the subscript has a nonmutating setter. let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(ablPtr) do { // Test getter. let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678)) let bufPtr = (rawPtr + ablHeaderSize).assumingMemoryBound( to: AudioBuffer.self) bufPtr.pointee = audioBuffer ablPtrWrapper.count = 1 expectEqual(2, ablPtrWrapper[0].mNumberChannels) expectEqual(1024, ablPtrWrapper[0].mDataByteSize) expectEqual(audioBuffer.mData, ablPtrWrapper[0].mData) } do { // Test setter. let audioBuffer = AudioBuffer( mNumberChannels: 5, mDataByteSize: 256, mData: UnsafeMutableRawPointer(bitPattern: 0x8765_4321 as UInt)) ablPtrWrapper.count = 2 ablPtrWrapper[1] = audioBuffer let audioBufferPtr = (rawPtr + ablHeaderSize).assumingMemoryBound( to: AudioBuffer.self) + 1 expectEqual(5, audioBufferPtr.pointee.mNumberChannels) expectEqual(256, audioBufferPtr.pointee.mDataByteSize) expectEqual(audioBuffer.mData, audioBufferPtr.pointee.mData) } ablPtr.deallocate(capacity: sizeInBytes) } CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)/trap") { let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 4) ablPtrWrapper[0].mNumberChannels = 42 ablPtrWrapper[1].mNumberChannels = 42 ablPtrWrapper[2].mNumberChannels = 42 ablPtrWrapper[3].mNumberChannels = 42 expectCrashLater() ablPtrWrapper[4].mNumberChannels = 42 } CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer/Collection") { var ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 16) expectType(UnsafeMutableAudioBufferListPointer.self, &ablPtrWrapper) var expected: [AudioBuffer] = [] for i in 0..<16 { let audioBuffer = AudioBuffer( mNumberChannels: UInt32(2 + i), mDataByteSize: UInt32(1024 * i), mData: UnsafeMutableRawPointer(bitPattern: 0x1234_5678 + i * 10)) ablPtrWrapper[i] = audioBuffer expected.append(audioBuffer) } // FIXME: use checkMutableRandomAccessCollection, when we have that function. checkRandomAccessCollection(expected, ablPtrWrapper) free(ablPtrWrapper.unsafeMutablePointer) } runAllTests()