这一定是我遇到过的核心音频中最神秘的错误。当我在音频单元的输出上发送格式时,为什么会收到此错误?
是因为音频单元确实支持我正在使用的流格式,还是因为我所在的平台(即iOS)不支持该格式?
如果是前者,每个音频单元是否只支持特定格式?如果是这样,我在哪里可以找到该信息?
我正在尝试建立对音频单元和音频图的直观理解。这基本上是有道理的,但流格式却非常神秘。
我正在编写一个使用 CoreAudio 的音频单元 API 的 iOS 应用程序,并且在某个时刻我会进行调用AudioUnitGetProperty(audioUnit, kAudioUnitProperty_StreamFormat, ...)。此时我设置了一个断点来查看 ASBD,我发现该mFormatFlags字段是41. 问题是,我可以从该数字中解码实际的标志名称(例如kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked | ...)吗?
多谢。
我正在用 Audio Units 编写一个简单的 iOS 应用程序。我想添加混响效果。所以图形看起来像 RemoteIO_Input -> Reverb -> RemoveIO_Output。但是在尝试为混响单元设置流格式时出现错误 - kAudioUnitErr_FormatNotSupported。该代码在不使用混响单元(图形中的单个远程 IO)的情况下工作正常,因此其他配置似乎很好,我没有提供他们的代码。
UPD:使用 iOS 6
所以问题:
允许的格式有限制吗?
我应该使用什么格式参数?
应该在 RemoteIO 输出元素的任何范围内设置格式吗?
谢谢关注。
代码: 说明:
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
descRev.componentType = kAudioUnitType_Effect;
descRev.componentSubType = kAudioUnitSubType_Reverb2;
descRev.componentFlags = 0;
descRev.componentFlagsMask = 0;
descRev.componentManufacturer = kAudioUnitManufacturer_Apple;
Run Code Online (Sandbox Code Playgroud)
图表设置
NewAUGraph(&graph);
AUNode ioNode;
AUNode rNode;
AUGraphAddNode(graph, &desc, &ioNode);
AUGraphAddNode(graph, &descRev, &rNode);
AUGraphOpen(graph);
AUGraphConnectNodeInput(graph, ioNode, 1, rNode, 0);
AUGraphConnectNodeInput(graph, rNode, 0, ioNode, 0); …Run Code Online (Sandbox Code Playgroud) 我正在尝试为远程 I/O 音频单元的输入流设置不同的采样率(如 32kHz、24kHz 等)。但是输出总是以这些采样率之一播放 - 22.05kHz、33.1kHz、11.0kHz,无论我设置什么。令人奇怪的是,当我叫 AudioUnitGetProperty上kAudioUnitScope_Output了kAudioUnitProperty_SampleRate,它总是返回44.1
- (void)startToneUnit
{
AudioComponentDescription defaultOutputDescription;
defaultOutputDescription.componentType = kAudioUnitType_Output;
defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
defaultOutputDescription.componentFlags = 0;
defaultOutputDescription.componentFlagsMask = 0;
// Get the default playback output unit
AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
NSAssert(defaultOutput, @"Can't find default output");
// Create a new unit based on this that we'll use for output
OSErr err = AudioComponentInstanceNew(defaultOutput, &toneUnit);
NSAssert1(toneUnit, @"Error creating unit: %hd", err);
// Set our tone rendering function …Run Code Online (Sandbox Code Playgroud) 我使用录音机在文档目录中录制和创建文件,然后我使用音频播放器播放它。我可以在模拟器和设备上录制它,但我不能只在设备上播放。
请注意 1. 我不从文件播放声音,我从 NSData 播放(我将音乐存储到数据库中,然后检索它们以播放) 2. 它在模拟器上运行良好,但在设备上失败。
这是我播放音频的代码
- (void)playAudioWithData:(NSData *)data {
[self stopPlayingAudio];
[self stopRecordingAudio];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
[self.audioPlayer play];
}
Run Code Online (Sandbox Code Playgroud)
这是录制设置:
NSDictionary *audioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:44100],AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt: 1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:AVAudioQualityMedium],AVEncoderAudioQualityKey,nil];
Run Code Online (Sandbox Code Playgroud) 我怎样才能在扬声器上听到与麦克风录制但现场录制的内容相同的内容?
我想做的就是戴上耳机听到同样的声音,但我只会控制音量。
我知道如何录制音频然后播放它,但我希望它是实时的,我不需要保存音频,只需同时听到相同的内容即可。
我在 installTapOnBus() 方法中不能做什么?
如果您参考讲座 WWDC 2016 Delivering an Exceptional Audio Experience @ :31 分钟,它提到在实时音频中我不需要创建线程或分配任何内存。
这篇文章也提到了这一点。
这里的游戏名称是将任何可以移动的东西从渲染块移到初始化函数中。这包括分配内存块和调用系统函数之类的事情。
这是我的示例代码:
inputNode?.installTap(onBus: bus,
bufferSize: myTapOnBusBufferSize,
format: theAudioFormat) {
(buffer: AVAudioPCMBuffer!,
time: AVAudioTime!) -> Void in
theShowInfo.audioFormat = theAudioFormat
self.onNewBuffer(buffer)
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着在我的 onNewBuffer() 函数内部
我无法输入以下内容
var myStringArray = ["",""]
Run Code Online (Sandbox Code Playgroud)
或这个 ..
DispatchQueue.main.async(qos: .userInteractive) {
}
Run Code Online (Sandbox Code Playgroud)
或这个?
NotificationCenter.default.post(name: Notification.Name(rawValue: MyNotificationIdentifier), object: nil)
Run Code Online (Sandbox Code Playgroud)
这是否意味着如果我在线程中执行这些调用并分配内存,我的应用程序将会崩溃?
这是否意味着如果我执行 fft 算法,我需要在 onNewBuffer 函数的线程中编写 fft 的所有代码?
我正在尝试实时处理音频数据,以便可以根据麦克风输入的声音显示屏幕频谱分析仪/可视化。我正在使用 AVFoundationAVCaptureAudioDataOutputSampleBufferDelegate来捕获音频数据,这会触发 delgate 函数captureOutput。函数如下:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
autoreleasepool {
guard captureOutput != nil,
sampleBuffer != nil,
connection != nil,
CMSampleBufferDataIsReady(sampleBuffer) else { return }
//Check this is AUDIO (and not VIDEO) being received
if (connection.audioChannels.count > 0)
{
//Determine number of frames in buffer
var numFrames = CMSampleBufferGetNumSamples(sampleBuffer)
//Get AudioBufferList
var audioBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))
var blockBuffer: CMBlockBuffer?
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nil, &audioBufferList, …Run Code Online (Sandbox Code Playgroud) 我已经添加并导入了AudioToolbox框架。但我的项目无法看到该文件AudioDeviceID,AudioObjectPropertyAddress. 它给出了错误,Use of undeclared type 'AudioDeviceID'. 我尝试了一个示例核心音频项目,它工作得很好。我错过了什么吗?
在我的 iOS AU 主机应用程序中,我使用 AVAudioUnitComponentManager.components 方法来检索可用音频单元的列表。大多数时候它都按预期工作。但有时它仅返回 Apple 创建的音频单元,而不返回设备上安装的第三方音频单元。有趣的是,如果我在应用程序中遇到此问题后,我转到 GarageBand 并打开那里的音频单元列表,那么当我返回到我的应用程序时,所有第三方 AU 都会出现。所以我想知道在调用 GarageBand 正在执行的 AVAudioUnitComponentManager.components 方法之前可能应该完成一些其他初始化,我也应该在我的应用程序中执行。
有什么建议么?
core-audio ×10
ios ×10
avfoundation ×5
audiounit ×4
audio ×3
swift ×2
cocoa-touch ×1
iphone ×1
swift4 ×1