diff options
Diffstat (limited to 'externals/oboe/src/common/Utilities.cpp')
| -rw-r--r-- | externals/oboe/src/common/Utilities.cpp | 375 |
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 |
