diff --git a/cocos/audio/include/AudioDecoderEXT.h b/cocos/audio/include/AudioDecoderEXT.h index 5128402cee..d52a3d3746 100644 --- a/cocos/audio/include/AudioDecoderEXT.h +++ b/cocos/audio/include/AudioDecoderEXT.h @@ -29,6 +29,7 @@ #include #import #include "audio/include/AudioDecoder.h" +#include "platform/CCFileStream.h" namespace cocos2d { @@ -83,8 +84,15 @@ public: bool seek(uint32_t frameOffset) override; private: + void closeInternal(); + + static OSStatus readCallback(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount); + static SInt64 getSizeCallback(void *inClientData); + ExtAudioFileRef _extRef; - + std::unique_ptr _fileStream; + AudioFileID _audioFileId; + AudioStreamBasicDescription _outputFormat; }; diff --git a/cocos/audio/src/AudioDecoderEXT.mm b/cocos/audio/src/AudioDecoderEXT.mm index 926743426d..ca44341420 100644 --- a/cocos/audio/src/AudioDecoderEXT.mm +++ b/cocos/audio/src/AudioDecoderEXT.mm @@ -26,6 +26,7 @@ #include "audio/include/AudioDecoderEXT.h" #include "audio/include/AudioMacros.h" +#include "platform/CCFileUtils.h" #import @@ -34,14 +35,14 @@ namespace cocos2d { AudioDecoderEXT::AudioDecoderEXT() - : _extRef(nullptr) + : _extRef(nullptr), _fileStream(nullptr), _audioFileId(nullptr) { memset(&_outputFormat, 0, sizeof(_outputFormat)); } AudioDecoderEXT::~AudioDecoderEXT() { - close(); + closeInternal(); } bool AudioDecoderEXT::open(const std::string& fullPath) @@ -52,12 +53,15 @@ namespace cocos2d { { BREAK_IF_ERR_LOG(fullPath.empty(), "Invalid path!"); - NSString *fileFullPath = [[NSString alloc] initWithCString:fullPath.c_str() encoding:NSUTF8StringEncoding]; - fileURL = (CFURLRef)[[NSURL alloc] initFileURLWithPath:fileFullPath]; - [fileFullPath release]; - BREAK_IF_ERR_LOG(fileURL == nil, "Converting path to CFURLRef failed!"); + _fileStream = cocos2d::FileUtils::getInstance()->openFileStream(fullPath, FileStream::Mode::READ); + BREAK_IF_ERR_LOG(_fileStream == nullptr, "FileUtils::openFileStream FAILED for file: %s", fullPath.c_str()); + + OSStatus status = AudioFileOpenWithCallbacks(_fileStream.get(), &AudioDecoderEXT::readCallback, nullptr, &AudioDecoderEXT::getSizeCallback, nullptr, 0, &_audioFileId); + BREAK_IF_ERR_LOG(status != noErr, "AudioFileOpenWithCallbacks FAILED, Error = %d", (int)status); + + status = ExtAudioFileWrapAudioFileID(_audioFileId, false, &_extRef); + BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileWrapAudioFileID FAILED, Error = %d", (int)status); - OSStatus status = ExtAudioFileOpenURL(fileURL, &_extRef); BREAK_IF_ERR_LOG(status != noErr, "ExtAudioFileOpenURL FAILED, Error = %d", (int)status); AudioStreamBasicDescription fileFormat; @@ -112,11 +116,7 @@ namespace cocos2d { void AudioDecoderEXT::close() { - if (_extRef != nullptr) - { - ExtAudioFileDispose(_extRef); - _extRef = nullptr; - } + closeInternal(); } uint32_t AudioDecoderEXT::read(uint32_t framesToRead, char* pcmBuf) @@ -158,4 +158,53 @@ namespace cocos2d { } while(false); return ret; } + + void AudioDecoderEXT::closeInternal() + { + if (_extRef != nullptr) + { + ExtAudioFileDispose(_extRef); + AudioFileClose(_audioFileId); + _extRef = nullptr; + _audioFileId = nullptr; + _fileStream = nullptr; + } + } + + OSStatus AudioDecoderEXT::readCallback(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount) + { + if (!inClientData) + { + return kAudioFileNotOpenError; + } + + auto* fileStream = (cocos2d::FileStream*)inClientData; + + const auto seekResult = fileStream->seek(inPosition, SEEK_SET); + if (seekResult < 0) + { + return kAudioFilePositionError; + } + + const auto count = fileStream->read(buffer, requestCount); + + if (count < 0) + { + return kAudioFileEndOfFileError; + } + + *actualCount = count; + + return noErr; + } + + SInt64 AudioDecoderEXT::getSizeCallback(void *inClientData) + { + auto* fileStream = (cocos2d::FileStream*)inClientData; + + fileStream->seek(0, SEEK_END); + auto fileSize = (SInt64)fileStream->tell(); + + return fileSize; + } } // namespace cocos2d {