aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/src/common/Utilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/oboe/src/common/Utilities.cpp')
-rw-r--r--externals/oboe/src/common/Utilities.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/externals/oboe/src/common/Utilities.cpp b/externals/oboe/src/common/Utilities.cpp
new file mode 100644
index 0000000000..98cbb569ce
--- /dev/null
+++ b/externals/oboe/src/common/Utilities.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <set>
+#include <sstream>
+
+#ifdef __ANDROID__
+#include <sys/system_properties.h>
+#endif
+
+#include <oboe/AudioStream.h>
+#include "oboe/Definitions.h"
+#include "oboe/Utilities.h"
+
+namespace oboe {
+
+constexpr float kScaleI16ToFloat = (1.0f / 32768.0f);
+
+void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples) {
+ for (int i = 0; i < numSamples; i++) {
+ float fval = source[i];
+ fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation
+ fval *= 32768.0f;
+ auto sample = static_cast<int32_t>(fval);
+ // clip to 16-bit range
+ if (sample < 0) sample = 0;
+ else if (sample > 0x0FFFF) sample = 0x0FFFF;
+ sample -= 32768; // center at zero
+ destination[i] = static_cast<int16_t>(sample);
+ }
+}
+
+void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples) {
+ for (int i = 0; i < numSamples; i++) {
+ destination[i] = source[i] * kScaleI16ToFloat;
+ }
+}
+
+int32_t convertFormatToSizeInBytes(AudioFormat format) {
+ int32_t size = 0;
+ switch (format) {
+ case AudioFormat::I16:
+ size = sizeof(int16_t);
+ break;
+ case AudioFormat::Float:
+ size = sizeof(float);
+ break;
+ case AudioFormat::I24:
+ size = 3; // packed 24-bit data
+ break;
+ case AudioFormat::I32:
+ size = sizeof(int32_t);
+ break;
+ case AudioFormat::IEC61937:
+ size = sizeof(int16_t);
+ break;
+ case AudioFormat::MP3:
+ case AudioFormat::AAC_LC:
+ case AudioFormat::AAC_HE_V1:
+ case AudioFormat::AAC_HE_V2:
+ case AudioFormat::AAC_ELD:
+ case AudioFormat::AAC_XHE:
+ case AudioFormat::OPUS:
+ // For compressed formats, set the size per sample as 0 as they may not have
+ // fix size per sample.
+ size = 0;
+ break;
+ default:
+ break;
+ }
+ return size;
+}
+
+template<>
+const char *convertToText<Result>(Result returnCode) {
+ switch (returnCode) {
+ case Result::OK: return "OK";
+ case Result::ErrorDisconnected: return "ErrorDisconnected";
+ case Result::ErrorIllegalArgument: return "ErrorIllegalArgument";
+ case Result::ErrorInternal: return "ErrorInternal";
+ case Result::ErrorInvalidState: return "ErrorInvalidState";
+ case Result::ErrorInvalidHandle: return "ErrorInvalidHandle";
+ case Result::ErrorUnimplemented: return "ErrorUnimplemented";
+ case Result::ErrorUnavailable: return "ErrorUnavailable";
+ case Result::ErrorNoFreeHandles: return "ErrorNoFreeHandles";
+ case Result::ErrorNoMemory: return "ErrorNoMemory";
+ case Result::ErrorNull: return "ErrorNull";
+ case Result::ErrorTimeout: return "ErrorTimeout";
+ case Result::ErrorWouldBlock: return "ErrorWouldBlock";
+ case Result::ErrorInvalidFormat: return "ErrorInvalidFormat";
+ case Result::ErrorOutOfRange: return "ErrorOutOfRange";
+ case Result::ErrorNoService: return "ErrorNoService";
+ case Result::ErrorInvalidRate: return "ErrorInvalidRate";
+ case Result::ErrorClosed: return "ErrorClosed";
+ default: return "Unrecognized result";
+ }
+}
+
+template<>
+const char *convertToText<AudioFormat>(AudioFormat format) {
+ switch (format) {
+ case AudioFormat::Invalid: return "Invalid";
+ case AudioFormat::Unspecified: return "Unspecified";
+ case AudioFormat::I16: return "I16";
+ case AudioFormat::Float: return "Float";
+ case AudioFormat::I24: return "I24";
+ case AudioFormat::I32: return "I32";
+ case AudioFormat::IEC61937: return "IEC61937";
+ case AudioFormat::MP3: return "MP3";
+ case AudioFormat::AAC_LC: return "AAC_LC";
+ case AudioFormat::AAC_HE_V1: return "AAC_HE_V1";
+ case AudioFormat::AAC_HE_V2: return "AAC_HE_V2";
+ case AudioFormat::AAC_ELD: return "AAC_ELD";
+ case AudioFormat::AAC_XHE: return "AAC_XHE";
+ case AudioFormat::OPUS: return "OPUS";
+ default: return "Unrecognized format";
+ }
+}
+
+template<>
+const char *convertToText<PerformanceMode>(PerformanceMode mode) {
+ switch (mode) {
+ case PerformanceMode::LowLatency: return "LowLatency";
+ case PerformanceMode::None: return "None";
+ case PerformanceMode::PowerSaving: return "PowerSaving";
+ default: return "Unrecognized performance mode";
+ }
+}
+
+template<>
+const char *convertToText<SharingMode>(SharingMode mode) {
+ switch (mode) {
+ case SharingMode::Exclusive: return "Exclusive";
+ case SharingMode::Shared: return "Shared";
+ default: return "Unrecognized sharing mode";
+ }
+}
+
+template<>
+const char *convertToText<DataCallbackResult>(DataCallbackResult result) {
+ switch (result) {
+ case DataCallbackResult::Continue: return "Continue";
+ case DataCallbackResult::Stop: return "Stop";
+ default: return "Unrecognized data callback result";
+ }
+}
+
+template<>
+const char *convertToText<Direction>(Direction direction) {
+ switch (direction) {
+ case Direction::Input: return "Input";
+ case Direction::Output: return "Output";
+ default: return "Unrecognized direction";
+ }
+}
+
+template<>
+const char *convertToText<StreamState>(StreamState state) {
+ switch (state) {
+ case StreamState::Closed: return "Closed";
+ case StreamState::Closing: return "Closing";
+ case StreamState::Disconnected: return "Disconnected";
+ case StreamState::Flushed: return "Flushed";
+ case StreamState::Flushing: return "Flushing";
+ case StreamState::Open: return "Open";
+ case StreamState::Paused: return "Paused";
+ case StreamState::Pausing: return "Pausing";
+ case StreamState::Started: return "Started";
+ case StreamState::Starting: return "Starting";
+ case StreamState::Stopped: return "Stopped";
+ case StreamState::Stopping: return "Stopping";
+ case StreamState::Uninitialized: return "Uninitialized";
+ case StreamState::Unknown: return "Unknown";
+ default: return "Unrecognized stream state";
+ }
+}
+
+template<>
+const char *convertToText<AudioApi>(AudioApi audioApi) {
+
+ switch (audioApi) {
+ case AudioApi::Unspecified: return "Unspecified";
+ case AudioApi::OpenSLES: return "OpenSLES";
+ case AudioApi::AAudio: return "AAudio";
+ default: return "Unrecognized audio API";
+ }
+}
+
+template<>
+const char *convertToText<AudioStream*>(AudioStream* stream) {
+ static std::string streamText;
+ std::stringstream s;
+
+ s<<"StreamID: "<< static_cast<void*>(stream)<<std::endl
+ <<"DeviceId: "<<stream->getDeviceId()<<std::endl
+ <<"Direction: "<<oboe::convertToText(stream->getDirection())<<std::endl
+ <<"API type: "<<oboe::convertToText(stream->getAudioApi())<<std::endl
+ <<"BufferCapacity: "<<stream->getBufferCapacityInFrames()<<std::endl
+ <<"BufferSize: "<<stream->getBufferSizeInFrames()<<std::endl
+ <<"FramesPerBurst: "<< stream->getFramesPerBurst()<<std::endl
+ <<"FramesPerDataCallback: "<<stream->getFramesPerDataCallback()<<std::endl
+ <<"SampleRate: "<<stream->getSampleRate()<<std::endl
+ <<"ChannelCount: "<<stream->getChannelCount()<<std::endl
+ <<"Format: "<<oboe::convertToText(stream->getFormat())<<std::endl
+ <<"SharingMode: "<<oboe::convertToText(stream->getSharingMode())<<std::endl
+ <<"PerformanceMode: "<<oboe::convertToText(stream->getPerformanceMode())
+ <<std::endl
+ <<"CurrentState: "<<oboe::convertToText(stream->getState())<<std::endl
+ <<"XRunCount: "<<stream->getXRunCount()<<std::endl
+ <<"FramesRead: "<<stream->getFramesRead()<<std::endl
+ <<"FramesWritten: "<<stream->getFramesWritten()<<std::endl;
+
+ streamText = s.str();
+ return streamText.c_str();
+}
+
+template<>
+const char *convertToText<Usage>(Usage usage) {
+
+ switch (usage) {
+ case Usage::Media: return "Media";
+ case Usage::VoiceCommunication: return "VoiceCommunication";
+ case Usage::VoiceCommunicationSignalling: return "VoiceCommunicationSignalling";
+ case Usage::Alarm: return "Alarm";
+ case Usage::Notification: return "Notification";
+ case Usage::NotificationRingtone: return "NotificationRingtone";
+ case Usage::NotificationEvent: return "NotificationEvent";
+ case Usage::AssistanceAccessibility: return "AssistanceAccessibility";
+ case Usage::AssistanceNavigationGuidance: return "AssistanceNavigationGuidance";
+ case Usage::AssistanceSonification: return "AssistanceSonification";
+ case Usage::Game: return "Game";
+ case Usage::Assistant: return "Assistant";
+ default: return "Unrecognized usage";
+ }
+}
+
+template<>
+const char *convertToText<ContentType>(ContentType contentType) {
+
+ switch (contentType) {
+ case ContentType::Speech: return "Speech";
+ case ContentType::Music: return "Music";
+ case ContentType::Movie: return "Movie";
+ case ContentType::Sonification: return "Sonification";
+ default: return "Unrecognized content type";
+ }
+}
+
+template<>
+const char *convertToText<InputPreset>(InputPreset inputPreset) {
+
+ switch (inputPreset) {
+ case InputPreset::Generic: return "Generic";
+ case InputPreset::Camcorder: return "Camcorder";
+ case InputPreset::VoiceRecognition: return "VoiceRecognition";
+ case InputPreset::VoiceCommunication: return "VoiceCommunication";
+ case InputPreset::Unprocessed: return "Unprocessed";
+ case InputPreset::VoicePerformance: return "VoicePerformance";
+ default: return "Unrecognized input preset";
+ }
+}
+
+template<>
+const char *convertToText<SessionId>(SessionId sessionId) {
+
+ switch (sessionId) {
+ case SessionId::None: return "None";
+ case SessionId::Allocate: return "Allocate";
+ default: return "Unrecognized session id";
+ }
+}
+
+template<>
+const char *convertToText<ChannelCount>(ChannelCount channelCount) {
+
+ switch (channelCount) {
+ case ChannelCount::Unspecified: return "Unspecified";
+ case ChannelCount::Mono: return "Mono";
+ case ChannelCount::Stereo: return "Stereo";
+ default: return "Unrecognized channel count";
+ }
+}
+
+template<>
+const char *convertToText<SampleRateConversionQuality>(SampleRateConversionQuality sampleRateConversionQuality) {
+
+ switch (sampleRateConversionQuality) {
+ case SampleRateConversionQuality::None: return "None";
+ case SampleRateConversionQuality::Fastest: return "Fastest";
+ case SampleRateConversionQuality::Low: return "Low";
+ case SampleRateConversionQuality::Medium: return "Medium";
+ case SampleRateConversionQuality::High: return "High";
+ case SampleRateConversionQuality::Best: return "Best";
+ default: return "Unrecognized sample rate conversion quality";
+ }
+}
+
+std::string getPropertyString(const char * name) {
+ std::string result;
+#ifdef __ANDROID__
+ char valueText[PROP_VALUE_MAX] = {0};
+ if (__system_property_get(name, valueText) != 0) {
+ result = valueText;
+ }
+#else
+ (void) name;
+#endif
+ return result;
+}
+
+int getPropertyInteger(const char * name, int defaultValue) {
+ int result = defaultValue;
+#ifdef __ANDROID__
+ char valueText[PROP_VALUE_MAX] = {0};
+ if (__system_property_get(name, valueText) != 0) {
+ result = atoi(valueText);
+ }
+#else
+ (void) name;
+#endif
+ return result;
+}
+
+int getSdkVersion() {
+ static int sCachedSdkVersion = -1;
+#ifdef __ANDROID__
+ if (sCachedSdkVersion == -1) {
+ sCachedSdkVersion = getPropertyInteger("ro.build.version.sdk", -1);
+ }
+#endif
+ return sCachedSdkVersion;
+}
+
+bool isAtLeastPreReleaseCodename(const std::string& codename) {
+ std::string buildCodename = getPropertyString("ro.build.version.codename");
+ // Special case "REL", which means the build is not a pre-release build.
+ if ("REL" == buildCodename) {
+ return false;
+ }
+
+ // Otherwise lexically compare them. Return true if the build codename is equal to or
+ // greater than the requested codename.
+ return buildCodename.compare(codename) >= 0;
+}
+
+int getChannelCountFromChannelMask(ChannelMask channelMask) {
+ return __builtin_popcount(static_cast<uint32_t>(channelMask));
+}
+
+
+std::set<AudioFormat> COMPRESSED_FORMATS = {
+ AudioFormat::MP3, AudioFormat::AAC_LC, AudioFormat::AAC_HE_V1, AudioFormat::AAC_HE_V2,
+ AudioFormat::AAC_ELD, AudioFormat::AAC_XHE, AudioFormat::OPUS
+};
+bool isCompressedFormat(AudioFormat format) {
+ return COMPRESSED_FORMATS.count(format) != 0;
+}
+
+}// namespace oboe