From df76bcca6c5b7220c806a733a24bea4cfa8ec538 Mon Sep 17 00:00:00 2001 From: shogo4405 Date: Thu, 25 Apr 2024 20:20:09 +0900 Subject: [PATCH] Add volume control feature by track. --- .../AVAudioPCMBuffer+Extension.swift | 38 ++++++++++++++++++- Sources/IO/IOAudioMixerTrack.swift | 19 +++------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/Sources/Extension/AVAudioPCMBuffer+Extension.swift b/Sources/Extension/AVAudioPCMBuffer+Extension.swift index b24e7cf4c..67f839fa4 100644 --- a/Sources/Extension/AVAudioPCMBuffer+Extension.swift +++ b/Sources/Extension/AVAudioPCMBuffer+Extension.swift @@ -1,3 +1,4 @@ +import Accelerate import AVFoundation extension AVAudioPCMBuffer { @@ -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 @@ -70,6 +71,7 @@ extension AVAudioPCMBuffer { } @discardableResult + @inlinable final func muted(_ isMuted: Bool) -> AVAudioPCMBuffer { guard isMuted else { return self @@ -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.. { 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: