tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PCMFile.cc (6799B)


      1 /*
      2 *  Copyright (c) 2012 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_coding/test/PCMFile.h"
     12 
     13 #include <cctype>
     14 #include <cstdint>
     15 #include <cstdio>
     16 #include <cstdlib>
     17 #include <cstring>
     18 #include <string>
     19 
     20 #include "absl/strings/string_view.h"
     21 #include "api/audio/audio_frame.h"
     22 #include "rtc_base/checks.h"
     23 #include "test/gtest.h"
     24 
     25 namespace webrtc {
     26 
     27 #define MAX_FILE_NAME_LENGTH_BYTE 500
     28 
     29 PCMFile::PCMFile()
     30    : pcm_file_(nullptr),
     31      samples_10ms_(160),
     32      frequency_(16000),
     33      end_of_file_(false),
     34      auto_rewind_(false),
     35      rewinded_(false),
     36      read_stereo_(false),
     37      save_stereo_(false) {
     38  timestamp_ =
     39      (((uint32_t)rand() & 0x0000FFFF) << 16) | ((uint32_t)rand() & 0x0000FFFF);
     40 }
     41 
     42 PCMFile::PCMFile(uint32_t timestamp)
     43    : pcm_file_(nullptr),
     44      samples_10ms_(160),
     45      frequency_(16000),
     46      end_of_file_(false),
     47      auto_rewind_(false),
     48      rewinded_(false),
     49      read_stereo_(false),
     50      save_stereo_(false) {
     51  timestamp_ = timestamp;
     52 }
     53 
     54 PCMFile::~PCMFile() {
     55  if (pcm_file_) {
     56    fclose(pcm_file_);
     57  }
     58 }
     59 
     60 int16_t PCMFile::ChooseFile(std::string* file_name,
     61                            int16_t max_len,
     62                            uint16_t* frequency_hz) {
     63  char tmp_name[MAX_FILE_NAME_LENGTH_BYTE];
     64 
     65  EXPECT_TRUE(fgets(tmp_name, MAX_FILE_NAME_LENGTH_BYTE, stdin) != nullptr);
     66  tmp_name[MAX_FILE_NAME_LENGTH_BYTE - 1] = '\0';
     67  int16_t n = 0;
     68 
     69  // Removing trailing spaces.
     70  while ((isspace(static_cast<unsigned char>(tmp_name[n])) ||
     71          iscntrl(static_cast<unsigned char>(tmp_name[n]))) &&
     72         (static_cast<unsigned char>(tmp_name[n]) != 0) &&
     73         (n < MAX_FILE_NAME_LENGTH_BYTE)) {
     74    n++;
     75  }
     76  if (n > 0) {
     77    memmove(tmp_name, &tmp_name[n], MAX_FILE_NAME_LENGTH_BYTE - n);
     78  }
     79 
     80  // Removing trailing spaces.
     81  n = (int16_t)(strlen(tmp_name) - 1);
     82  if (n >= 0) {
     83    while ((isspace(static_cast<unsigned char>(tmp_name[n])) ||
     84            iscntrl(static_cast<unsigned char>(tmp_name[n]))) &&
     85           (n >= 0)) {
     86      n--;
     87    }
     88  }
     89  if (n >= 0) {
     90    tmp_name[n + 1] = '\0';
     91  }
     92 
     93  int16_t len = (int16_t)strlen(tmp_name);
     94  if (len > max_len) {
     95    return -1;
     96  }
     97  if (len > 0) {
     98    std::string tmp_string(tmp_name, len + 1);
     99    *file_name = tmp_string;
    100  }
    101  printf("Enter the sampling frequency (in Hz) of the above file [%u]: ",
    102         *frequency_hz);
    103  EXPECT_TRUE(fgets(tmp_name, 10, stdin) != nullptr);
    104  uint16_t tmp_frequency = (uint16_t)atoi(tmp_name);
    105  if (tmp_frequency > 0) {
    106    *frequency_hz = tmp_frequency;
    107  }
    108  return 0;
    109 }
    110 
    111 void PCMFile::Open(absl::string_view file_name,
    112                   uint16_t frequency,
    113                   absl::string_view mode,
    114                   bool auto_rewind) {
    115  if ((pcm_file_ = fopen(std::string(file_name).c_str(),
    116                         std::string(mode).c_str())) == nullptr) {
    117    printf("Cannot open file %s.\n", std::string(file_name).c_str());
    118    ADD_FAILURE() << "Unable to read file";
    119  }
    120  frequency_ = frequency;
    121  samples_10ms_ = (uint16_t)(frequency_ / 100);
    122  auto_rewind_ = auto_rewind;
    123  end_of_file_ = false;
    124  rewinded_ = false;
    125 }
    126 
    127 int32_t PCMFile::SamplingFrequency() const {
    128  return frequency_;
    129 }
    130 
    131 uint16_t PCMFile::PayloadLength10Ms() const {
    132  return samples_10ms_;
    133 }
    134 
    135 int32_t PCMFile::Read10MsData(AudioFrame& audio_frame) {
    136  uint16_t channels = 1;
    137  if (read_stereo_) {
    138    channels = 2;
    139  }
    140 
    141  int32_t payload_size =
    142      (int32_t)fread(audio_frame.mutable_data(), sizeof(uint16_t),
    143                     samples_10ms_ * channels, pcm_file_);
    144  if (payload_size < samples_10ms_ * channels) {
    145    int16_t* frame_data = audio_frame.mutable_data();
    146    for (int k = payload_size; k < samples_10ms_ * channels; k++) {
    147      frame_data[k] = 0;
    148    }
    149    if (auto_rewind_) {
    150      rewind(pcm_file_);
    151      rewinded_ = true;
    152    } else {
    153      end_of_file_ = true;
    154    }
    155  }
    156  audio_frame.samples_per_channel_ = samples_10ms_;
    157  audio_frame.sample_rate_hz_ = frequency_;
    158  audio_frame.num_channels_ = channels;
    159  audio_frame.timestamp_ = timestamp_;
    160  timestamp_ += samples_10ms_;
    161  ++blocks_read_;
    162  if (num_10ms_blocks_to_read_ && blocks_read_ >= *num_10ms_blocks_to_read_)
    163    end_of_file_ = true;
    164  return samples_10ms_;
    165 }
    166 
    167 void PCMFile::Write10MsData(const AudioFrame& audio_frame) {
    168  if (audio_frame.num_channels_ == 1) {
    169    if (!save_stereo_) {
    170      if (fwrite(audio_frame.data(), sizeof(uint16_t),
    171                 audio_frame.samples_per_channel_, pcm_file_) !=
    172          static_cast<size_t>(audio_frame.samples_per_channel_)) {
    173        return;
    174      }
    175    } else {
    176      const int16_t* frame_data = audio_frame.data();
    177      int16_t* stereo_audio = new int16_t[2 * audio_frame.samples_per_channel_];
    178      for (size_t k = 0; k < audio_frame.samples_per_channel_; k++) {
    179        stereo_audio[k << 1] = frame_data[k];
    180        stereo_audio[(k << 1) + 1] = frame_data[k];
    181      }
    182      if (fwrite(stereo_audio, sizeof(int16_t),
    183                 2 * audio_frame.samples_per_channel_, pcm_file_) !=
    184          static_cast<size_t>(2 * audio_frame.samples_per_channel_)) {
    185        return;
    186      }
    187      delete[] stereo_audio;
    188    }
    189  } else {
    190    if (fwrite(audio_frame.data(), sizeof(int16_t),
    191               audio_frame.num_channels_ * audio_frame.samples_per_channel_,
    192               pcm_file_) !=
    193        static_cast<size_t>(audio_frame.num_channels_ *
    194                            audio_frame.samples_per_channel_)) {
    195      return;
    196    }
    197  }
    198 }
    199 
    200 void PCMFile::Write10MsData(const int16_t* playout_buffer,
    201                            size_t length_smpls) {
    202  if (fwrite(playout_buffer, sizeof(uint16_t), length_smpls, pcm_file_) !=
    203      length_smpls) {
    204    return;
    205  }
    206 }
    207 
    208 void PCMFile::Close() {
    209  fclose(pcm_file_);
    210  pcm_file_ = nullptr;
    211  blocks_read_ = 0;
    212 }
    213 
    214 void PCMFile::FastForward(int num_10ms_blocks) {
    215  const int channels = read_stereo_ ? 2 : 1;
    216  long num_bytes_to_move =
    217      num_10ms_blocks * sizeof(int16_t) * samples_10ms_ * channels;
    218  int error = fseek(pcm_file_, num_bytes_to_move, SEEK_CUR);
    219  RTC_DCHECK_EQ(error, 0);
    220 }
    221 
    222 void PCMFile::Rewind() {
    223  rewind(pcm_file_);
    224  end_of_file_ = false;
    225  blocks_read_ = 0;
    226 }
    227 
    228 bool PCMFile::Rewinded() {
    229  return rewinded_;
    230 }
    231 
    232 void PCMFile::SaveStereo(bool is_stereo) {
    233  save_stereo_ = is_stereo;
    234 }
    235 
    236 void PCMFile::ReadStereo(bool is_stereo) {
    237  read_stereo_ = is_stereo;
    238 }
    239 
    240 void PCMFile::SetNum10MsBlocksToRead(int value) {
    241  num_10ms_blocks_to_read_ = value;
    242 }
    243 
    244 }  // namespace webrtc