为什么 OpenSL ES 不会在每次启动应用程序时播放音频
Why OpenSL ES won't play audio every time an application is started
我正在使用Android上的OpenSL ES在游戏引擎中实现音频播放。到目前为止,我仅支持Android文件描述符数据定位器(AndroidFD)。问题是,如果我在Opensles。epensles。
包装纸:
audioEngine.cpp
AudioEngine::AudioEngine()
: _engine(NULL),
_engineInterface(NULL),
_outputMix(NULL)
{
createEngine();
createOutputMix();
}
AudioEngine::~AudioEngine()
{
(*_outputMix)->Destroy(_outputMix);
(*_engine)->Destroy(_engine);
}
Sound* AudioEngine::loadSound(const String& filename) const
{
return NEW Sound(_engineInterface, _outputMix, filename);
}
// Private
void AudioEngine::createEngine()
{
Uint32 result = slCreateEngine(&_engine, 0u, NULL, 0u, NULL, NULL);
CHECK_OPENSLES_ERROR(result, "Platform::AudioEngine (OpenSLES)",
"Failed to create the engine");
result = (*_engine)->Realize(_engine, SL_BOOLEAN_FALSE);
CHECK_OPENSLES_ERROR(result, "Platform::AudioEngine (OpenSLES)",
"Failed to initialise the engine");
result = (*_engine)->GetInterface(_engine, SL_IID_ENGINE, &_engineInterface);
CHECK_OPENSLES_ERROR(result, "Platform::AudioEngine (OpenSLES)",
"Failed to get the engine interface");
}
void AudioEngine::createOutputMix()
{
Uint32 result = (*_engineInterface)->CreateOutputMix(_engineInterface, &_outputMix, 0u,
NULL, NULL);
CHECK_OPENSLES_ERROR(result, "Platform::AudioEngine (OpenSLES)",
"Failed to create the output mix");
result = (*_outputMix)->Realize(_outputMix, SL_BOOLEAN_FALSE);
CHECK_OPENSLES_ERROR(result, "Platform::AudioEngine (OpenSLES)",
"Failed to initialise the output mix");
}
sound.cpp
// Public
Sound::Sound(SLEngineItf engineInterface, SLObjectItf outputMix, const String& filename)
: _engineInterface(engineInterface),
_outputMix(outputMix),
_player(NULL),
_playerInterface(NULL)
{
// Member (SLDataFormat_MIME)
_dataSourceFormat.formatType = SL_DATAFORMAT_MIME;
_dataSourceFormat.mimeType = NULL;
_dataSourceFormat.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
// Member (SLDataLocator_AndroidFD)
_dataSourceLocator.locatorType = SL_DATALOCATOR_ANDROIDFD;
AAssetManager* assetManager = Application::assetManager();
AAsset* asset = AAssetManager_open(assetManager, filename.data(), AASSET_MODE_UNKNOWN);
_dataSourceLocator.fd = AAsset_openFileDescriptor(asset,
reinterpret_cast<off_t*>(&_dataSourceLocator.offset),
reinterpret_cast<off_t*>(&_dataSourceLocator.length));
AAsset_close(asset);
createPlayer();
}
Sound::~Sound()
{
(*_player)->Destroy(_player);
}
void Sound::play() const
{
const Uint32 result = (*_playerInterface)->SetPlayState(_playerInterface,
SL_PLAYSTATE_PLAYING);
CHECK_OPENSLES_ERROR(result, "Platform::Sound (OpenSLES)",
"Failed to set the play state");
}
// Private
void Sound::createPlayer()
{
SLDataSource dataSource =
{
&_dataSourceLocator,
&_dataSourceFormat
};
SLDataLocator_OutputMix outputMixLocator =
{
SL_DATALOCATOR_OUTPUTMIX,
_outputMix
};
SLDataSink dataSink =
{
&outputMixLocator,
NULL
};
Uint32 result = (*_engineInterface)->CreateAudioPlayer(_engineInterface, &_player,
&dataSource, &dataSink, 0u, NULL, NULL);
CHECK_OPENSLES_ERROR(result, "Platform::Sound (OpenSLES)",
"Failed to create a player");
result = (*_player)->Realize(_player, SL_BOOLEAN_FALSE);
CHECK_OPENSLES_ERROR(result, "Platform::Sound (OpenSLES)",
"Failed to initialise the player");
result = (*_player)->GetInterface(_player, SL_IID_PLAY, &_playerInterface);
CHECK_OPENSLES_ERROR(result, "Platform::SoundInstance (OpenSLES)",
"Failed to get the player interface");
}
game.cpp
Game::initialise()
{
_audioEngine = NEW AudioEngine();
_sound = _audioEngine->loadSound("music.ogg");
_sound->play();
}
应用程序启动时,声音将不会总是播放。如果我在游戏内部:: directise()中写下所有opensl es代码,则声音将始终播放。我无法弄清楚为什么在包装器类中不使用相同的代码。
我在三星Galaxy S III(GT-I9305),Android 4.2.2,Cyanogenmod 10.1.3-I9305
在播放声音时,您可能必须将数据源,outputmixlocator和datasink保留在范围内,因为它们被作为指针传递。使它们成为成员变量,以使它们在物体的寿命中保持活力。
相关文章:
- QSerialPort 在应用程序启动之前正在使用中
- C++ - 从 MFC 应用程序启动记事本,并将其默认标题从 "Untitled - Notepad" 更改为其他内容
- 在应用程序启动时停靠 QDockWidget?
- 在应用程序启动时读取文件
- osX - 如何从我的 QT 应用程序启动另一个程序
- 如何跟踪 C++14 中的控制台应用程序启动的次数?
- 调试从 Linux 中的另一个C++应用程序启动的 python 脚本
- 添加新对话框后,MFC 应用程序启动失败并"DLL Initialization Failed"
- 在应用程序启动之前做某事
- 基于CDialog的应用程序启动时,如何将我的辅助对话框窗口带到顶部
- 在Qt和C++中从另一个应用程序启动一个应用软件会产生问题
- 在 C++/STL/MFC 应用程序启动早期发生的致命异常中,是否可以信任堆栈回溯符号名称?
- 从控制台应用程序启动窗口应用程序
- 如何从另一个C++控制台应用程序启动/结束C++控制台应用程序
- 从 MFC(c++) 应用程序启动的可执行 jar 中获取返回值
- 从 MFC 应用程序启动 Java 时,在 MFC 应用程序中显示等待光标,直到它完成其进程
- 从控制台应用程序启动控制台应用程序
- Windows应用程序启动我的控制台
- 从应用程序启动 Linux 服务时避免套接字继承C++
- 如何在应用程序启动后隐藏其命令提示符