Attention! Translated article might be found on my English blog.

2016年7月28日木曜日

ExtAudioFileSeek()で-66568(kExtAudioFileError_InvalidSeek)が返ってきてシークできなかった

シークする前にExtAudioFileSetProperty()で kExtAudioFileProperty_ClientDataFormatをセットする必要があるようです。

参考: Audio Unit:音楽ファイルを再生する

以下のコードでは、ファイルと同じASBD(AudioStreamBasicDescription)をセットしています。
- (void)prepareForRead {
    NSAssert(self.fileURL != nil && self.fileRef == NULL, @"");
    
    ExtAudioFileRef fileRef;
    OSStatus err = ExtAudioFileOpenURL((__bridge CFURLRef _Nonnull)(self.fileURL),
                                       &fileRef);
    _ASSERT_NOERR;
    
    self.fileRef = fileRef;
    
    UInt32 size = sizeof(ASBD);
    ASBD desc;
    err = ExtAudioFileGetProperty(self.fileRef,
                                  kExtAudioFileProperty_FileDataFormat,
                                  &size,
                                  &desc);
    _ASSERT_NOERR;
    self.format = desc;
    
    // ExtAudioFileSeek()を行うために必要。
    err = ExtAudioFileSetProperty(self.fileRef,
                                  kExtAudioFileProperty_ClientDataFormat,
                                  size,
                                  &desc);
    _ASSERT_NOERR;
}
.mp3や.m4aなどのnon-LPCMを扱う場合はLPCM用のASBDをclientDataFormatとしてセットしてください。

なお、上記の対策を施してもなおkExtAudioFileError_InvalidSeekが返る場合は、
他の原因があるかもしれません。

参考: ExtAudioFileSeek - Extended Audio File Services Reference
参考: ExtAudioFileSeek returning -66568 (kExtAudioFileError_InvalidSeek)
参考: ExtAudioFile woes