1 /*
2  * Copyright (C) 2015 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 package com.android.cts.verifier.audio.wavelib;
18 
19 import android.util.Log;
20 
21 public class VectorAverage {
22     private static final String LOGTAG = "VectorAverage";
23     private static final int mVersion = 0;
24     private double[] mData;
25     private int mValueCount = 0;
26 
27     public static final int CAPTURE_TYPE_AVERAGE = 0;
28     public static final int CAPTURE_TYPE_MAX     = 1;
29     public static final int CAPTURE_TYPE_MIN     = 2;
30 
31     private int mCaptureType = CAPTURE_TYPE_AVERAGE;
32 
setData(double[] data, boolean replace)33     public void setData(double[] data, boolean replace) {
34         int size = data.length;
35         if (mData == null || mData.length != size) {
36             mData = new double[size];
37             mValueCount = 0;
38         }
39         if (replace || mValueCount == 0) {
40             System.arraycopy(data, 0, mData, 0, size);
41             mValueCount = 1;
42         } else {
43             switch(mCaptureType) {
44                 default:
45                 case CAPTURE_TYPE_AVERAGE: {
46                     for (int i = 0; i < size; i++) {
47                         mData[i] += data[i];
48                     }
49                     mValueCount++;
50                 }
51                 break;
52                 case CAPTURE_TYPE_MAX: {
53                     for (int i = 0; i < size; i++) {
54                         if (data[i] > mData[i]) {
55                             mData[i] = data[i];
56                         }
57                     }
58                     mValueCount = 1;
59                 }
60                 break;
61                 case CAPTURE_TYPE_MIN: {
62                     for (int i = 0; i < size; i++) {
63                         if (data[i] < mData[i]) {
64                             mData[i] = data[i];
65                         }
66                     }
67                     mValueCount = 1;
68                 }
69                 break;
70             }
71         }
72     }
73 
getData(double[] data, boolean raw)74     public int getData(double[] data, boolean raw) {
75         int nCount = 0;
76         if (mData != null && mData.length <= data.length) {
77             nCount = mData.length;
78             if (mValueCount == 0) {
79                 for (int i = 0; i < nCount; i++) {
80                     data[i] = 0;
81                 }
82             } else if (!raw && mValueCount > 1) {
83                 for (int i = 0; i < nCount; i++) {
84                     data[i] = mData[i] / mValueCount;
85                 }
86             } else {
87                 for (int i = 0; i < nCount; i++) {
88                     data[i] = mData[i];
89                 }
90             }
91         }
92         return nCount;
93     }
94 
getCount()95     public int getCount() {
96         return mValueCount;
97     }
98 
getSize()99     public int getSize() {
100         if (mData != null) {
101             return mData.length;
102         }
103         return 0;
104     }
105 
reset()106     public void reset() {
107         mValueCount = 0;
108     }
109 
setCaptureType(int type)110     public void setCaptureType(int type) {
111         switch(type) {
112             case CAPTURE_TYPE_AVERAGE:
113             case CAPTURE_TYPE_MAX:
114             case CAPTURE_TYPE_MIN:
115                 mCaptureType = type;
116                 break;
117             default:
118                 mCaptureType = CAPTURE_TYPE_AVERAGE;
119         }
120     }
121 
getCaptureType()122     public int getCaptureType() {
123         return mCaptureType;
124     }
125 
126     private final String SERIALIZED_VERSION = "VECTOR_AVERAGE_VERSION";
127     private final String SERIALIZED_COUNT = "COUNT";
128 
toString()129     public String toString() {
130         StringBuffer sb = new StringBuffer();
131 
132         //version
133         sb.append(SERIALIZED_VERSION +"="+ mVersion +"\n");
134 
135         double[] data = new double[getSize()];
136         getData(data,false);
137 
138         //element count
139         int nCount = data.length;
140         sb.append(SERIALIZED_COUNT + "=" + nCount +"\n");
141 
142         for (int i = 0; i < nCount; i++) {
143             sb.append(String.format("%f\n",data[i]));
144         }
145 
146         return sb.toString();
147     }
148 
initFromString(String string)149     public boolean initFromString(String string) {
150         boolean success = false;
151 
152         String[] lines = string.split(System.getProperty("line.separator"));
153 
154         int lineCount = lines.length;
155         if (lineCount > 3) {
156             int nVersion = -1;
157             int nCount = -1;
158             int nIndex = 0;
159 
160             //search for version:
161             while (nIndex < lineCount) {
162                 String[] separated = lines[nIndex].split("=");
163                 nIndex++;
164                 if (separated.length > 1 && separated[0].equalsIgnoreCase(SERIALIZED_VERSION)) {
165                     nVersion = Integer.parseInt(separated[1]);
166                     break;
167                 }
168             }
169 
170             if (nVersion >= 0) {
171                 //get count
172 
173                 while (nIndex < lineCount) {
174                     String[] separated = lines[nIndex].split("=");
175                     nIndex++;
176                     if (separated.length > 1 && separated[0].equalsIgnoreCase(SERIALIZED_COUNT)) {
177                         nCount = Integer.parseInt(separated[1]);
178                         break;
179                     }
180                 }
181 
182                 if (nCount > 0 && nCount <= lineCount-2 && nCount < 20000) { //foolproof
183                     //now add nCount to the vector.
184                     double[] data = new double[nCount];
185                     int dataIndex=0;
186 
187                     while (nIndex < lineCount) {
188                         double value = Double.parseDouble(lines[nIndex]);
189                         data[dataIndex++] = value;
190                         nIndex++;
191                     }
192                     setData(data, true);
193                     success = true;
194                 }
195             }
196         }
197 
198         return success;
199     }
200 
log(String msg)201     private static void log(String msg) {
202         Log.v(LOGTAG, msg);
203     }
204 }
205