2010-09-28 71 views
0

我在Apple的開發人員網站上使用SpeakHear示例應用程序來創建錄音應用程序。我試圖使用kAudioFormatAppleIMA4系統常量直接記錄到IMA4格式。這被列爲可用格式之一,但每次我設置我的音頻格式變量並傳遞並設置它時,我會得到'fmt?'錯誤。下面是我用它來設置音頻格式變量的代碼:以IMA4格式在iPhone上錄製單音

#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; 

} 

而且這裏是我使用的功能:

- (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

回答

3

我不確定您傳遞的所有格式標記是否正確; IMA4(其中IIRC代表IMA ADPCM 4:1)是4位(來自16位的4:1壓縮),帶有一些標頭。

根據該文檔爲AudioStreamBasicDescription

  • mBytesPerFrame應該是0,由於格式被壓縮。
  • mBitsPerChannel應該爲0,因爲格式是壓縮的。
  • mFormatFlags應該爲0,因爲沒有什麼可選的。

Aaccording至afconvert -f caff -t ima4 -c 1 blah.aiff blah.caf隨後afinfo blah.caf

  • mBytesPerPacket應該是34,和
  • mFramesPerPacket應該是64.你也許可以將這些設置爲0來代替。

original IMA spec中的參考算法沒有那麼有用(它是掃描的OCR,該站點也有掃描)。

1

在@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); 

這樣,你不需要用猜測的某些格式的功能打擾。被警告,雖然在這個例子中kAudioFormatiLBC不需要任何其他的信息,其他格式(通常是通道的數量和採樣率)。