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