在iPhone上以IMA4格式录制单声道

我正在使用Apple开发者网站上的SpeakHear示例应用程序来创建录音应用程序。 我正在尝试使用kAudioFormatAppleIMA4系统常量直接录制到IMA4格式。 这被列为可用格式之一,但每次我设置我的音频格式变量并通过并设置它时,我得到一个’fmt?’ 错误。 这是我用来设置音频格式变量的代码:

#define kAudioRecordingFormat kAudioFormatAppleIMA4 #define kAudioRecordingType kAudioFileCAFType #define kAudioRecordingSampleRate 16000.00 #define kAudioRecordingChannelsPerFrame 1 #define kAudioRecordingFramesPerPacket 1 #define kAudioRecordingBitsPerChannel 16 #define kAudioRecordingBytesPerPacket 2 #define kAudioRecordingBytesPerFrame 2 - (void) setupAudioFormat: (UInt32) formatID { // Obtains the hardware sample rate for use in the recording // audio format. Each time the audio route changes, the sample rate // needs to get updated. UInt32 propertySize = sizeof (self.hardwareSampleRate); OSStatus err = AudioSessionGetProperty ( kAudioSessionProperty_CurrentHardwareSampleRate, &propertySize, &hardwareSampleRate ); if(err != 0){ NSLog(@"AudioRecorder::setupAudioFormat - error getting audio session property"); } audioFormat.mSampleRate = kAudioRecordingSampleRate; NSLog (@"Hardware sample rate = %f", self.audioFormat.mSampleRate); audioFormat.mFormatID = formatID; audioFormat.mChannelsPerFrame = kAudioRecordingChannelsPerFrame; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = kAudioRecordingFramesPerPacket; audioFormat.mBitsPerChannel = kAudioRecordingBitsPerChannel; audioFormat.mBytesPerPacket = kAudioRecordingBytesPerPacket; audioFormat.mBytesPerFrame = kAudioRecordingBytesPerFrame; } 

这是我使用该function的地方:

 - (id) initWithURL: fileURL { NSLog (@"initializing a recorder object."); self = [super init]; if (self != nil) { // Specify the recording format. Options are: // // kAudioFormatLinearPCM // kAudioFormatAppleLossless // kAudioFormatAppleIMA4 // kAudioFormatiLBC // kAudioFormatULaw // kAudioFormatALaw // // When targeting the Simulator, SpeakHere uses linear PCM regardless of the format // specified here. See the setupAudioFormat: method in this file. [self setupAudioFormat: kAudioRecordingFormat]; OSStatus result = AudioQueueNewInput ( &audioFormat, recordingCallback, self, // userData NULL, // run loop NULL, // run loop mode 0, // flags &queueObject ); NSLog (@"Attempted to create new recording audio queue object. Result: %f", result); // get the recording format back from the audio queue's audio converter -- // the file may require a more specific stream description than was // necessary to create the encoder. UInt32 sizeOfRecordingFormatASBDStruct = sizeof (audioFormat); AudioQueueGetProperty ( queueObject, kAudioQueueProperty_StreamDescription, // this constant is only available in iPhone OS &audioFormat, &sizeOfRecordingFormatASBDStruct ); AudioQueueAddPropertyListener ( [self queueObject], kAudioQueueProperty_IsRunning, audioQueuePropertyListenerCallback, self ); [self setAudioFileURL: (CFURLRef) fileURL]; [self enableLevelMetering]; } return self; } 

谢谢您的帮助! -Matt

我不确定你传递的所有格式标志是否正确; IMA4(其中,IIRC,代表IMA ADPCM 4:1)是4位(16位的4:1压缩),带有一些标头。

根据AudioStreamBasicDescription的文档:

  • 由于格式是压缩的,因此mBytesPerFrame应为0。
  • mBitsPerChannel应为0,因为格式是压缩的。
  • mFormatFlags可能应为0,因为没有什么可供选择的。

根据afconvert -f caff -t ima4 -c 1 blah.aiff blah.caf然后是afinfo blah.caf

  • mBytesPerPacket应该是34,和
  • mFramesPerPacket应为64.您可以将这些设置为0。

原始IMA规范中的参考算法没有那么有用(它是扫描的OCR,该站点也有扫描)。

除了@tc之外。 已经说过,使用以下内容更容易根据ID自动填充您的描述:

 AudioStreamBasicDescription streamDescription; UInt32 streamDesSize = sizeof(streamDescription); memset(&streamDescription, 0, streamDesSize); streamDescription.mFormatID = kAudioFormatiLBC; OSStatus status; status = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &streamDesSize, &streamDescription); assert(status==noErr); 

这样您就不必费心去猜测某些格式的function了。 请注意,虽然在此示例中kAudioFormatiLBC不需要任何其他格式,但其他格式(通常是通道数和采样率)。