Skip to content

Commit

Permalink
Add volume control feature by track.
Browse files Browse the repository at this point in the history
  • Loading branch information
shogo4405 committed Apr 25, 2024
1 parent 25e5f2c commit df76bcc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 14 deletions.
38 changes: 37 additions & 1 deletion Sources/Extension/AVAudioPCMBuffer+Extension.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Accelerate
import AVFoundation

extension AVAudioPCMBuffer {
Expand Down Expand Up @@ -34,7 +35,7 @@ extension AVAudioPCMBuffer {
}

@discardableResult
@inline(__always)
@inlinable
final func copy(_ audioBuffer: AVAudioBuffer) -> Bool {
guard let audioBuffer = audioBuffer as? AVAudioPCMBuffer, frameLength == audioBuffer.frameLength else {
return false
Expand Down Expand Up @@ -70,6 +71,7 @@ extension AVAudioPCMBuffer {
}

@discardableResult
@inlinable
final func muted(_ isMuted: Bool) -> AVAudioPCMBuffer {
guard isMuted else {
return self
Expand Down Expand Up @@ -103,4 +105,38 @@ extension AVAudioPCMBuffer {
}
return self
}

@inlinable
final func volume(_ value: Float) -> Self {
guard value < 1.0 && format.commonFormat == .pcmFormatFloat32 else {
return self
}
var count = value
if format.isInterleaved {
if let floatChannelData = floatChannelData?[0] {
vDSP_vsmul(
floatChannelData,
1,
&count,
floatChannelData,
1,
UInt(frameLength * format.channelCount)
)
}
} else {
for i in 0..<Int(format.channelCount) {
if let floatChannelData = floatChannelData?[i] {
vDSP_vsmul(
floatChannelData,
1,
&count,
floatChannelData,
1,
UInt(frameLength)
)
}
}
}
return self
}
}
19 changes: 6 additions & 13 deletions Sources/IO/IOAudioMixerTrack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ protocol IOAudioMixerTrackDelegate: AnyObject {

/// Constraints on the audio mixier track's settings.
public struct IOAudioMixerTrackSettings: Codable {
/// Specifies the volume for output.
public var volume: Float = 1.0

/// Specifies the muted that indicates whether the audio output is muted.
public var isMuted: Bool
public var isMuted = false

/// Specifies the mixes the channels or not. Currently, it supports input sources with 4, 5, 6, and 8 channels.
public var downmix: Bool
public var downmix = true

/// Specifies the map of the output to input channels.
/// ## Example code:
Expand All @@ -25,16 +28,6 @@ public struct IOAudioMixerTrackSettings: Codable {
/// ```
public var channelMap: [Int]?

/// Creates a new instance of a settings.
public init(
isMuted: Bool = false,
downmix: Bool = true,
channelMap: [Int]? = nil) {
self.isMuted = isMuted
self.downmix = downmix
self.channelMap = channelMap
}

func apply(_ converter: AVAudioConverter?, oldValue: IOAudioMixerTrackSettings?) {
guard let converter else {
return
Expand Down Expand Up @@ -205,7 +198,7 @@ final class IOAudioMixerTrack<T: IOAudioMixerTrackDelegate> {
case .haveData:
let time = AVAudioTime(sampleTime: sampleTime, atRate: outputBuffer.format.sampleRate)
if let anchor, let when = time.extrapolateTime(fromAnchor: anchor) {
delegate?.track(self, didOutput: outputBuffer.muted(settings.isMuted), when: when)
delegate?.track(self, didOutput: outputBuffer.volume(settings.volume).muted(settings.isMuted), when: when)
}
sampleTime += 1024
case .error:
Expand Down

0 comments on commit df76bcc

Please sign in to comment.