Skip to content

Xcode 14 Beta and fatal error when initializing FixedWidthIntegers  #21

@adamtow

Description

@adamtow

Running the Xcode 14 beta, I'm seeing fatal errors when initializing variables from messages sent from the ATEM. Seems like the code here is triggering the error:

init(from slice: ArraySlice<UInt8>) {
	self.init(bigEndian: slice.withUnsafeBufferPointer {
		$0.baseAddress!.withMemoryRebound(to: Self.self, capacity: 1) {$0.pointee}
	})
}

Building the same code using Xcode 13.4.1 does not result in an error when running.

This particular message causes an error to happen is AEBP which returns information when a Fairlight Audio Mixer Source Equalizer Band has changed:

extension Message.Did {
	/// Informs a controller that a source's equalizer settings have changed
	public struct ChangeFairlightMixerSourceEqualizerBand: SerializableMessage {
		public static let title = Message.Title(string: "AEBP")

		public let index: AudioSource
		public let sourceId: Int64
		public let band: UInt8
		public let bandEnabled: Bool
		public let supportedShapes: FairlightEqualizerBandShape
		public let shape: FairlightEqualizerBandShape
		public let supportedFrequencyRanges: FairlightEqualizerFrequencyRange
		public let frequencyRange: FairlightEqualizerFrequencyRange
		public let frequency: UInt32
		public let gain: Int32
		public let qFactor: Int16

		public init(with bytes: ArraySlice<UInt8>) throws {
			self.index = AudioSource(rawValue: UInt16(from: bytes[relative: Position.index]))
			self.sourceId = Int64(from: bytes[relative: Position.sourceId])
			self.band = bytes[relative: Position.band]
			self.bandEnabled = bytes[relative: Position.bandEnabled].firstBit
			self.supportedShapes = FairlightEqualizerBandShape(rawValue: bytes[relative: Position.supportedShapes])
			self.shape = FairlightEqualizerBandShape(rawValue: bytes[relative: Position.shape])
			self.supportedFrequencyRanges = FairlightEqualizerFrequencyRange(rawValue: bytes[relative: Position.supportedFrequencyRanges])
			self.frequencyRange = FairlightEqualizerFrequencyRange(rawValue: bytes[relative: Position.frequencyRange])
			self.frequency = UInt32(from: bytes[relative: Position.frequency])
			self.gain = Int32(from: bytes[relative: Position.gain])
			self.qFactor = Int16(from: bytes[relative: Position.qFactor])
		}

		public init(index: AudioSource, sourceId: Int64, band: UInt8, bandEnabled: Bool, supportedShapes: FairlightEqualizerBandShape, shape: FairlightEqualizerBandShape, supportedFrequencyRanges: FairlightEqualizerFrequencyRange, frequencyRange: FairlightEqualizerFrequencyRange, frequency: UInt32, gain: Int32, qFactor: Int16) {
			self.index = index
			self.sourceId = sourceId
			self.band = band
			self.bandEnabled = bandEnabled
			self.supportedShapes = supportedShapes
			self.shape = shape
			self.supportedFrequencyRanges = supportedFrequencyRanges
			self.frequencyRange = frequencyRange
			self.frequency = frequency
			self.gain = gain
			self.qFactor = qFactor
		}

		public var dataBytes: [UInt8] {
			.init(unsafeUninitializedCapacity: 36) { (buffer, count) in
				buffer.write(index.rawValue.bigEndian, at: Position.index.lowerBound)
				buffer.write(sourceId.bigEndian, at: Position.sourceId.lowerBound)
				buffer[Position.band] = band
				buffer[Position.bandEnabled] = bandEnabled ? 1 : 0
				buffer[Position.supportedShapes] = supportedShapes.rawValue
				buffer[Position.shape] = shape.rawValue
				buffer[Position.supportedFrequencyRanges] = supportedFrequencyRanges.rawValue
				buffer[Position.frequencyRange] = frequencyRange.rawValue
				buffer.write(frequency.bigEndian, at: Position.frequency.lowerBound)
				buffer.write(gain.bigEndian, at: Position.gain.lowerBound)
				buffer.write(qFactor.bigEndian, at: Position.qFactor.lowerBound)
				count = 36
			}
		}

		public var debugDescription: String { return """
Did.ChangeFairlightMixerSourceEqualizerBand {
	index: \(index),
	sourceId: \(sourceId),
	band: \(band),
	bandEnabled: \(bandEnabled),
	supportedShapes: \(supportedShapes),
	shape: \(shape),
	supportedFrequencyRanges: \(supportedFrequencyRanges),
	frequencyRange: \(frequencyRange),
	frequency: \(frequency),
	gain: \(gain),
	qFactor: \(qFactor),
}
"""
		}
		
		enum Position {
			static let index = 0..<2
			static let sourceId = 8..<16
			static let band = 16
			static let bandEnabled = 17
			static let supportedShapes = 18
			static let shape = 19
			static let supportedFrequencyRanges = 20
			static let frequencyRange = 21
			static let frequency = 24..<28
			static let gain = 28..<32
			static let qFactor = 32..<34
		}
	}
}

and the code to call it out:

import Foundation
import Atem

var enabled: Bool = false

let address: String
if CommandLine.arguments.count > 1 {
	address = CommandLine.arguments[1]
} else {
	print("Enter switcher IP address: ", terminator: "")
	address = readLine() ?? "10.1.0.210"
}
print("Trying to connect to switcher with IP address", address)

let controller = try Controller(ipAddress: address) { connection in
	connection.when { (change: Did.ChangeFairlightMixerSourceEqualizerBand) in
		print(change)
	}

	connection.when { (connected: Config.InitiationComplete) in
		print(connected)
		print("Type 0 or 1 and <enter> to change the Audio Follow Video setting.")
	}
	
	connection.whenDisconnected = {
		print("Disconnected")
	}
}

while true {
	_ = readLine() ?? "1"
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions