mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 23:24:41 +00:00
Initial commit
added libraries: opus flac libsndfile updated: libvorbis libogg openal - Everything works as expected for now. Bare in mind libsndfile needed the check for whether or not it could find the xiph libraries removed in order for this to work.
This commit is contained in:
parent
05a083ca6f
commit
a745fc3757
1954 changed files with 431332 additions and 21037 deletions
|
|
@ -71,9 +71,15 @@ constexpr SLuint32 GetChannelMask(DevFmtChannels chans) noexcept
|
|||
case DevFmtX61: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
|
||||
SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER |
|
||||
SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
|
||||
case DevFmtX71: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
|
||||
case DevFmtX71:
|
||||
case DevFmtX3D71: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
|
||||
SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
|
||||
SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
|
||||
case DevFmtX714: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
|
||||
SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
|
||||
SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT |
|
||||
SL_SPEAKER_TOP_FRONT_LEFT | SL_SPEAKER_TOP_FRONT_RIGHT | SL_SPEAKER_TOP_BACK_LEFT |
|
||||
SL_SPEAKER_TOP_BACK_RIGHT;
|
||||
case DevFmtAmbi3D:
|
||||
break;
|
||||
}
|
||||
|
|
@ -107,7 +113,7 @@ constexpr SLuint32 GetByteOrderEndianness() noexcept
|
|||
return SL_BYTEORDER_BIGENDIAN;
|
||||
}
|
||||
|
||||
const char *res_str(SLresult result) noexcept
|
||||
constexpr const char *res_str(SLresult result) noexcept
|
||||
{
|
||||
switch(result)
|
||||
{
|
||||
|
|
@ -141,10 +147,11 @@ const char *res_str(SLresult result) noexcept
|
|||
return "Unknown error code";
|
||||
}
|
||||
|
||||
#define PRINTERR(x, s) do { \
|
||||
if UNLIKELY((x) != SL_RESULT_SUCCESS) \
|
||||
ERR("%s: %s\n", (s), res_str((x))); \
|
||||
} while(0)
|
||||
inline void PrintErr(SLresult res, const char *str)
|
||||
{
|
||||
if(res != SL_RESULT_SUCCESS) UNLIKELY
|
||||
ERR("%s: %s\n", str, res_str(res));
|
||||
}
|
||||
|
||||
|
||||
struct OpenSLPlayback final : public BackendBase {
|
||||
|
|
@ -228,11 +235,11 @@ int OpenSLPlayback::mixerProc()
|
|||
SLAndroidSimpleBufferQueueItf bufferQueue;
|
||||
SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
|
||||
&bufferQueue)};
|
||||
PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
|
||||
PrintErr(result, "bufferQueue->GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
|
||||
PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
|
||||
PrintErr(result, "bufferQueue->GetInterface SL_IID_PLAY");
|
||||
}
|
||||
|
||||
const size_t frame_step{mDevice->channelsFromFmt()};
|
||||
|
|
@ -248,11 +255,11 @@ int OpenSLPlayback::mixerProc()
|
|||
SLuint32 state{0};
|
||||
|
||||
result = VCALL(player,GetPlayState)(&state);
|
||||
PRINTERR(result, "player->GetPlayState");
|
||||
PrintErr(result, "player->GetPlayState");
|
||||
if(SL_RESULT_SUCCESS == result && state != SL_PLAYSTATE_PLAYING)
|
||||
{
|
||||
result = VCALL(player,SetPlayState)(SL_PLAYSTATE_PLAYING);
|
||||
PRINTERR(result, "player->SetPlayState");
|
||||
PrintErr(result, "player->SetPlayState");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
{
|
||||
|
|
@ -289,7 +296,7 @@ int OpenSLPlayback::mixerProc()
|
|||
}
|
||||
|
||||
result = VCALL(bufferQueue,Enqueue)(data.first.buf, mDevice->UpdateSize*mFrameSize);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
PrintErr(result, "bufferQueue->Enqueue");
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
{
|
||||
mDevice->handleDisconnect("Failed to queue audio: 0x%08x", result);
|
||||
|
|
@ -318,26 +325,26 @@ void OpenSLPlayback::open(const char *name)
|
|||
|
||||
// create engine
|
||||
SLresult result{slCreateEngine(&mEngineObj, 0, nullptr, 0, nullptr, nullptr)};
|
||||
PRINTERR(result, "slCreateEngine");
|
||||
PrintErr(result, "slCreateEngine");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "engine->Realize");
|
||||
PrintErr(result, "engine->Realize");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
|
||||
PRINTERR(result, "engine->GetInterface");
|
||||
PrintErr(result, "engine->GetInterface");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mEngine,CreateOutputMix)(&mOutputMix, 0, nullptr, nullptr);
|
||||
PRINTERR(result, "engine->CreateOutputMix");
|
||||
PrintErr(result, "engine->CreateOutputMix");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mOutputMix,Realize)(SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "outputMix->Realize");
|
||||
PrintErr(result, "outputMix->Realize");
|
||||
}
|
||||
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
|
|
@ -505,20 +512,20 @@ bool OpenSLPlayback::reset()
|
|||
|
||||
result = VCALL(mEngine,CreateAudioPlayer)(&mBufferQueueObj, &audioSrc, &audioSnk, ids.size(),
|
||||
ids.data(), reqs.data());
|
||||
PRINTERR(result, "engine->CreateAudioPlayer");
|
||||
PrintErr(result, "engine->CreateAudioPlayer");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
/* Set the stream type to "media" (games, music, etc), if possible. */
|
||||
SLAndroidConfigurationItf config;
|
||||
result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
|
||||
PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
|
||||
PrintErr(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
|
||||
result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE, &streamType,
|
||||
sizeof(streamType));
|
||||
PRINTERR(result, "config->SetConfiguration");
|
||||
PrintErr(result, "config->SetConfiguration");
|
||||
}
|
||||
|
||||
/* Clear any error since this was optional. */
|
||||
|
|
@ -527,7 +534,7 @@ bool OpenSLPlayback::reset()
|
|||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "bufferQueue->Realize");
|
||||
PrintErr(result, "bufferQueue->Realize");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
|
|
@ -554,11 +561,11 @@ void OpenSLPlayback::start()
|
|||
SLAndroidSimpleBufferQueueItf bufferQueue;
|
||||
SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
|
||||
&bufferQueue)};
|
||||
PRINTERR(result, "bufferQueue->GetInterface");
|
||||
PrintErr(result, "bufferQueue->GetInterface");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(bufferQueue,RegisterCallback)(&OpenSLPlayback::processC, this);
|
||||
PRINTERR(result, "bufferQueue->RegisterCallback");
|
||||
PrintErr(result, "bufferQueue->RegisterCallback");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
throw al::backend_exception{al::backend_error::DeviceError,
|
||||
|
|
@ -584,25 +591,25 @@ void OpenSLPlayback::stop()
|
|||
|
||||
SLPlayItf player;
|
||||
SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player)};
|
||||
PRINTERR(result, "bufferQueue->GetInterface");
|
||||
PrintErr(result, "bufferQueue->GetInterface");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED);
|
||||
PRINTERR(result, "player->SetPlayState");
|
||||
PrintErr(result, "player->SetPlayState");
|
||||
}
|
||||
|
||||
SLAndroidSimpleBufferQueueItf bufferQueue;
|
||||
result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
|
||||
PRINTERR(result, "bufferQueue->GetInterface");
|
||||
PrintErr(result, "bufferQueue->GetInterface");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL0(bufferQueue,Clear)();
|
||||
PRINTERR(result, "bufferQueue->Clear");
|
||||
PrintErr(result, "bufferQueue->Clear");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(bufferQueue,RegisterCallback)(nullptr, nullptr);
|
||||
PRINTERR(result, "bufferQueue->RegisterCallback");
|
||||
PrintErr(result, "bufferQueue->RegisterCallback");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
|
|
@ -611,7 +618,9 @@ void OpenSLPlayback::stop()
|
|||
std::this_thread::yield();
|
||||
result = VCALL(bufferQueue,GetState)(&state);
|
||||
} while(SL_RESULT_SUCCESS == result && state.count > 0);
|
||||
PRINTERR(result, "bufferQueue->GetState");
|
||||
PrintErr(result, "bufferQueue->GetState");
|
||||
|
||||
mRing->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -686,16 +695,16 @@ void OpenSLCapture::open(const char* name)
|
|||
name};
|
||||
|
||||
SLresult result{slCreateEngine(&mEngineObj, 0, nullptr, 0, nullptr, nullptr)};
|
||||
PRINTERR(result, "slCreateEngine");
|
||||
PrintErr(result, "slCreateEngine");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "engine->Realize");
|
||||
PrintErr(result, "engine->Realize");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
|
||||
PRINTERR(result, "engine->GetInterface");
|
||||
PrintErr(result, "engine->GetInterface");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
|
|
@ -770,7 +779,7 @@ void OpenSLCapture::open(const char* name)
|
|||
result = VCALL(mEngine,CreateAudioRecorder)(&mRecordObj, &audioSrc, &audioSnk,
|
||||
ids.size(), ids.data(), reqs.data());
|
||||
}
|
||||
PRINTERR(result, "engine->CreateAudioRecorder");
|
||||
PrintErr(result, "engine->CreateAudioRecorder");
|
||||
}
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
|
|
@ -778,13 +787,13 @@ void OpenSLCapture::open(const char* name)
|
|||
/* Set the record preset to "generic", if possible. */
|
||||
SLAndroidConfigurationItf config;
|
||||
result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
|
||||
PRINTERR(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
|
||||
PrintErr(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
SLuint32 preset = SL_ANDROID_RECORDING_PRESET_GENERIC;
|
||||
result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET, &preset,
|
||||
sizeof(preset));
|
||||
PRINTERR(result, "config->SetConfiguration");
|
||||
PrintErr(result, "config->SetConfiguration");
|
||||
}
|
||||
|
||||
/* Clear any error since this was optional. */
|
||||
|
|
@ -793,19 +802,19 @@ void OpenSLCapture::open(const char* name)
|
|||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mRecordObj,Realize)(SL_BOOLEAN_FALSE);
|
||||
PRINTERR(result, "recordObj->Realize");
|
||||
PrintErr(result, "recordObj->Realize");
|
||||
}
|
||||
|
||||
SLAndroidSimpleBufferQueueItf bufferQueue;
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
|
||||
PRINTERR(result, "recordObj->GetInterface");
|
||||
PrintErr(result, "recordObj->GetInterface");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(bufferQueue,RegisterCallback)(&OpenSLCapture::processC, this);
|
||||
PRINTERR(result, "bufferQueue->RegisterCallback");
|
||||
PrintErr(result, "bufferQueue->RegisterCallback");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
|
|
@ -818,12 +827,12 @@ void OpenSLCapture::open(const char* name)
|
|||
for(size_t i{0u};i < data.first.len && SL_RESULT_SUCCESS == result;i++)
|
||||
{
|
||||
result = VCALL(bufferQueue,Enqueue)(data.first.buf + chunk_size*i, chunk_size);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
PrintErr(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
for(size_t i{0u};i < data.second.len && SL_RESULT_SUCCESS == result;i++)
|
||||
{
|
||||
result = VCALL(bufferQueue,Enqueue)(data.second.buf + chunk_size*i, chunk_size);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
PrintErr(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -849,12 +858,12 @@ void OpenSLCapture::start()
|
|||
{
|
||||
SLRecordItf record;
|
||||
SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
|
||||
PRINTERR(result, "recordObj->GetInterface");
|
||||
PrintErr(result, "recordObj->GetInterface");
|
||||
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(record,SetRecordState)(SL_RECORDSTATE_RECORDING);
|
||||
PRINTERR(result, "record->SetRecordState");
|
||||
PrintErr(result, "record->SetRecordState");
|
||||
}
|
||||
if(SL_RESULT_SUCCESS != result)
|
||||
throw al::backend_exception{al::backend_error::DeviceError,
|
||||
|
|
@ -865,12 +874,12 @@ void OpenSLCapture::stop()
|
|||
{
|
||||
SLRecordItf record;
|
||||
SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
|
||||
PRINTERR(result, "recordObj->GetInterface");
|
||||
PrintErr(result, "recordObj->GetInterface");
|
||||
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
result = VCALL(record,SetRecordState)(SL_RECORDSTATE_PAUSED);
|
||||
PRINTERR(result, "record->SetRecordState");
|
||||
PrintErr(result, "record->SetRecordState");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -878,7 +887,6 @@ void OpenSLCapture::captureSamples(al::byte *buffer, uint samples)
|
|||
{
|
||||
const uint update_size{mDevice->UpdateSize};
|
||||
const uint chunk_size{update_size * mFrameSize};
|
||||
const auto silence = (mDevice->FmtType == DevFmtUByte) ? al::byte{0x80} : al::byte{0};
|
||||
|
||||
/* Read the desired samples from the ring buffer then advance its read
|
||||
* pointer.
|
||||
|
|
@ -907,39 +915,52 @@ void OpenSLCapture::captureSamples(al::byte *buffer, uint samples)
|
|||
|
||||
i += rem;
|
||||
}
|
||||
mRing->readAdvance(adv_count);
|
||||
|
||||
SLAndroidSimpleBufferQueueItf bufferQueue{};
|
||||
if LIKELY(mDevice->Connected.load(std::memory_order_acquire))
|
||||
if(mDevice->Connected.load(std::memory_order_acquire)) LIKELY
|
||||
{
|
||||
const SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
|
||||
&bufferQueue)};
|
||||
PRINTERR(result, "recordObj->GetInterface");
|
||||
if UNLIKELY(SL_RESULT_SUCCESS != result)
|
||||
PrintErr(result, "recordObj->GetInterface");
|
||||
if(SL_RESULT_SUCCESS != result) UNLIKELY
|
||||
{
|
||||
mDevice->handleDisconnect("Failed to get capture buffer queue: 0x%08x", result);
|
||||
bufferQueue = nullptr;
|
||||
}
|
||||
}
|
||||
if(!bufferQueue || adv_count == 0)
|
||||
return;
|
||||
|
||||
if LIKELY(bufferQueue)
|
||||
/* For each buffer chunk that was fully read, queue another writable buffer
|
||||
* chunk to keep the OpenSL queue full. This is rather convulated, as a
|
||||
* result of the ring buffer holding more elements than are writable at a
|
||||
* given time. The end of the write vector increments when the read pointer
|
||||
* advances, which will "expose" a previously unwritable element. So for
|
||||
* every element that we've finished reading, we queue that many elements
|
||||
* from the end of the write vector.
|
||||
*/
|
||||
mRing->readAdvance(adv_count);
|
||||
|
||||
SLresult result{SL_RESULT_SUCCESS};
|
||||
auto wdata = mRing->getWriteVector();
|
||||
if(adv_count > wdata.second.len) LIKELY
|
||||
{
|
||||
SLresult result{SL_RESULT_SUCCESS};
|
||||
auto wdata = mRing->getWriteVector();
|
||||
std::fill_n(wdata.first.buf, wdata.first.len*chunk_size, silence);
|
||||
for(size_t i{0u};i < wdata.first.len && SL_RESULT_SUCCESS == result;i++)
|
||||
auto len1 = std::min(wdata.first.len, adv_count-wdata.second.len);
|
||||
auto buf1 = wdata.first.buf + chunk_size*(wdata.first.len-len1);
|
||||
for(size_t i{0u};i < len1 && SL_RESULT_SUCCESS == result;i++)
|
||||
{
|
||||
result = VCALL(bufferQueue,Enqueue)(wdata.first.buf + chunk_size*i, chunk_size);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
result = VCALL(bufferQueue,Enqueue)(buf1 + chunk_size*i, chunk_size);
|
||||
PrintErr(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
if(wdata.second.len > 0)
|
||||
}
|
||||
if(wdata.second.len > 0)
|
||||
{
|
||||
auto len2 = std::min(wdata.second.len, adv_count);
|
||||
auto buf2 = wdata.second.buf + chunk_size*(wdata.second.len-len2);
|
||||
for(size_t i{0u};i < len2 && SL_RESULT_SUCCESS == result;i++)
|
||||
{
|
||||
std::fill_n(wdata.second.buf, wdata.second.len*chunk_size, silence);
|
||||
for(size_t i{0u};i < wdata.second.len && SL_RESULT_SUCCESS == result;i++)
|
||||
{
|
||||
result = VCALL(bufferQueue,Enqueue)(wdata.second.buf + chunk_size*i, chunk_size);
|
||||
PRINTERR(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
result = VCALL(bufferQueue,Enqueue)(buf2 + chunk_size*i, chunk_size);
|
||||
PrintErr(result, "bufferQueue->Enqueue");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue