我想AVAudioInputNode使用音频单元效果 ( AVAudioUnitEffect)处理来自设备内置麦克风 ( ) 的音频。对于我的示例,我使用AVAudioUnitReverb. 连接AVAudioUnitReverb导致应用程序崩溃。
import UIKit
import AVFoundation
class ViewController: UIViewController {
let audioEngine = AVAudioEngine()
let unitReverb = AVAudioUnitReverb()
var inputNode: AVAudioInputNode!
override func viewDidLoad() {
super.viewDidLoad()
inputNode = audioEngine.inputNode
audioEngine.attachNode(unitReverb)
let inputFormat = inputNode.inputFormatForBus(0)
audioEngine.connect(inputNode, to: unitReverb, format: inputFormat)
// This line is crashing the application!
// With this error "AVAudioNode.mm:521: AUSetFormat: error -10868"
audioEngine.connect(unitReverb, to: audioEngine.outputNode, format: inputFormat)
audioEngine.startAndReturnError(nil)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我绕过混响并inputNode直接连接到audioEngine.outputNode,我没有问题,但是我没有混响:
audioEngine.connect(inputNode, …
正如标题所示。
Swift 中有一个旧的解决方案here。但我很难转换到 Objective-C。似乎没有 Objective-C 的等价物UnsafeBufferPointer
我需要播放声音并能够从缓冲区录制旋律。但我不明白如何设置AVAudioSession类别和/或AVAudioPlayerNode实现我的目标。声音在播放器节点中安排。如果我理解正确的话,AVAudioRecorder仅从麦克风录制,而不是用 播放的音乐AVAudioPlayerNode。所以,这是我的尝试:首先我设置一个会话:
NSError *error = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:&error];
if (error) {
NSLog(@"AVAudioSession error %ld, %@", error.code, error.localizedDescription);
}
[audioSession setActive:YES error:&error];
if (error) {
NSLog(@"AVAudioSession error %ld, %@", error.code, error.localizedDescription);
}
Run Code Online (Sandbox Code Playgroud)
建立一个文件进行记录:
NSString* docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"Recording.caf"];
NSURL* url = [NSURL fileURLWithPath:docs];
NSError* error = nil;
self.fileForRecording = [[AVAudioFile alloc] initForWriting:url
settings:[self.engine.inputNode inputFormatForBus:0].settings
error:&error];
if (error) {
NSLog(@"CREATE FILE ERROR %@", …Run Code Online (Sandbox Code Playgroud) 每当代码到达时
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {[weak self] (buffer:AVAudioPCMBuffer, when:AVAudioTime),应用程序就会因以下错误而崩溃
由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“所需条件为假:format.sampleRate == hwFormat.sampleRate”
在添加另一个之前,我已经厌倦了移除水龙头,并且我确保我不会添加多个水龙头。奇怪的是,该应用程序在低于 12 的 iOS 上运行良好,并且在所有模拟器上运行良好。
它仅在使用 iOS 12 的真实设备上崩溃。我尝试寻找解决方案但找不到任何东西。
我在 iOS 游戏应用程序中使用 AVAudioEngine 来处理音频。我遇到的一个问题是 AVAudioPlayerNode.play() 需要很长时间才能执行,这在游戏等实时应用程序中可能会出现问题。
play() 只是激活播放器节点 - 您不必每次播放声音时都调用它。因此,不必经常调用它,但必须偶尔调用它,例如最初激活播放器,或在停用播放器后(在某些情况下会发生这种情况)。即使只是偶尔调用,较长的执行时间也可能是一个问题,特别是当您需要同时对多个玩家调用 play() 时。
play() 的执行时间似乎与 AVAudioSession.ioBufferDuration 的值成正比,您可以使用 AVAudioSession.setPreferredIOBufferDuration() 请求更改该值。这是我用来测试这个的一些代码:
import AVFoundation
import UIKit
class ViewController: UIViewController {
private let engine = AVAudioEngine()
private let player = AVAudioPlayerNode()
private let ioBufferSize = 1024.0 // Or 256.0
override func viewDidLoad() {
super.viewDidLoad()
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setPreferredIOBufferDuration(ioBufferSize / 44100.0)
try! audioSession.setActive(true)
engine.attach(player)
engine.connect(player, to: engine.mainMixerNode, format: nil)
try! engine.start()
print("IO buffer duration: \(audioSession.ioBufferDuration)")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: …Run Code Online (Sandbox Code Playgroud) 我对iOS8中的新音频引擎存在严重问题.我有一个使用AVAudioPlayer构建的应用程序,我试图找到一种迁移到新架构的方法,但是我遇到了以下问题(我相信你会同意,这是一个严重的基本障碍) :
我的头文件:
AVAudioEngine *engine;
AVAudioMixerNode *mainMixer;
AVAudioPlayerNode *player;
Run Code Online (Sandbox Code Playgroud)
我的m文件(在viewDidLoad中):
engine = [[AVAudioEngine alloc] init];
player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp3"]];
AVAudioFile *file = [[AVAudioFile alloc] initForReading:fileUrl error:nil];
NSLog(@"duration: %.2f", file.length / file.fileFormat.sampleRate);
[player scheduleFile:file atTime:nil completionHandler:^{
AVAudioTime *nodeTime = player.lastRenderTime;
AVAudioTime *playerTime = [player playerTimeForNodeTime:nodeTime];
float secs = (float)playerTime.sampleTime / file.fileFormat.sampleRate;
NSLog(@"finished at: %.2f", secs);
}];
mainMixer = [engine mainMixerNode];
[engine connect:player to:mainMixer format:file.processingFormat];
[engine startAndReturnError:nil];
[player play];
Run Code Online (Sandbox Code Playgroud)
上面的代码初始化引擎和节点,然后开始播放我正在使用的任何文件.首先,它打印出音乐文件的持续时间,然后,在完成播放后,在回调函数中,它打印播放器的当前时间.这两个应该是相同的或者在最坏的情况下,彼此非常非常接近,但事实并非如此,这两个值之间的差异非常大,例如 …
avaudioplayer ios8 avaudioengine avaudiofile avaudioplayernode
我正在尝试播放具有不同效果的声音.在之前的viewController中我录制了一个声音,然后在下一个屏幕中,它可以用效果播放.第一次它工作正常但第二次崩溃时出现如下错误:
2015-08-07 13:00:45.900 Pitch Perfect [9643:1121173] 13:00:45.900错误:AVAudioEngine.mm:253:AttachNode:必需条件为false:!nodeimpl-> HasEngineImpl()2015-08-07 13 :00:45.953 Pitch Perfect [9643:1121173]由于未捕获的异常'com.apple.coreaudio.avfaudio'而终止应用程序,原因:'必需条件为false:!nodeimpl-> HasEngineImpl()'
import UIKit
import AVFoundation
class PlaySoundsViewController: UIViewController, AVAudioPlayerDelegate {
var receivedAudio:RecordedAudio!
var audioPlayer: AVAudioPlayer!
var disabledButton:UIButton!
var firstTime:Bool = true
var audioEngine:AVAudioEngine!
var audioFile:AVAudioFile!
var audioPlayerNode:AVAudioPlayerNode!
var audioStopped:Bool!
var typeOfSound:IntegerLiteralType!
@IBOutlet weak var stopButton: UIButton!
@IBOutlet weak var reverbButton: UIButton!
@IBOutlet weak var echoButton: UIButton!
@IBOutlet weak var darthButton: UIButton!
@IBOutlet weak var chipmonkButton: UIButton!
@IBOutlet weak var snailButton: UIButton!
@IBOutlet weak var rabbitButton: UIButton!
override …Run Code Online (Sandbox Code Playgroud) 我们如何使用AVAudioPlayerNode/访问 Apple Music 库中的歌曲以AVAudioEngine进行播放和处理?
我在苹果论坛上问过这个问题。
我想在我的iOS上使用Swift 3处理从麦克风读取的字节.我目前使用的是AVAudioEngine.
print(inputNode.inputFormat(forBus: bus).settings)
print(inputNode.inputFormat(forBus: bus).formatDescription)
Run Code Online (Sandbox Code Playgroud)
这给了我以下输出:
["AVNumberOfChannelsKey": 1, "AVLinearPCMBitDepthKey": 32, "AVSampleRateKey": 16000, "AVLinearPCMIsNonInterleaved": 1, "AVLinearPCMIsBigEndianKey": 0, "AVFormatIDKey": 1819304813, "AVLinearPCMIsFloatKey": 1]
<CMAudioFormatDescription 0x14d5bbb0 [0x3a5fb7d8]> {
mediaType:'soun'
mediaSubType:'lpcm'
mediaSpecific: {
ASBD: {
mSampleRate: 16000.000000
mFormatID: 'lpcm'
mFormatFlags: 0x29
mBytesPerPacket: 4
mFramesPerPacket: 1
mBytesPerFrame: 4
mChannelsPerFrame: 1
mBitsPerChannel: 32 }
cookie: {(null)}
ACL: {(null)}
FormatList Array: {(null)}
}
extensions: {(null)}
}
Run Code Online (Sandbox Code Playgroud)
问题是我想要发送数据的服务器不期望32位浮点数而是16位无符号整数.我想我必须改变mFormatFlags.有谁知道我怎么能这样做,什么价值是正确的?
生成的字节流应该等同于我在android上使用的字节流
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLES_PER_SECOND,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
recordSegmentSizeBytes);
Run Code Online (Sandbox Code Playgroud)
我试过这个:
let cfmt = AVAudioCommonFormat.pcmFormatInt16
inputNode.inputFormat(forBus: bus) = AVAudioFormat(commonFormat: cfmt, …Run Code Online (Sandbox Code Playgroud) 问题1
我的第一个问题是将an AVAudioPlayerNode和an AVAudioSequencer用于MIDI 时的播放同步。基本上,我试图通过MIDI播放某些东西,但是它们需要完全同步。
我知道AVAudioPlayerNodes 有同步方法,但是音序器似乎没有这样的东西。
目前,我已经尝试在单独的线程上使用CAMediaTime() + delay和usleep,但是它们似乎不能很好地工作。
问题2我正在使用上的水龙头engine.inputNode来获取录音,与音乐播放分开。但是,录音似乎开始得较早。当我将记录的数据与原始播放进行比较时,相差大约300毫秒。我可以在300毫秒后开始记录,但是即使那样,也不能保证精确的同步,并且可能与机器有关。
所以我的问题是,什么是确保在播放开始时准确开始录制的好方法?
目前我正在使用 AVAudioEngine 从麦克风获取音频样本并成功实现 FFT。为了获得稳定的频率值,我还在 FFT 之前对音频样本实现了 Hann 窗。现在我想对音频样本实施低通滤波器以消除高频。我做了一些关于 iOS 中低通滤波器的研究,但大多数答案都是通过 AVAudioUnit 找到的。这让我很困惑,是否可以仅在 AVAudioEngine 中实现低通滤波器?可以对音频样本应用低通滤波器吗?如果是,我们需要遵循哪种方法?提前致谢。
avaudioengine ×11
ios ×8
swift ×6
avfoundation ×4
avaudiofile ×2
iphone ×2
apple-music ×1
core-audio ×1
ios8 ×1
objective-c ×1