No *_*ing 7 core-audio ios ios5
我一直试图在iOS 5上一个renderCallback记录从RemoteIO单元直接AAC在iPad 2,我已经看到了矛盾的信息说这是不可能的-这是可能的(在评论点击这里).我想要这样做的原因是因为录制到PCM需要如此多的磁盘空间来记录任何长度 - 即使它稍后被转换为AAC.
我准备放弃了.我已经通过谷歌刮,所以,核心音频书和苹果的核心音频邮件列表和论坛,并已经到了,我没有得到任何错误的点-和我记录的东西到磁盘,但生成的文件无法播放.模拟器和设备都是这种情况.
所以...如果有人有这方面的经验,我真的很感激在正确的方向上轻推.设置是RemoteIO正在播放AUSamplers的输出并且工作正常.
以下是我在下面的代码中所做的事情
指定AudioStreamBasicDescriptionremoteIO设备的格式kAudioFormatLinearPCM
ExtAudioFileRef
通过从RemoteIO单元获取指定客户端格式,创建并指定目标格式
为RemoteID单元指定renderCallback
在renderCallback中,在kAudioUnitRenderAction_PostRender阶段中写入数据
正如我所说,我没有收到任何错误,并且生成的音频文件大小显示正在写入某些内容,但该文件无法播放.也许我的格式搞砸了?
无论如何,这是我在一个瓶子里的信息和/或"Be Here Dragons"的旗帜,任何人都在冒着Core-Audio的黑暗水域.
//尝试播放文件时得到的不愉快的消息:

//部分remoteIO设置
// Enable IO for recording
UInt32 flag = 1;
result = AudioUnitSetProperty(ioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus, // == 1
&flag,
sizeof(flag));
if (noErr != result) {[self printErrorMessage: @"Enable IO for recording" withStatus: result]; return;}
// Describe format - - - - - - - - - -
size_t bytesPerSample = sizeof (AudioUnitSampleType);
AudioStreamBasicDescription audioFormat;
memset(&audioFormat, 0, sizeof(audioFormat));
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 2;
audioFormat.mBytesPerFrame = 2;
result = AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus, // == 1
&audioFormat,
sizeof(audioFormat));
result = AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kOutputBus, // == 0
&audioFormat,
sizeof(audioFormat));
Run Code Online (Sandbox Code Playgroud)
//设置文件和rendercallback的函数
- (void)startRecordingAAC
{
OSStatus result;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *recordFile = [documentsDirectory stringByAppendingPathComponent: @"audio.m4a"];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(__bridge CFStringRef)recordFile,
kCFURLPOSIXPathStyle,
false);
AudioStreamBasicDescription destinationFormat;
memset(&destinationFormat, 0, sizeof(destinationFormat));
destinationFormat.mChannelsPerFrame = 2;
destinationFormat.mFormatID = kAudioFormatMPEG4AAC;
UInt32 size = sizeof(destinationFormat);
result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &destinationFormat);
if(result) printf("AudioFormatGetProperty %ld \n", result);
result = ExtAudioFileCreateWithURL(destinationURL,
kAudioFileM4AType,
&destinationFormat,
NULL,
kAudioFileFlags_EraseFile,
&extAudioFileRef);
if(result) printf("ExtAudioFileCreateWithURL %ld \n", result);
AudioStreamBasicDescription clientFormat;
memset(&clientFormat, 0, sizeof(clientFormat));
result = AudioUnitGetProperty(ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, & clientFormat, &size);
if(result) printf("AudioUnitGetProperty %ld \n", result);
result = ExtAudioFileSetProperty(extAudioFileRef,kExtAudioFileProperty_ClientDataFormat,sizeof(clientFormat),&clientFormat);
if(result) printf("ExtAudioFileSetProperty %ld \n", result);
result = ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL);
if (result) {[self printErrorMessage: @"ExtAudioFileWriteAsync error" withStatus: result];}
result = AudioUnitAddRenderNotify(ioUnit, renderCallback, (__bridge void*)self);
if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result];}
}
Run Code Online (Sandbox Code Playgroud)
//最后,rendercallback
static OSStatus renderCallback (void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
OSStatus result;
if (*ioActionFlags == kAudioUnitRenderAction_PostRender){
MusicPlayerController* THIS = (__bridge MusicPlayerController *)inRefCon;
result = ExtAudioFileWriteAsync(THIS->extAudioFileRef, inNumberFrames, ioData);
if(result) printf("ExtAudioFileWriteAsync %ld \n", result);
}
return noErr;
}
Run Code Online (Sandbox Code Playgroud)
No *_*ing 14
所以我终于解决了这个问题!呃,什么信息清道夫狩猎.
无论如何,这是我错过的ExtAudioFile文档中的位(参见粗体文本).我没有设置这个属性.数据正在写入我的.m4a文件,但在播放时无法读取.总结一下:我有一堆AUSamplers - > AUMixer - > RemoteIO.RemoteIO实例上的渲染回调以压缩的m4a格式将数据写入磁盘.因此可以动态生成压缩音频(iOS 5/iPad 2)
看起来相当健壮 - 我在rendercallback中有一些printf语句,写入工作正常.
好极了!
ExtAudioFileProperty_CodecManufacturer扩展音频文件对象使用的编解码器的制造商.值是读/写UInt32.您必须在设置kExtAudioFileProperty_ClientDataFormat(页面20)属性之前指定此属性,该属性又会触发创建编解码器.使用iOS中该属性指定kAppleHardwareAudioCodecManufacturer或kAppleSoftwareAudioCodecManufacturer硬件或软件编码器之间进行选择.适用于Mac OS X v10.7及更高版本.在ExtendedAudioFile.h中声明.
// specify codec
UInt32 codec = kAppleHardwareAudioCodecManufacturer;
size = sizeof(codec);
result = ExtAudioFileSetProperty(extAudioFileRef,
kExtAudioFileProperty_CodecManufacturer,
size,
&codec);
if(result) printf("ExtAudioFileSetProperty %ld \n", result);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5647 次 |
| 最近记录: |