1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/transient/file_utils.h"
12 
13 #include <memory>
14 
15 #include "rtc_base/system/file_wrapper.h"
16 
17 namespace webrtc {
18 
ConvertByteArrayToFloat(const uint8_t bytes[4],float * out)19 int ConvertByteArrayToFloat(const uint8_t bytes[4], float* out) {
20   if (!bytes || !out) {
21     return -1;
22   }
23 
24   uint32_t binary_value = 0;
25   for (int i = 3; i >= 0; --i) {
26     binary_value <<= 8;
27     binary_value += bytes[i];
28   }
29 
30   *out = bit_cast<float>(binary_value);
31 
32   return 0;
33 }
34 
ConvertByteArrayToDouble(const uint8_t bytes[8],double * out)35 int ConvertByteArrayToDouble(const uint8_t bytes[8], double* out) {
36   if (!bytes || !out) {
37     return -1;
38   }
39 
40   uint64_t binary_value = 0;
41   for (int i = 7; i >= 0; --i) {
42     binary_value <<= 8;
43     binary_value += bytes[i];
44   }
45 
46   *out = bit_cast<double>(binary_value);
47 
48   return 0;
49 }
50 
ConvertFloatToByteArray(float value,uint8_t out_bytes[4])51 int ConvertFloatToByteArray(float value, uint8_t out_bytes[4]) {
52   if (!out_bytes) {
53     return -1;
54   }
55 
56   uint32_t binary_value = bit_cast<uint32_t>(value);
57   for (size_t i = 0; i < 4; ++i) {
58     out_bytes[i] = binary_value;
59     binary_value >>= 8;
60   }
61 
62   return 0;
63 }
64 
ConvertDoubleToByteArray(double value,uint8_t out_bytes[8])65 int ConvertDoubleToByteArray(double value, uint8_t out_bytes[8]) {
66   if (!out_bytes) {
67     return -1;
68   }
69 
70   uint64_t binary_value = bit_cast<uint64_t>(value);
71   for (size_t i = 0; i < 8; ++i) {
72     out_bytes[i] = binary_value;
73     binary_value >>= 8;
74   }
75 
76   return 0;
77 }
78 
ReadInt16BufferFromFile(FileWrapper * file,size_t length,int16_t * buffer)79 size_t ReadInt16BufferFromFile(FileWrapper* file,
80                                size_t length,
81                                int16_t* buffer) {
82   if (!file || !file->is_open() || !buffer || length <= 0) {
83     return 0;
84   }
85 
86   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[2]);
87 
88   size_t int16s_read = 0;
89 
90   while (int16s_read < length) {
91     size_t bytes_read = file->Read(byte_array.get(), 2);
92     if (bytes_read < 2) {
93       break;
94     }
95     int16_t value = byte_array[1];
96     value <<= 8;
97     value += byte_array[0];
98     buffer[int16s_read] = value;
99     ++int16s_read;
100   }
101 
102   return int16s_read;
103 }
104 
ReadInt16FromFileToFloatBuffer(FileWrapper * file,size_t length,float * buffer)105 size_t ReadInt16FromFileToFloatBuffer(FileWrapper* file,
106                                       size_t length,
107                                       float* buffer) {
108   if (!file || !file->is_open() || !buffer || length <= 0) {
109     return 0;
110   }
111 
112   std::unique_ptr<int16_t[]> buffer16(new int16_t[length]);
113 
114   size_t int16s_read = ReadInt16BufferFromFile(file, length, buffer16.get());
115 
116   for (size_t i = 0; i < int16s_read; ++i) {
117     buffer[i] = buffer16[i];
118   }
119 
120   return int16s_read;
121 }
122 
ReadInt16FromFileToDoubleBuffer(FileWrapper * file,size_t length,double * buffer)123 size_t ReadInt16FromFileToDoubleBuffer(FileWrapper* file,
124                                        size_t length,
125                                        double* buffer) {
126   if (!file || !file->is_open() || !buffer || length <= 0) {
127     return 0;
128   }
129 
130   std::unique_ptr<int16_t[]> buffer16(new int16_t[length]);
131 
132   size_t int16s_read = ReadInt16BufferFromFile(file, length, buffer16.get());
133 
134   for (size_t i = 0; i < int16s_read; ++i) {
135     buffer[i] = buffer16[i];
136   }
137 
138   return int16s_read;
139 }
140 
ReadFloatBufferFromFile(FileWrapper * file,size_t length,float * buffer)141 size_t ReadFloatBufferFromFile(FileWrapper* file,
142                                size_t length,
143                                float* buffer) {
144   if (!file || !file->is_open() || !buffer || length <= 0) {
145     return 0;
146   }
147 
148   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[4]);
149 
150   size_t floats_read = 0;
151 
152   while (floats_read < length) {
153     size_t bytes_read = file->Read(byte_array.get(), 4);
154     if (bytes_read < 4) {
155       break;
156     }
157     ConvertByteArrayToFloat(byte_array.get(), &buffer[floats_read]);
158     ++floats_read;
159   }
160 
161   return floats_read;
162 }
163 
ReadDoubleBufferFromFile(FileWrapper * file,size_t length,double * buffer)164 size_t ReadDoubleBufferFromFile(FileWrapper* file,
165                                 size_t length,
166                                 double* buffer) {
167   if (!file || !file->is_open() || !buffer || length <= 0) {
168     return 0;
169   }
170 
171   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[8]);
172 
173   size_t doubles_read = 0;
174 
175   while (doubles_read < length) {
176     size_t bytes_read = file->Read(byte_array.get(), 8);
177     if (bytes_read < 8) {
178       break;
179     }
180     ConvertByteArrayToDouble(byte_array.get(), &buffer[doubles_read]);
181     ++doubles_read;
182   }
183 
184   return doubles_read;
185 }
186 
WriteInt16BufferToFile(FileWrapper * file,size_t length,const int16_t * buffer)187 size_t WriteInt16BufferToFile(FileWrapper* file,
188                               size_t length,
189                               const int16_t* buffer) {
190   if (!file || !file->is_open() || !buffer || length <= 0) {
191     return 0;
192   }
193 
194   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[2]);
195 
196   size_t int16s_written = 0;
197 
198   for (int16s_written = 0; int16s_written < length; ++int16s_written) {
199     // Get byte representation.
200     byte_array[0] = buffer[int16s_written] & 0xFF;
201     byte_array[1] = (buffer[int16s_written] >> 8) & 0xFF;
202 
203     file->Write(byte_array.get(), 2);
204   }
205 
206   file->Flush();
207 
208   return int16s_written;
209 }
210 
WriteFloatBufferToFile(FileWrapper * file,size_t length,const float * buffer)211 size_t WriteFloatBufferToFile(FileWrapper* file,
212                               size_t length,
213                               const float* buffer) {
214   if (!file || !file->is_open() || !buffer || length <= 0) {
215     return 0;
216   }
217 
218   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[4]);
219 
220   size_t floats_written = 0;
221 
222   for (floats_written = 0; floats_written < length; ++floats_written) {
223     // Get byte representation.
224     ConvertFloatToByteArray(buffer[floats_written], byte_array.get());
225 
226     file->Write(byte_array.get(), 4);
227   }
228 
229   file->Flush();
230 
231   return floats_written;
232 }
233 
WriteDoubleBufferToFile(FileWrapper * file,size_t length,const double * buffer)234 size_t WriteDoubleBufferToFile(FileWrapper* file,
235                                size_t length,
236                                const double* buffer) {
237   if (!file || !file->is_open() || !buffer || length <= 0) {
238     return 0;
239   }
240 
241   std::unique_ptr<uint8_t[]> byte_array(new uint8_t[8]);
242 
243   size_t doubles_written = 0;
244 
245   for (doubles_written = 0; doubles_written < length; ++doubles_written) {
246     // Get byte representation.
247     ConvertDoubleToByteArray(buffer[doubles_written], byte_array.get());
248 
249     file->Write(byte_array.get(), 8);
250   }
251 
252   file->Flush();
253 
254   return doubles_written;
255 }
256 
257 }  // namespace webrtc
258