我正在尝试找到播放音频无缝循环的最佳方式,用户可以在尽可能短的时间内切换到另一个音频,并提供相当数量(30-150)的非常短的循环.OpenAL是否足以满足这一要求,还是需要深入研究音频单元?Apple文档说,对于像仪器这样的实时反馈,Audio Units是正确的选择.
我只想得到社群对此的意见,任何链接和示例项目都将不胜感激.
我是iOS及其C基础的新手,但不是一般的编程.我的困境是这样的.我正在基于AudioUnits的复杂应用程序中实现回声效果.该应用程序需要混响,回声和压缩等功能.但是,当我在我的应用程序中生成的音频样本使用特定的AudioStreamBasicDescription格式时,回声才有效.但是,此格式不适用于其他AudioUnits.虽然还有其他方法可以解决这个问题,但修复回声算法中的位错可能是最直接的方法.
与echo一起使用的*AudioStreamBasicDescription*具有mFormatFlag: kAudioFormatFlagsAudioUnitCanonical ; 具体是:
AudioUnit Stream Format (ECHO works, NO AUDIO UNITS)
Sample Rate: 44100
Format ID: lpcm
Format Flags: 3116 = kAudioFormatFlagsAudioUnitCanonical
Bytes per Packet: 4
Frames per Packet: 1
Bytes per Frame: 4
Channels per Frame: 2
Bits per Channel: 32
Set ASBD on input
Set ASBD on output
au SampleRate rate: 0.000000, 2 channels, 12 formatflags, 1819304813 mFormatID, 16 bits per channel
Run Code Online (Sandbox Code Playgroud)
除了mFormatFlag之外,与AudioUnit一起使用的流格式是相同的:kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian …
在周末,我遇到了一个学习如何在iOS上编程音频合成的绊脚石.我已经在iOS上开发了好几年了,但我刚刚进入音频合成方面.现在,我只是编写演示应用程序来帮助我学习这些概念.我目前能够在音频单元的回放渲染器中构建和堆叠正弦波而没有任何问题.但是,我想了解渲染器中发生了什么,因此我可以在每个左右声道中渲染2个单独的正弦波.目前,我假设在我的init音频部分,我需要进行以下更改:
从:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
Run Code Online (Sandbox Code Playgroud)
至:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = kSampleRate;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
Run Code Online (Sandbox Code Playgroud)
但是,渲染器对我来说有些希望.我一直在处理我能找到的任何教程或示例代码.我可以使单声道信号的给定上下文工作,但我无法使渲染器生成立体声信号.我想要的只是左声道中的一个不同频率和右声道中的不同频率 - 但老实说,我不理解渲染器足以让它工作.我已经尝试将memcpy函数导入mBuffers [0]和mbuffers [1],但这会导致应用程序崩溃.我的渲染在下面(它目前包含堆叠的正弦波,但对于立体声示例,我可以在每个通道中使用一个设定频率的波).
#define kOutputBus 0
#define kSampleRate 44100
//44100.0f
#define kWaveform (M_PI * 2.0f / kSampleRate)
OSStatus playbackCallback(void …Run Code Online (Sandbox Code Playgroud) 我被指控将VOIP添加到游戏中(跨平台,因此不能使用Apple游戏套件来执行此操作).
现在3或4天,我正试图绕着音频单元和remoteIO ...我已经忽略了几十个例子等等,但每次它只是将一个简单的算法应用到输入PCM并播放它回到扬声器上.根据Apple的文档,为了做VOIP,我们应该使用kAudioSessionCategory_PlayAndRecord.
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(audioCategory),
&audioCategory);
XThrowIfError(status, "couldn't set audio category");
Run Code Online (Sandbox Code Playgroud)
1)但似乎(对我而言)playAndRecord将始终播放来自麦克风的内容(或者更令人兴奋的是PerformThru回调// aurioTouch),我错了吗?
我有最简单的回调,只做AURender
static OSStatus PerformThru(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
OSStatus err = AudioUnitRender(THIS->rioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData);
if (err)
printf("PerformThru: error %d\n", (int)err);
return err
}
Run Code Online (Sandbox Code Playgroud)
从那个回调我打算将数据发送给对等体(当然不是直接,但数据将来自它)......
我不知道我怎么能输出不同于输入的输出,除了可能有2个单位,一个录音,一个播放,但它似乎不是Apple的意图(仍然依据文档).
当然,我找不到任何关于它的文档,音频单元仍然没有记录......
任何人都会知道最好的方法是什么?
我想将输出渲染回调通过添加AudioUnitAddRenderNotify到当前活动的RemoteIO单元上,该单元将音频输出到扬声器.我无法访问实际的RemoteIO实例变量,但我想在应用程序中获取列表音频单元,并以此方式找到RemoteIO单元.这甚至可能吗?
我已经搜索过并且已经完成了可以播放MIDI音符的OS X应用程序,但是当我在iOS中尝试时,什么都没发生.这是核心代码:
AUGraph graph;
AudioUnit synthUnit;
AUNode synthNode, outNode;
NewAUGraph(&graph);
AudioComponentDescription cd;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentType = kAudioUnitType_MusicDevice;
cd.componentSubType = kAudioUnitSubType_MIDISynth;
AUGraphAddNode(graph, &cd, &synthNode);
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_GenericOutput;
AUGraphAddNode(graph, &cd, &outNode), "AUGraphAddNode");
CheckError(AUGraphOpen(graph), "AUGraphOpen");
AUGraphConnectNodeInput(graph, synthNode, 0, outNode, 0);
AUGraphNodeInfo(graph, synthNode, 0, &synthUnit);
AUGraphInitialize(graph);
CAShow(graph);
AUGraphStart(graph);
CFURLRef bankURL = ... //gs_instruments.dls
AudioUnitSetProperty(synthUnit,
kMusicDeviceProperty_SoundBankURL,
kAudioUnitScope_Global,
0,
&bankURL,
sizeof(bankURL));
static UInt32 kChannelMessage_NoteOn = 0x90;
UInt8 channel = 0;
UInt8 note = 60;
UInt32 velocity = 127;
MusicDeviceMIDIEvent(synthUnit,
kChannelMessage_NoteOn | channel, …Run Code Online (Sandbox Code Playgroud) 如何在运行时/现场使用音频单元对音频(PCM数据)重新采样?
我有一个音频单元设置,如下所示。
- (void) setUpAudioUnit {
OSStatus status;
AudioComponentInstance audioUnit;
AudioComponent inputComponent;
AudioComponentDescription audioComponentDescription;
AudioStreamBasicDescription audioStreamBasicDescription;
// Describe audio component
audioComponentDescription.componentType = kAudioUnitType_Output;
audioComponentDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
audioComponentDescription.componentFlags = 0;
audioComponentDescription.componentFlagsMask = 0;
audioComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get component
inputComponent = AudioComponentFindNext(NULL, &audioComponentDescription);
// Get audio units
status = AudioComponentInstanceNew(inputComponent, &audioUnit);
checkStatus(status);
// Enable IO for recording
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus,
&flag,
sizeof(flag));
checkStatus(status);
// Enable IO for playback
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus, …Run Code Online (Sandbox Code Playgroud) 我正在创建一个使用Audio Units的应用程序,虽然Objective-C中有很多代码示例(包括Apple自己的aurioTouch等),但我试图在Swift中编写整个代码.
我已经能够设置我的AUGraph并通过它运行一些音频,但我似乎无法弄清楚渲染回调的语法.我尝试了几种方法:
方法1:直接创建AURenderCallback
let render : AURenderCallback = { (
inRefCon: UnsafeMutablePointer<Void>,
ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBufNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus in
return noErr
}
Run Code Online (Sandbox Code Playgroud)
因为我只是想让它工作,所以除了在此时返回noErr之外我在这个回调中什么都不做.但是,编译器返回以下错误:
(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) - > OSStatus'无法转换为'AURenderCallback
文档中AURenderCallback的定义如下:
typealias AURenderCallback = (UnsafeMutablePointer<Void>,UnsafeMutablePointer<AudioUnitRenderActionFlags>,UnsafePointer<AudioTimeStamp>, UInt32, UInt32,UnsafeMutablePointer<AudioBufferList>) -> OSStatus
Run Code Online (Sandbox Code Playgroud)
它似乎与我输入的相同,尽管可能是我不明白文档要求的内容.
方法2:创建表示AURenderCallback的函数
func render(
inRefCon: UnsafeMutablePointer<Void>,
ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBufNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus {
return noErr
}
Run Code Online (Sandbox Code Playgroud)
这不会将任何错误作为函数提供,但是当我将它放入inputProc参数中的AURenderCallbackStruct时,我收到一个错误:
找不到类型'AURenderCallbackStruct'的初始值设定项,它接受类型'的参数列表'(inputProc:(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) - > OSStatus,inputProcRefCon:nil)
我没有找到很多在Swift中创建AURenderCallbacks的例子,与Objective-C相比,语法似乎有很大差异.任何帮助,将不胜感激.
我正在尝试将单声道音频单元输入路由到立体声输出。我已经深入研究了类似的问题,但是从来没有任何解决方案。
我首先使用AVAudioSessionCategoryPlayAndRecord类别,AVAudioSessionModeHearingAccessibility模式和AVAudioSessionCategoryOptionAllowBluetoothA2DP选项创建一个AVAudioSession 。将其设置为活动后,我开始配置输入/输出。
我的单声道格式:
AudioStreamBasicDescription monoFormat;
monoFormat.mSampleRate = 44100;
monoFormat.mFormatID = kAudioFormatLinearPCM;
monoFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
monoFormat.mBytesPerPacket = 4;
monoFormat.mFramesPerPacket = 1;
monoFormat.mBytesPerFrame = 4;
monoFormat.mChannelsPerFrame = 1; //mono
monoFormat.mBitsPerChannel = 32;
monoFormat.mReserved = 0;
Run Code Online (Sandbox Code Playgroud)
我的立体声格式:
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
audioFormat.mBytesPerPacket = 8;
audioFormat.mFramesPerPacket = 1;
audioFormat.mBytesPerFrame = 8;
audioFormat.mChannelsPerFrame = 2;//stereo
audioFormat.mBitsPerChannel = …Run Code Online (Sandbox Code Playgroud) 当使用kAudioUnitSubType_VoiceProcessingIO联合AVAudioPlayer这就导致了音频播放音量是相当低的。切换到kAudioUnitSubType_RemoteIO播放音量时,音量再次处于适当的高水平。
取决于顺序3步
A。配置VoiceProcessingIO音频单元B。创建一个音频播放器C。播放音频播放器音量在这三个步骤的顺序上有很大差异。
这是一个示例存储库(_不要奇怪为什么它叫audiokit,它是我使用不同音频sdks遇到的问题的集合,那就是一个集合存储库。但是这个特定的分支没有使用AudioKit)
https://github.com/mlostekk/AudioKitSampleRate/tree/issue/outputVolumeNoAudiokit(分支outputVolumeNoAudiokit)
在我们的应用中,常规情况由按钮表示VP3。首先设置语音处理输入回调,然后在以后创建音频播放器并进行播放。但是这种情况导致输出量非常低
订单是 A -> B -> C
按钮VP1(B -> C -> A)导致音量过大。
按钮VP2(B -> A -> C)也导致音量过大
该按钮NoVP1还使用A -> B -> C,这是正常情况,但实际上此处语音处理已禁用,但我们需要它。
有人能解释为什么这样的情况吗?以及如何解决VP3场景具有正常/不那么低的输出量
这似乎仅在较新的设备(iphone7及更高版本)上发生,即使在较旧的设备上也可以听到音量差异。越新越激烈
这不要紧,如果模式为.spokenAudio,.default或.measurement。它似乎kAudioUnitSubType_VoiceProcessingIO仅取决于。
audiounit ×10
ios ×8
core-audio ×7
objective-c ×3
audio ×2
xcode ×2
audiotoolbox ×1
avfoundation ×1
c++ ×1
ios5 ×1
ipad ×1
iphone ×1
midi ×1
openal ×1
resampling ×1
swift ×1
voip ×1