通过Augraph连接的iOS波形生成器
iOS waveform generator connected via AUGraph
我创建了一个连接到Augraph的简单波形生成器。我已经重复了一些苹果的示例代码,以设置像这样的audiostreambasicdescription
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
{
mFormatID = kAudioFormatLinearPCM;
int sampleSize = SizeOf32(AudioSampleType);
mFormatFlags = kAudioFormatFlagsCanonical;
mBitsPerChannel = 8 * sampleSize;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
else {
mBytesPerPacket = mBytesPerFrame = sampleSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
在我的班级中,我称此功能
mClientFormat.SetCanonical(2, true);
mClientFormat.mSampleRate = kSampleRate;
样本率为
#define kSampleRate 44100.0f;
其他设置也取自示例代码
// output unit
CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);
// iPodEQ unit
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);
// multichannel mixer unit
CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);
一切正常,但是问题在于,当我尝试到达第二个缓冲区
时,我没有得到立体声声音,我的回调功能正在失败(不良访问)Float32 *bufferLeft = (Float32 *)ioData->mBuffers[0].mData;
Float32 *bufferRight = (Float32 *)ioData->mBuffers[1].mData;
// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
switch (generator.soundType) {
case 0: //Sine
bufferLeft[frame] = sinf(thetaLeft) * amplitude;
bufferRight[frame] = sinf(thetaRight) * amplitude;
break;
所以看来我得到的是单声道而不是立体声。指针Bufferright是空的,但不知道为什么。任何帮助将不胜感激。
我可以看到两个可能的错误。首先,正如@invalidname所指出的那样,在立体声中录制可能不会在iPhone等单声道设备上使用。好吧,它可能会起作用,但是如果这样做的话,您只是要恢复双单声道立体声流,无论如何,为什么还要打扰呢?您不妨配置流以在单声道中工作,并为自己放置CPU的头顶。
第二个问题可能是您的声音失真的根源。您的流描述格式标志应为:
kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked
另外,不要忘记将杂交标志设置为0。虽然该标志的值可能被忽略了,但明确将其设置为0并没有什么害处。
。编辑:在iPhone上调试音频的另一个更通用的提示 - 如果您要扭曲,剪辑或其他奇怪的效果,请从手机中获取数据有效载荷,并查看Wave Editor中的录音。能够缩小并查看各个样本将为您提供很多有关问题的线索。
要这样做,您需要打开"组织者"窗口,单击手机,然后在应用程序旁边展开小箭头(在通常会卸载它的同一地点)。现在,您将看到一些向下指向箭头,如果单击它,Xcode将将数据有效负载从您的应用程序复制到硬盘驱动器上的某个地方。如果要将录音转储到磁盘上,您会在此处找到提取的文件。
链接引用
我猜想问题是您要指定一种交错的格式,但是然后访问缓冲区,就好像它们在IO回调中没有相互交流一样。iodata-> mbuffers [1]是无效的,因为左右通道的所有数据都在iodata-> mbuffers [0] .mdata中交错。检查iodata-> mnumberbuffers。我的猜测是设置为1。另外,请验证iodata-> mbuffers [0] .MnumberChannels设置为2,这将表示交错数据。
还请查看核心音频公用事业类,以帮助设置格式。使它变得容易得多。您的设置格式的代码可能会简化为一行,您会更有信心它是正确的(尽管对我来说,您的格式看起来正确设置了 - 如果您想要的是交错的16位INT):
CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true)
Apple用来在使用Xcode安装的SDK中打包这些类,但是现在您需要在此处下载它们:https://developer.apple.com/library/mac/mac/samplecode/coreaudioutilityclasses/introduction/introdocution/introcloclet。html
无论如何,看起来最简单的修复方法就是将格式更改为非交换。因此,在您的代码中:mclientformat.setcanonical(2,false);
- 使用ios:ate写入到流会覆盖现有文件
- 如何访问RTCVideoRenderer的帧?(ios)
- ios::fmtflags 在 C++ 中是如何工作的?setf() 是如何工作的?
- 我可以在 iOS 或 mac 应用程序中使用C++代码吗?
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 为什么 C++ 11 在 ios 类中添加了运算符 bool
- 'string'文件在带有C++文件的iOS插件上找不到
- 文件模式标志"ios::app"是否用于删除文件(如果文件已存在)?
- 使用 C++ iOS::ate 获取错误的文件大小
- 使用 适用于 Android 和 iOS 的 tf-lite C++ API
- 波形音频 - waveOutWrite 发出断断续续的声音
- 如何正确设置 ios 标志以进行流操作?
- 在为 iOS 构建 aws-sdk-cpp 时,cmake 上的 CXX 编译器错误已损坏
- C++ std::locale( "en" ) 在 iOS 上引发异常
- 在瓦尔格林德的泄漏摘要中使用 std::ios::sync_with_stdio(fasle) 打印时获取"still reachable"
- 在iOS应用程序中创建数据库
- Qt & Firebase C++ SDK 在 iOS 上的链接问题
- 在波形文件中查找狄拉克
- 是否有可以在iOS上运行的API来更改现有视频的每秒帧数?
- 通过Augraph连接的iOS波形生成器