OLD | NEW |
| (Empty) |
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 "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 return samples_10ms_; | |
141 } | |
142 | |
143 void PCMFile::Write10MsData(AudioFrame& audio_frame) { | |
144 if (audio_frame.num_channels_ == 1) { | |
145 if (!save_stereo_) { | |
146 if (fwrite(audio_frame.data_, sizeof(uint16_t), | |
147 audio_frame.samples_per_channel_, pcm_file_) != | |
148 static_cast<size_t>(audio_frame.samples_per_channel_)) { | |
149 return; | |
150 } | |
151 } else { | |
152 int16_t* stereo_audio = new int16_t[2 * audio_frame.samples_per_channel_]; | |
153 for (size_t k = 0; k < audio_frame.samples_per_channel_; k++) { | |
154 stereo_audio[k << 1] = audio_frame.data_[k]; | |
155 stereo_audio[(k << 1) + 1] = audio_frame.data_[k]; | |
156 } | |
157 if (fwrite(stereo_audio, sizeof(int16_t), | |
158 2 * audio_frame.samples_per_channel_, pcm_file_) != | |
159 static_cast<size_t>(2 * audio_frame.samples_per_channel_)) { | |
160 return; | |
161 } | |
162 delete[] stereo_audio; | |
163 } | |
164 } else { | |
165 if (fwrite(audio_frame.data_, sizeof(int16_t), | |
166 audio_frame.num_channels_ * audio_frame.samples_per_channel_, | |
167 pcm_file_) != | |
168 static_cast<size_t>(audio_frame.num_channels_ * | |
169 audio_frame.samples_per_channel_)) { | |
170 return; | |
171 } | |
172 } | |
173 } | |
174 | |
175 void PCMFile::Write10MsData(int16_t* playout_buffer, size_t length_smpls) { | |
176 if (fwrite(playout_buffer, sizeof(uint16_t), length_smpls, pcm_file_) != | |
177 length_smpls) { | |
178 return; | |
179 } | |
180 } | |
181 | |
182 void PCMFile::Close() { | |
183 fclose(pcm_file_); | |
184 pcm_file_ = NULL; | |
185 } | |
186 | |
187 void PCMFile::Rewind() { | |
188 rewind(pcm_file_); | |
189 end_of_file_ = false; | |
190 } | |
191 | |
192 bool PCMFile::Rewinded() { | |
193 return rewinded_; | |
194 } | |
195 | |
196 void PCMFile::SaveStereo(bool is_stereo) { | |
197 save_stereo_ = is_stereo; | |
198 } | |
199 | |
200 void PCMFile::ReadStereo(bool is_stereo) { | |
201 read_stereo_ = is_stereo; | |
202 } | |
203 | |
204 } // namespace webrtc | |
OLD | NEW |