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