我一直在为iOS的频率检测应用程序工作,我在用一个用户定义的AudioBufferList填充来自麦克风的音频样本时遇到问题.
当我在InputCallback方法中调用AudioUnitRender时,我得到的返回码为-50.我相信这意味着我的一个参数无效.我猜它是AudioBufferList,但我无法弄清楚它有什么问题.我想我已经设置好了它,它与我在ASBD中指定的数据格式相匹配.
下面是我认为可能不正确的远程I/O设置和函数调用:
ASBD:
size_t bytesPerSample = sizeof(AudioUnitSampleType);
AudioStreamBasicDescription localStreamFormat = {0};
localStreamFormat.mFormatID = kAudioFormatLinearPCM;
localStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
localStreamFormat.mBytesPerPacket = bytesPerSample;
localStreamFormat.mBytesPerFrame = bytesPerSample;
localStreamFormat.mFramesPerPacket = 1;
localStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
localStreamFormat.mChannelsPerFrame = 2;
localStreamFormat.mSampleRate = sampleRate;
Run Code Online (Sandbox Code Playgroud)
InputCallback声明:
err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Input,
kOutputBus, &callbackStruct, sizeof(callbackStruct));
Run Code Online (Sandbox Code Playgroud)
AudioBufferList声明:
// Allocate AudioBuffers
bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mNumberChannels = 2;
bufferList->mBuffers[0].mDataByteSize = 1024;
bufferList->mBuffers[0].mData = calloc(256, sizeof(uint32_t));
Run Code Online (Sandbox Code Playgroud)
InputCallback函数:
AudioUnit rioUnit = THIS->ioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;
renderErr …Run Code Online (Sandbox Code Playgroud) 我写了一个简单的audiounit,它应该交换立体声源的左右声道.对于使用BASS库的命令行程序,此代码的移植版本在C中运行良好,但是我无法在Xcode中使用相同的代码来进行音频处理.
对于例如{1,2,3,4,5,6}的缓冲器输入,我预期立体声反转为{2,1,4,3,6,5}.
我的代码以这种方式正确地反转了样本,但我听到的只是某种低通滤波,而不是样本的立体反转.
输入缓冲区中的前4个值为:0.000104 0.000101 0.000080 0.000113
输出为:0.000101 0.000104 0.000113 0.000080
我是否误解了输入/输出缓冲区的结构方式?
void First::FirstKernel::Process( const Float32 *inSourceP,
Float32 *inDestP,
UInt32 inSamplesToProcess,
UInt32 inNumChannels,
bool &ioSilence )
{
if (!ioSilence) {
const Float32 *sourceP = inSourceP;
Float32 *destP = inDestP;
for (int i = inSamplesToProcess/2; i>0; --i) {
*(destP+1) = *sourceP;
*destP = *(sourceP+1);
sourceP = sourceP +2;
destP = destP +2;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用低通滤波器AU.在将流格式设置为过滤器单元时,我不断收到kAudioUnitErr_FormatNotSupported(-10868)错误,但如果我只使用远程IO单元则没有错误.
我正在使用的流格式是(更新的):
myASBD.mSampleRate = hardwareSampleRate;
myASBD.mFormatID = kAudioFormatLinearPCM;
myASBD.mFormatFlags = kAudioFormatFlagIsSignedInteger;
myASBD.mBitsPerChannel = 8 * sizeof(float);
myASBD.mFramesPerPacket = 1;
myASBD.mChannelsPerFrame = 1;
myASBD.mBytesPerPacket = sizeof(float) * myASBD.mFramesPerPacket;
myASBD.mBytesPerFrame = sizeof(float) * myASBD.mChannelsPerFrame;
Run Code Online (Sandbox Code Playgroud)
我正在设置过滤器流,如下所示:
// Sets input stream type to ASBD
setupErr = AudioUnitSetProperty(filterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &myASBD, sizeof(myASBD));
NSLog(@"Filter in: %i", setupErr);
//NSAssert(setupErr == noErr, @"No ASBD on Finput");
//Sets output stream type to ASBD
setupErr = AudioUnitSetProperty(filterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &myASBD, sizeof(myASBD));
NSLog(@"Filter out: %i", setupErr);
NSAssert(setupErr == noErr, …Run Code Online (Sandbox Code Playgroud) 我正在编写一个iOS应用程序,它从麦克风输入,通过高通滤波器音频单元运行,然后通过扬声器播放.我已经能够通过使用AUGraph API成功地做到这一点.在其中,我放置了两个节点:远程I/O单元和效果音频单元(kAudioUnitType_Effect,kAudioUnitSubType_HighPassFilter),并将io单元的输入元素的输出范围连接到效果单元的输入,效果节点的输出连接到io单元的输出元素输入范围.但是现在我需要根据处理过的音频样本做一些分析,所以我需要直接访问缓冲区.这意味着(如果我错了请纠正我)我不能再用来AUGraphConnectNodeInput在效果节点的输出和io单元的输出元素之间建立连接,并且必须为io单元的输出元素附加渲染回调函数,所以每当扬声器需要新样本时我都可以访问缓冲区.我已经这样做了,但是当我AudioUnitRender在渲染回调中调用该函数时,我得到-50错误.我相信我有一个ASBD在两个音频单元之间不匹配的情况,因为我在渲染回调中没有做任何事情(而AUGraph之前已经处理过它).这是代码:
AudioController.h:
@interface AudioController : NSObject
{
AUGraph mGraph;
AudioUnit mEffects;
AudioUnit ioUnit;
}
@property (readonly, nonatomic) AudioUnit mEffects;
@property (readonly, nonatomic) AudioUnit ioUnit;
-(void)initializeAUGraph;
-(void)startAUGraph;
-(void)stopAUGraph;
@end
Run Code Online (Sandbox Code Playgroud)
AudioController.mm:
@implementation AudioController
…
static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
AudioController *THIS = (__bridge AudioController*)inRefCon;
AudioBuffer buffer;
AudioStreamBasicDescription fxOutputASBD;
UInt32 fxOutputASBDSize = sizeof(fxOutputASBD);
AudioUnitGetProperty([THIS mEffects], kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &fxOutputASBD, &fxOutputASBDSize);
buffer.mDataByteSize = inNumberFrames …Run Code Online (Sandbox Code Playgroud) 我正在使用CoreAudio构建一个MIDI合成器.目前,我有以下音频图:
Sampler -> Reverb -> IO
Run Code Online (Sandbox Code Playgroud)
我需要为图表和混响添加合唱效果.问题是iPhone上没有合唱效果.为了解决这个问题,我计划实现自己的合唱效果.为此,我需要访问音频流.
问题是:什么是在音频图中间访问音频流的最佳方式.
Sampler -> Reverb -> [Custom processing] -> IOUnit
Run Code Online (Sandbox Code Playgroud)
有没有办法可以使用AudioUnitAddRenderNotify回调之类的东西来改变音频流?或者我必须像这样打破音频图形:
Sampler -> Reverb -> [AudioUnitAddRenderNotify callback] -> buffer -> [RenderCallback] -> IOUnit
Run Code Online (Sandbox Code Playgroud)
任何意见,将不胜感激.
有时执行
AudioOutputUnitStop(inputUnit)
Run Code Online (Sandbox Code Playgroud)
导致应用冻结约10/15秒,并显示以下控制台消息:
WARNING: [0x3b58918c] AURemoteIO.cpp:1225: Stop: AURemoteIO::Stop: error 0x10004003 calling TerminateOwnIOThread
Run Code Online (Sandbox Code Playgroud)
此类代码由Novocaine库处理,特别是在[Novocaine暂停]方法中发生,我调用该方法以停止执行音频文件的播放(https://github.com/alexbw/novocaine/blob/master /Novocaine/Novocaine.m)。
任何提示都非常感谢!
谢谢,丹
我目前正在开发iOS的VOIP项目.
我使用AudioUnits从麦克风获取数据并播放声音.
我的主应用程序是用C#(Xamarin)编写的,它使用C++库来实现更快的音频和编解码处理.
为了测试输入/输出结果我正在测试同一设备上的录制和播放
- 将麦克风音频数据存储在recordingCallback的缓冲区中
- 从playbackCallback中的缓冲区播放数据
这按预期工作,语音质量很好.
我已经这样做了,但结果文件只包含一些短的"嘟嘟"信号.
我需要什么音频设置,我可以在生成的原始PCM文件中听到我的声音(真实的音频信号)而不是短的哔声?
有谁知道什么可能是错的或我必须做什么,我能够正确地重播生成的PCM文件?
我目前的格式设置是(C#代码):
int framesPerPacket = 1;
int channelsPerFrame = 1;
int bitsPerChannel = 16;
int bytesPerFrame = bitsPerChannel / 8 * channelsPerFrame;
int bytesPerPacket = bytesPerFrame * framesPerPacket;
AudioStreamBasicDescription audioFormat = new AudioStreamBasicDescription ()
{
SampleRate = 8000,
Format = AudioFormatType.LinearPCM,
FormatFlags = AudioFormatFlags.LinearPCMIsSignedInteger | AudioFormatFlags.LinearPCMIsPacked | AudioFormatFlags.LinearPCMIsAlignedHigh,
BitsPerChannel = bitsPerChannel,
ChannelsPerFrame = channelsPerFrame,
BytesPerFrame = bytesPerFrame,
FramesPerPacket = framesPerPacket,
BytesPerPacket = bytesPerPacket,
Reserved = 0
}; …Run Code Online (Sandbox Code Playgroud) 目前下面的代码可以流式传输本地mp3文件,所以如果我打电话
audio.scheduleFile(NSBundle.mainBundle().URLForResource("Moon River", withExtension: "mp3")!)
它将正确播放本地文件.现在我希望能够流式传输非本地网址.
我需要做什么才能让我流式传输MP3网址?
class Audio: NSObject {
var graph: AUGraph
var filePlayerAU: AudioUnit
var filePlayerNode: AUNode
var outputAU: AudioUnit
var fileID: AudioFileID
var currentFrame: Int64
override init () {
graph = AUGraph()
filePlayerAU = AudioUnit()
filePlayerNode = AUNode()
outputAU = AudioUnit()
fileID = AudioFileID()
currentFrame = 0
super.init()
NewAUGraph(&graph)
// Add file player node
var cd = AudioComponentDescription(componentType: OSType(kAudioUnitType_Generator),
componentSubType: OSType(kAudioUnitSubType_AudioFilePlayer),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0, componentFlagsMask: 0)
AUGraphAddNode(graph, &cd, &filePlayerNode)
// Add output node
var outputNode …Run Code Online (Sandbox Code Playgroud) 我正在为Mac编写我的第一个音频应用程序,它加载外部音频单元并使用它通过AVAudioEngine实例播放声音,我一直看到这个警告:
警告:140:此应用程序或其使用的库正在使用已弃用的Carbon Component Manager来托管Audio Units.将来的版本中将删除对此的支持.此外,这使主机与版本3音频单元不兼容.请转到AudioComponent.h中的API.
我已经从使用AVAudioUnitComponents转换到AudioComponents(现在通过这个api访问),我希望能解决这个问题,但是当我调用start()我的引擎时,我仍然会看到这个警告.
任何想法在这里出了什么问题?据我所知,我不再使用已弃用的API.AVAudioEngine是否有可能在引擎盖下使用已弃用的API?
这是我正在使用的代码的片段.我正在调用selectInstrument我使用AudioComponents API检索的描述.
public func selectInstrument(withDescription description: AudioComponentDescription, callback: @escaping SelectInstrumentCallback) {
AVAudioUnit.instantiate(with: description, options: []) { avAudioUnit, error in
guard let unit = avAudioUnit else {
callback(nil)
return
}
self.disconnectCurrent()
self.connect(unit: unit)
unit.auAudioUnit.requestViewController { viewController in
callback(viewController)
}
}
}
private func disconnectCurrent() {
guard let current = currentInstrument else { return }
self.engine.disconnectNodeInput(engine.mainMixerNode)
self.engine.detach(current)
self.currentInstrument = nil
self.engine.stop()
}
private func connect(unit: AVAudioUnit) {
let hardwareFormat …Run Code Online (Sandbox Code Playgroud) 使用AVAudioUnitSampler时,我在iPhone(iOS 11)上遇到了一个奇怪的问题.
假设我有一个用钢琴声音初始化的AVAudioUnitSampler.因此,每次连接或断开耳机时,我都会听到钢琴声音加上正弦波音,声音越大,连接/断开耳机的次数越多.
因此,对我而言,每次耳机插入/拔出时都会感觉到,新的音频单元采样器将内部连接到声音输出(并且,由于它是未初始化的,因此仅产生正弦波音调).
以下类已经显示了该问题.请注意,我正在使用AudioKit来处理MIDI信号并触发采样器(虽然在这一端,一切似乎工作正常,即.startNote()并stopNote()正确调用):
class MidiController: NSObject, AKMIDIListener {
var midi = AKMIDI()
var engine = AVAudioEngine()
var samplerUnit = AVAudioUnitSampler()
override public init() {
super.init()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleRouteChange),
name: .AVAudioSessionRouteChange,
object: nil)
midi.openInput()
midi.addListener(self)
engine.attach(samplerUnit)
engine.connect(samplerUnit, to: engine.outputNode)
startEngine()
}
func startEngine() {
if (!engine.isRunning) {
do {
try self.engine.start()
} catch {
fatalError("couldn't start engine.")
}
}
}
@objc func handleRouteChange(notification: NSNotification) {
let deadlineTime = DispatchTime.now() + …Run Code Online (Sandbox Code Playgroud)