• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <sstream>
21 
22 #ifdef __ANDROID__
23 #include <sys/system_properties.h>
24 #endif
25 
26 #include <oboe/AudioStream.h>
27 #include "oboe/Definitions.h"
28 #include "oboe/Utilities.h"
29 
30 namespace oboe {
31 
32 constexpr float kScaleI16ToFloat = (1.0f / 32768.0f);
33 
convertFloatToPcm16(const float * source,int16_t * destination,int32_t numSamples)34 void convertFloatToPcm16(const float *source, int16_t *destination, int32_t numSamples) {
35     for (int i = 0; i < numSamples; i++) {
36         float fval = source[i];
37         fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation
38         fval *= 32768.0f;
39         auto sample = static_cast<int32_t>(fval);
40         // clip to 16-bit range
41         if (sample < 0) sample = 0;
42         else if (sample > 0x0FFFF) sample = 0x0FFFF;
43         sample -= 32768; // center at zero
44         destination[i] = static_cast<int16_t>(sample);
45     }
46 }
47 
convertPcm16ToFloat(const int16_t * source,float * destination,int32_t numSamples)48 void convertPcm16ToFloat(const int16_t *source, float *destination, int32_t numSamples) {
49     for (int i = 0; i < numSamples; i++) {
50         destination[i] = source[i] * kScaleI16ToFloat;
51     }
52 }
53 
convertFormatToSizeInBytes(AudioFormat format)54 int32_t convertFormatToSizeInBytes(AudioFormat format) {
55     int32_t size = 0;
56     switch (format) {
57         case AudioFormat::I16:
58             size = sizeof(int16_t);
59             break;
60         case AudioFormat::Float:
61             size = sizeof(float);
62             break;
63         default:
64             break;
65     }
66     return size;
67 }
68 
69 template<>
convertToText(Result returnCode)70 const char *convertToText<Result>(Result returnCode) {
71     switch (returnCode) {
72         case Result::OK:                    return "OK";
73         case Result::ErrorDisconnected:     return "ErrorDisconnected";
74         case Result::ErrorIllegalArgument:  return "ErrorIllegalArgument";
75         case Result::ErrorInternal:         return "ErrorInternal";
76         case Result::ErrorInvalidState:     return "ErrorInvalidState";
77         case Result::ErrorInvalidHandle:    return "ErrorInvalidHandle";
78         case Result::ErrorUnimplemented:    return "ErrorUnimplemented";
79         case Result::ErrorUnavailable:      return "ErrorUnavailable";
80         case Result::ErrorNoFreeHandles:    return "ErrorNoFreeHandles";
81         case Result::ErrorNoMemory:         return "ErrorNoMemory";
82         case Result::ErrorNull:             return "ErrorNull";
83         case Result::ErrorTimeout:          return "ErrorTimeout";
84         case Result::ErrorWouldBlock:       return "ErrorWouldBlock";
85         case Result::ErrorInvalidFormat:    return "ErrorInvalidFormat";
86         case Result::ErrorOutOfRange:       return "ErrorOutOfRange";
87         case Result::ErrorNoService:        return "ErrorNoService";
88         case Result::ErrorInvalidRate:      return "ErrorInvalidRate";
89         case Result::ErrorClosed:           return "ErrorClosed";
90         default:                            return "Unrecognized result";
91     }
92 }
93 
94 template<>
convertToText(AudioFormat format)95 const char *convertToText<AudioFormat>(AudioFormat format) {
96     switch (format) {
97         case AudioFormat::Invalid:      return "Invalid";
98         case AudioFormat::Unspecified:  return "Unspecified";
99         case AudioFormat::I16:          return "I16";
100         case AudioFormat::Float:        return "Float";
101         default:                        return "Unrecognized format";
102     }
103 }
104 
105 template<>
convertToText(PerformanceMode mode)106 const char *convertToText<PerformanceMode>(PerformanceMode mode) {
107     switch (mode) {
108         case PerformanceMode::LowLatency:   return "LowLatency";
109         case PerformanceMode::None:         return "None";
110         case PerformanceMode::PowerSaving:  return "PowerSaving";
111         default:                            return "Unrecognized performance mode";
112     }
113 }
114 
115 template<>
convertToText(SharingMode mode)116 const char *convertToText<SharingMode>(SharingMode mode) {
117     switch (mode) {
118         case SharingMode::Exclusive:    return "Exclusive";
119         case SharingMode::Shared:       return "Shared";
120         default:                        return "Unrecognized sharing mode";
121     }
122 }
123 
124 template<>
convertToText(DataCallbackResult result)125 const char *convertToText<DataCallbackResult>(DataCallbackResult result) {
126     switch (result) {
127         case DataCallbackResult::Continue:  return "Continue";
128         case DataCallbackResult::Stop:      return "Stop";
129         default:                            return "Unrecognized data callback result";
130     }
131 }
132 
133 template<>
convertToText(Direction direction)134 const char *convertToText<Direction>(Direction direction) {
135     switch (direction) {
136         case Direction::Input:  return "Input";
137         case Direction::Output: return "Output";
138         default:                return "Unrecognized direction";
139     }
140 }
141 
142 template<>
convertToText(StreamState state)143 const char *convertToText<StreamState>(StreamState state) {
144     switch (state) {
145         case StreamState::Closed:           return "Closed";
146         case StreamState::Closing:          return "Closing";
147         case StreamState::Disconnected:     return "Disconnected";
148         case StreamState::Flushed:          return "Flushed";
149         case StreamState::Flushing:         return "Flushing";
150         case StreamState::Open:             return "Open";
151         case StreamState::Paused:           return "Paused";
152         case StreamState::Pausing:          return "Pausing";
153         case StreamState::Started:          return "Started";
154         case StreamState::Starting:         return "Starting";
155         case StreamState::Stopped:          return "Stopped";
156         case StreamState::Stopping:         return "Stopping";
157         case StreamState::Uninitialized:    return "Uninitialized";
158         case StreamState::Unknown:          return "Unknown";
159         default:                            return "Unrecognized stream state";
160     }
161 }
162 
163 template<>
convertToText(AudioApi audioApi)164 const char *convertToText<AudioApi>(AudioApi audioApi) {
165 
166     switch (audioApi) {
167         case AudioApi::Unspecified: return "Unspecified";
168         case AudioApi::OpenSLES:    return "OpenSLES";
169         case AudioApi::AAudio:      return "AAudio";
170         default:                    return "Unrecognized audio API";
171     }
172 }
173 
174 template<>
convertToText(AudioStream * stream)175 const char *convertToText<AudioStream*>(AudioStream* stream) {
176     static std::string streamText;
177     std::stringstream s;
178 
179     s<<"StreamID: "<< static_cast<void*>(stream)<<std::endl
180      <<"DeviceId: "<<stream->getDeviceId()<<std::endl
181      <<"Direction: "<<oboe::convertToText(stream->getDirection())<<std::endl
182      <<"API type: "<<oboe::convertToText(stream->getAudioApi())<<std::endl
183      <<"BufferCapacity: "<<stream->getBufferCapacityInFrames()<<std::endl
184      <<"BufferSize: "<<stream->getBufferSizeInFrames()<<std::endl
185      <<"FramesPerBurst: "<< stream->getFramesPerBurst()<<std::endl
186      <<"FramesPerDataCallback: "<<stream->getFramesPerDataCallback()<<std::endl
187      <<"SampleRate: "<<stream->getSampleRate()<<std::endl
188      <<"ChannelCount: "<<stream->getChannelCount()<<std::endl
189      <<"Format: "<<oboe::convertToText(stream->getFormat())<<std::endl
190      <<"SharingMode: "<<oboe::convertToText(stream->getSharingMode())<<std::endl
191      <<"PerformanceMode: "<<oboe::convertToText(stream->getPerformanceMode())
192      <<std::endl
193      <<"CurrentState: "<<oboe::convertToText(stream->getState())<<std::endl
194      <<"XRunCount: "<<stream->getXRunCount()<<std::endl
195      <<"FramesRead: "<<stream->getFramesRead()<<std::endl
196      <<"FramesWritten: "<<stream->getFramesWritten()<<std::endl;
197 
198     streamText = s.str();
199     return streamText.c_str();
200 }
201 
202 template<>
convertToText(Usage usage)203 const char *convertToText<Usage>(Usage usage) {
204 
205     switch (usage) {
206         case Usage::Media:                         return "Media";
207         case Usage::VoiceCommunication:            return "VoiceCommunication";
208         case Usage::VoiceCommunicationSignalling:  return "VoiceCommunicationSignalling";
209         case Usage::Alarm:                         return "Alarm";
210         case Usage::Notification:                  return "Notification";
211         case Usage::NotificationRingtone:          return "NotificationRingtone";
212         case Usage::NotificationEvent:             return "NotificationEvent";
213         case Usage::AssistanceAccessibility:       return "AssistanceAccessibility";
214         case Usage::AssistanceNavigationGuidance:  return "AssistanceNavigationGuidance";
215         case Usage::AssistanceSonification:        return "AssistanceSonification";
216         case Usage::Game:                          return "Game";
217         case Usage::Assistant:                     return "Assistant";
218         default:                                   return "Unrecognized usage";
219     }
220 }
221 
222 template<>
convertToText(ContentType contentType)223 const char *convertToText<ContentType>(ContentType contentType) {
224 
225     switch (contentType) {
226         case ContentType::Speech:        return "Speech";
227         case ContentType::Music:         return "Music";
228         case ContentType::Movie:         return "Movie";
229         case ContentType::Sonification:  return "Sonification";
230         default:                         return "Unrecognized content type";
231     }
232 }
233 
234 template<>
convertToText(InputPreset inputPreset)235 const char *convertToText<InputPreset>(InputPreset inputPreset) {
236 
237     switch (inputPreset) {
238         case InputPreset::Generic:             return "Generic";
239         case InputPreset::Camcorder:           return "Camcorder";
240         case InputPreset::VoiceRecognition:    return "VoiceRecognition";
241         case InputPreset::VoiceCommunication:  return "VoiceCommunication";
242         case InputPreset::Unprocessed:         return "Unprocessed";
243         case InputPreset::VoicePerformance:    return "VoicePerformance";
244         default:                               return "Unrecognized input preset";
245     }
246 }
247 
248 template<>
convertToText(SessionId sessionId)249 const char *convertToText<SessionId>(SessionId sessionId) {
250 
251     switch (sessionId) {
252         case SessionId::None:      return "None";
253         case SessionId::Allocate:  return "Allocate";
254         default:                   return "Unrecognized session id";
255     }
256 }
257 
258 template<>
convertToText(ChannelCount channelCount)259 const char *convertToText<ChannelCount>(ChannelCount channelCount) {
260 
261     switch (channelCount) {
262         case ChannelCount::Unspecified:  return "Unspecified";
263         case ChannelCount::Mono:         return "Mono";
264         case ChannelCount::Stereo:       return "Stereo";
265         default:                         return "Unrecognized channel count";
266     }
267 }
268 
getPropertyString(const char * name)269 std::string getPropertyString(const char * name) {
270     std::string result;
271 #ifdef __ANDROID__
272     char valueText[PROP_VALUE_MAX] = {0};
273     if (__system_property_get(name, valueText) != 0) {
274         result = valueText;
275     }
276 #else
277     (void) name;
278 #endif
279     return result;
280 }
281 
getPropertyInteger(const char * name,int defaultValue)282 int getPropertyInteger(const char * name, int defaultValue) {
283     int result = defaultValue;
284 #ifdef __ANDROID__
285     char valueText[PROP_VALUE_MAX] = {0};
286     if (__system_property_get(name, valueText) != 0) {
287         result = atoi(valueText);
288     }
289 #else
290     (void) name;
291 #endif
292     return result;
293 }
294 
getSdkVersion()295 int getSdkVersion() {
296     static int sCachedSdkVersion = -1;
297 #ifdef __ANDROID__
298     if (sCachedSdkVersion == -1) {
299         sCachedSdkVersion = getPropertyInteger("ro.build.version.sdk", -1);
300     }
301 #endif
302     return sCachedSdkVersion;
303 }
304 
305 }// namespace oboe
306