Home | History | Annotate | Download | only in transient
      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 "webrtc/modules/audio_processing/transient/file_utils.h"
     12 
     13 #include "webrtc/base/scoped_ptr.h"
     14 #include "webrtc/system_wrappers/include/file_wrapper.h"
     15 #include "webrtc/typedefs.h"
     16 
     17 namespace webrtc {
     18 
     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 
     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 
     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 
     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 
     79 size_t ReadInt16BufferFromFile(FileWrapper* file,
     80                                size_t length,
     81                                int16_t* buffer) {
     82   if (!file || !file->Open() || !buffer || length <= 0) {
     83     return 0;
     84   }
     85 
     86   rtc::scoped_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 
    105 size_t ReadInt16FromFileToFloatBuffer(FileWrapper* file,
    106                                       size_t length,
    107                                       float* buffer) {
    108   if (!file || !file->Open() || !buffer || length <= 0) {
    109     return 0;
    110   }
    111 
    112   rtc::scoped_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 
    123 size_t ReadInt16FromFileToDoubleBuffer(FileWrapper* file,
    124                                        size_t length,
    125                                        double* buffer) {
    126   if (!file || !file->Open() || !buffer || length <= 0) {
    127     return 0;
    128   }
    129 
    130   rtc::scoped_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 
    141 size_t ReadFloatBufferFromFile(FileWrapper* file,
    142                                size_t length,
    143                                float* buffer) {
    144   if (!file || !file->Open() || !buffer || length <= 0) {
    145     return 0;
    146   }
    147 
    148   rtc::scoped_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 
    164 size_t ReadDoubleBufferFromFile(FileWrapper* file,
    165                                 size_t length,
    166                                 double* buffer) {
    167   if (!file || !file->Open() || !buffer || length <= 0) {
    168     return 0;
    169   }
    170 
    171   rtc::scoped_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 
    187 size_t WriteInt16BufferToFile(FileWrapper* file,
    188                               size_t length,
    189                               const int16_t* buffer) {
    190   if (!file || !file->Open() || !buffer || length <= 0) {
    191     return 0;
    192   }
    193 
    194   rtc::scoped_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 
    211 size_t WriteFloatBufferToFile(FileWrapper* file,
    212                               size_t length,
    213                               const float* buffer) {
    214   if (!file || !file->Open() || !buffer || length <= 0) {
    215     return 0;
    216   }
    217 
    218   rtc::scoped_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 
    234 size_t WriteDoubleBufferToFile(FileWrapper* file,
    235                                size_t length,
    236                                const double* buffer) {
    237   if (!file || !file->Open() || !buffer || length <= 0) {
    238     return 0;
    239   }
    240 
    241   rtc::scoped_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