mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-05-07 20:12:28 +00:00
79 lines
3.0 KiB
Swift
79 lines
3.0 KiB
Swift
import AVFoundation
|
|
import Foundation
|
|
|
|
/// Constraints on the audio mixier settings.
|
|
public struct AudioMixerSettings: Codable, Sendable {
|
|
/// The default value.
|
|
public static let `default` = AudioMixerSettings()
|
|
/// Maximum sampleRate supported by the system
|
|
public static let maximumSampleRate: Float64 = 48000.0
|
|
|
|
#if os(macOS)
|
|
static let commonFormat: AVAudioCommonFormat = .pcmFormatFloat32
|
|
#else
|
|
static let commonFormat: AVAudioCommonFormat = .pcmFormatInt16
|
|
#endif
|
|
|
|
/// Specifies the sampleRate of audio output. A value of 0 will be the same as the main track source.
|
|
public let sampleRate: Float64
|
|
|
|
/// Specifies the channels of audio output. A value of 0 will be the same as the main track source.
|
|
/// - Warning: If you are using IOStreamRecorder, please set it to 1 or 2. Otherwise, the audio will not be saved in local recordings.
|
|
public let channels: UInt32
|
|
|
|
/// Specifies the muted that indicates whether the audio output is muted.
|
|
public var isMuted: Bool
|
|
|
|
/// Specifies the main track number.
|
|
public var mainTrack: UInt8
|
|
|
|
/// Specifies the track settings.
|
|
public var tracks: [UInt8: AudioMixerTrackSettings]
|
|
|
|
/// Specifies the maximum number of channels supported by the system
|
|
/// - Description: The maximum number of channels to be used when the number of channels is 0 (not set). More than 2 channels are not supported by the service. It is defined to prevent audio issues since recording does not support more than 2 channels.
|
|
public var maximumNumberOfChannels: UInt32 = 2
|
|
|
|
/// Creates a new instance of a settings.
|
|
public init(
|
|
sampleRate: Float64 = 0,
|
|
channels: UInt32 = 0,
|
|
isMuted: Bool = false,
|
|
mainTrack: UInt8 = 0,
|
|
tracks: [UInt8: AudioMixerTrackSettings] = .init()
|
|
) {
|
|
self.sampleRate = sampleRate
|
|
self.channels = channels
|
|
self.isMuted = isMuted
|
|
self.mainTrack = mainTrack
|
|
self.tracks = tracks
|
|
}
|
|
|
|
func invalidateOutputFormat(_ oldValue: Self) -> Bool {
|
|
return !(sampleRate == oldValue.sampleRate &&
|
|
channels == oldValue.channels)
|
|
}
|
|
|
|
func makeOutputFormat(_ formatDescription: CMFormatDescription?) -> AVAudioFormat? {
|
|
guard let format = AVAudioUtil.makeAudioFormat(formatDescription) else {
|
|
return nil
|
|
}
|
|
let sampleRate = min(sampleRate == 0 ? format.sampleRate : sampleRate, Self.maximumSampleRate)
|
|
let channelCount = channels == 0 ? min(format.channelCount, maximumNumberOfChannels) : channels
|
|
if let channelLayout = AVAudioUtil.makeChannelLayout(channelCount) {
|
|
return .init(
|
|
commonFormat: Self.commonFormat,
|
|
sampleRate: sampleRate,
|
|
interleaved: format.isInterleaved,
|
|
channelLayout: channelLayout
|
|
)
|
|
}
|
|
return .init(
|
|
commonFormat: Self.commonFormat,
|
|
sampleRate: sampleRate,
|
|
channels: min(channelCount, 2),
|
|
interleaved: format.isInterleaved
|
|
)
|
|
}
|
|
}
|