我正在使用Swift在OSX上开发音频效果应用程序,我对集成音高效果感兴趣.
我希望能够实时地将音调调高或调高八度.目前我只收到一个干燥的信号.
我不确定这是否可行,并且想知道这是否可能,或者任何人可能有任何帮助或建议.
与该问题相关的当前代码如下:
import Cocoa
import AVFoundation
class ViewController: NSViewController {
var engine = AVAudioEngine()
var timePitch = AVAudioUnitTimePitch()
override func viewDidLoad() {
timePitch.pitch = 1200
// Setup engine and node instances
var mixer = engine.mainMixerNode
var input = engine.inputNode
var output = engine.outputNode
var format = input.inputFormatForBus(0)
var error:NSError?
engine.attachNode(timePitch)
engine.connect(input, to: timePitch, format: format)
engine.connect(timePitch, to: output, format: format)
engine.startAndReturnError(&error)
super.viewDidLoad()
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
} …Run Code Online (Sandbox Code Playgroud) 我有一个问题是通过UDP在swift中通过CocoaAsyncSocket发送音频.
首先,我运行下面的代码开始监听4444 UDP端口.
vlc --demux=rawaud --rawaud-channels=1 --rawaud-samplerate=48000 udp://@:4444
Run Code Online (Sandbox Code Playgroud)
之后我在iPad2上运行我的应用程序并按连接.
import UIKit
import CocoaAsyncSocket
import AVFoundation
class ViewController: UIViewController , GCDAsyncUdpSocketDelegate {
var avAudioEngine : AVAudioEngine?
@IBAction func btnAction(sender: UIButton) {
avAudioEngine = AVAudioEngine()
let input = avAudioEngine?.inputNode
let socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
do {
try socket.bindToPort(4445)
try socket.connectToHost("192.168.0.137",onPort : 4444)
try socket.beginReceiving()
input?.installTapOnBus(0, bufferSize: 2048, format: input?.inputFormatForBus(0), block: { (buffer : AVAudioPCMBuffer, timeE: AVAudioTime) -> Void in
socket.sendData(self.toNSData(buffer), withTimeout: 0, tag: 0)
})
avAudioEngine?.prepare()
try avAudioEngine?.start()
// with …Run Code Online (Sandbox Code Playgroud) 我正在使用AVAudioSession并AVAudioInputNode在 iOS 中录制语音。
为了初始化它,我使用了以下设置,效果很好:
[AVFormatIDKey: kAudioFormatLinearPCM, AVLinearPCMBitDepthKey: 16, AVLinearPCMIsFloatKey: true, AVSampleRateKey: Float64(8000), AVNumberOfChannelsKey: 1] as [String : Any]
Run Code Online (Sandbox Code Playgroud)
现在,在我的新 iPhone 11 Pro 中,使用此代码我会因以下错误而崩溃:
required condition is false: format.sampleRate == hwFormat.sampleRate
避免它的方法是从以下设置采样率AVSession:
[AVFormatIDKey: kAudioFormatLinearPCM, AVLinearPCMBitDepthKey: 16, AVLinearPCMIsFloatKey: true, AVSampleRateKey: AVAudioSession.sharedInstance().sampleRate, AVNumberOfChannelsKey: 1] as [String : Any]
Run Code Online (Sandbox Code Playgroud)
该代码适用于我的 iPhone 11 Pro,但现在它在其他设备上崩溃了。
知道如何为每个人修复它吗?为什么会这样?发生了什么变化?
谢谢!
avaudioplayer avaudiorecorder ios avaudiosession avaudioengine
我注意到它 AVAudioSession.sharedInstance().sampleRate是 48000,而AVAudioEngine().inputNode.inputFormat(forBus: 0)显示的采样率为 44100。当我这样做时,try AVAudioSession.sharedInstance().setPreferredSampleRate(16000)它设置的是输入节点采样率,而不是会话采样率。所以我的问题是,这两个采样率有什么区别?
我尝试以 16kHz 现场录制语音音频,但音频听起来失真且有金属感。我想知道这是否与这些采样率的不匹配有关。
我有两个课MicrophoneHandler,和AudioPlayer.我已成功地使用AVCaptureSession以核定答案挖掘麦克风数据在这里,并和改装CMSampleBuffer,以NSData使用此功能:
func sendDataToDelegate(buffer: CMSampleBuffer!)
{
let block = CMSampleBufferGetDataBuffer(buffer)
var length = 0
var data: UnsafeMutablePointer<Int8> = nil
var status = CMBlockBufferGetDataPointer(block!, 0, nil, &length, &data) // TODO: check for errors
let result = NSData(bytesNoCopy: data, length: length, freeWhenDone: false)
self.delegate.handleBuffer(result)
}
Run Code Online (Sandbox Code Playgroud)
我现在想通过扬声器播放音频通过转换NSData产生的上面AVAudioPCMBuffer,并用播放AVAudioEngine.我的AudioPlayer班级如下:
var engine: AVAudioEngine!
var playerNode: AVAudioPlayerNode!
var mixer: AVAudioMixerNode!
override init()
{
super.init()
self.setup()
self.start()
}
func …Run Code Online (Sandbox Code Playgroud) 我正试图通过Apples Multipeer Connectivity框架将音频从麦克风传输到另一部iPhone.要做到音频捕获和播放我使用AVAudioEngine(非常感谢艺术Fistman"的回答在这里).
我通过在输入上安装一个麦克风来接收来自麦克风的数据,从中我得到一个AVAudioPCMBuffer,然后我将其转换为一个UInt8数组,然后我将其流式传输到另一部手机.
但是当我将数组转换回AVAudioPCMBuffer时,我得到一个EXC_BAD_ACCESS异常,编译器指向我再次将字节数组转换为AVAudioPCMBuffer的方法.
以下是我正在处理,转换和流式传输输入的代码:
input.installTap(onBus: 0, bufferSize: 2048, format: input.inputFormat(forBus: 0), block: {
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
let audioBuffer = self.typetobinary(buffer)
stream.write(audioBuffer, maxLength: audioBuffer.count)
})
Run Code Online (Sandbox Code Playgroud)
我对将数据转换两种功能(摘自Martin.R的答案在这里):
func binarytotype <T> (_ value: [UInt8], _: T.Type) -> T {
return value.withUnsafeBufferPointer {
UnsafeRawPointer($0.baseAddress!).load(as: T.self)
}
}
func typetobinary<T>(_ value: T) -> [UInt8] {
var data = [UInt8](repeating: 0, count: MemoryLayout<T>.size)
data.withUnsafeMutableBufferPointer {
UnsafeMutableRawPointer($0.baseAddress!).storeBytes(of: value, as: T.self)
}
return data …Run Code Online (Sandbox Code Playgroud) 为了同时进行可用的播放和录制,我们使用这些方法来设置AVAudioSession类别:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:NULL];
Run Code Online (Sandbox Code Playgroud)
通过这样做,输出音频端口从线路输出扬声器切换到内置扬声器.在循环录制窗口中,我们需要同时从线路输出扬声器和麦克风录音进行播放.要在设置AVAudioSession类别后从线路输出扬声器播放声音,我们使用一种设置输出音频端口的方法:
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
我们尝试使用AVAudio Engine安排录制和播放.AVAudioEngine连接结构:
// input->inputMixer->mainEqualizer ->tap
// 0 0 |0
// |
// |
// |0 0 0
// recordPlayerNode?recordMixer?meteringMixer?|
// 0 1 0 0 |
// |->mainMixer->out
// |
// volumePlayer?|
// 0 1
Run Code Online (Sandbox Code Playgroud)
执行overrideOutputAudioPort后,录制功能将停止在iPhone 6S及更高版本上运行.我们以这种方式进行录制:
if(self.isHeadsetPluggedIn)
{
volumePlayer.volume = 1;
}
else
{
volumePlayer.volume = 0.000001;
}
[volumePlayer play];
[mainEqualizer installTapOnBus:0 bufferSize:0 format:tempAudioFile.processingFormat block:^(AVAudioPCMBuffer *buf, AVAudioTime *when)
{ …Run Code Online (Sandbox Code Playgroud) 我正在尝试将音频缓冲区转换为不同的格式,并且我正在使用 AVAudioConverter。当您具有相同的采样率并且不需要使用 AVAudioConverterInputBlock 时,AVAudioConverter 会完成这项工作。
但是如果我处理相同的采样率,我的音频数据会出现奇怪的口吃。我有一种感觉,我没有很好地处理输入块。输出有重复两到三遍的单词。下面是完整的方法:
func sendAudio(audioFile: URL, completionHandler: @escaping (Bool, Bool, Data?)->Void) {
createSession(){ sessionUrl, observeURL, session in
let file = try! AVAudioFile(forReading: audioFile)
let formatOfAudio = file.processingFormat
self.engine = AVAudioEngine()
guard let input = self.engine.inputNode else {
print("no input")
return
}
//The audio in format in this case is: <AVAudioFormat 0x61800009d010: 2 ch, 44100 Hz, Float32, non-inter>
let formatIn = formatOfAudio
let formatOut = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 16000, channels: 1, interleaved: true)
let mixer = AVAudioMixerNode()
self.engine.attach(mixer) …Run Code Online (Sandbox Code Playgroud) 我最近发布了这个关于在 iOS 上使用多路由的问题,我以为我解决了它,但是我发现它不太有效:AVAudioEngine Multichannel mapping
我遇到的问题是多路由仅适用于前两个输出通道。我正在尝试使其适用于 4 通道音频接口。
我已经设法使用 AVAudioPlayer 将音频路由到 USB 接口的每个输出:
var avplayer = AVAudioPlayer()
@IBAction func avAudioPlayerPlay(_ sender: Any)
{
let audioSession = AVAudioSession.sharedInstance()
let route = audioSession.currentRoute
// set the session category
do
{
//try audioSession.setCategory(.multiRoute)
try audioSession.setCategory(.multiRoute, options: .mixWithOthers)
}
catch
{
print("unable to set category", error)
return
}
// activate the audio session - turns on multiroute I believe
do
{
try audioSession.setActive(true)
//try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
}
catch
{
print("unable to set …Run Code Online (Sandbox Code Playgroud) 我正在尝试将录制的音频(从AVAudioEngine inputNode)同步到录制过程中正在播放的音频文件。结果应该类似于多轨录音,其中每个后续新音轨都与录制时正在播放的先前音轨同步。
因为sampleTime在不同之间AVAudioEngine的输出和输入节点,我使用hostTime确定偏移原始音频和输入缓冲器。
在 iOS 上,我会假设我必须使用AVAudioSession的各种延迟属性 ( inputLatency, outputLatency, ioBufferDuration) 来协调轨道以及主机时间偏移,但我还没有想出使它们工作的神奇组合。这同样适用于各种AVAudioEngine和Node属性,如latency和presentationLatency.
在 macOS 上,AVAudioSession不存在(在 Catalyst 之外),这意味着我无法访问这些数字。同时,latency/presentationLatency属性在大多数情况下会AVAudioNodes报告0.0。在 macOS 上,我确实可以访问AudioObjectGetPropertyData并且可以向系统询问kAudioDevicePropertyLatency, kAudioDevicePropertyBufferSize、kAudioDevicePropertySafetyOffset等,但是对于协调所有这些的公式又有点不知所措。
我在https://github.com/jnpdx/AudioEngineLoopbackLatencyTest上有一个示例项目,它运行一个简单的环回测试(在 macOS、iOS 或 Mac Catalyst 上)并显示结果。在我的 Mac 上,轨道之间的偏移量约为 720 个样本。在其他人的 Mac 上,我看到多达 1500 个样本偏移。
在我的 iPhone 上,我可以通过使用AVAudioSession's outputLatency+使它接近完美的样本 …
avaudioengine ×10
swift ×8
ios ×7
avfoundation ×4
audio ×2
core-audio ×1
mac-catalyst ×1
objective-c ×1
pitch ×1
swift3 ×1
udp ×1