Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: voice_engine/file_player.cc

Issue 3013033002: Remove VoEFile (Closed)
Patch Set: rebase Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « voice_engine/file_player.h ('k') | voice_engine/file_player_unittests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "voice_engine/file_player.h"
12
13 #include "common_audio/resampler/include/resampler.h"
14 #include "common_types.h" // NOLINT(build/include)
15 #include "modules/media_file/media_file.h"
16 #include "modules/media_file/media_file_defines.h"
17 #include "rtc_base/logging.h"
18 #include "typedefs.h" // NOLINT(build/include)
19 #include "voice_engine/coder.h"
20
21 namespace webrtc {
22
23 namespace {
24
25 class FilePlayerImpl : public FilePlayer {
26 public:
27 FilePlayerImpl(uint32_t instanceID, FileFormats fileFormat);
28 ~FilePlayerImpl() override;
29
30 int Get10msAudioFromFile(int16_t* outBuffer,
31 size_t* lengthInSamples,
32 int frequencyInHz) override;
33 int32_t RegisterModuleFileCallback(FileCallback* callback) override;
34 int32_t StartPlayingFile(const char* fileName,
35 bool loop,
36 uint32_t startPosition,
37 float volumeScaling,
38 uint32_t notification,
39 uint32_t stopPosition,
40 const CodecInst* codecInst) override;
41 int32_t StartPlayingFile(InStream* sourceStream,
42 uint32_t startPosition,
43 float volumeScaling,
44 uint32_t notification,
45 uint32_t stopPosition,
46 const CodecInst* codecInst) override;
47 int32_t StopPlayingFile() override;
48 bool IsPlayingFile() const override;
49 int32_t GetPlayoutPosition(uint32_t* durationMs) override;
50 int32_t AudioCodec(CodecInst* audioCodec) const override;
51 int32_t Frequency() const override;
52 int32_t SetAudioScaling(float scaleFactor) override;
53
54 private:
55 int32_t SetUpAudioDecoder();
56
57 const FileFormats _fileFormat;
58 MediaFile& _fileModule;
59
60 uint32_t _decodedLengthInMS;
61
62 AudioCoder _audioDecoder;
63
64 CodecInst _codec;
65 int32_t _numberOf10MsPerFrame;
66 int32_t _numberOf10MsInDecoder;
67
68 Resampler _resampler;
69 float _scaling;
70 };
71
72 FilePlayerImpl::FilePlayerImpl(const uint32_t instanceID,
73 const FileFormats fileFormat)
74 : _fileFormat(fileFormat),
75 _fileModule(*MediaFile::CreateMediaFile(instanceID)),
76 _decodedLengthInMS(0),
77 _audioDecoder(instanceID),
78 _codec(),
79 _numberOf10MsPerFrame(0),
80 _numberOf10MsInDecoder(0),
81 _resampler(),
82 _scaling(1.0) {
83 _codec.plfreq = 0;
84 }
85
86 FilePlayerImpl::~FilePlayerImpl() {
87 MediaFile::DestroyMediaFile(&_fileModule);
88 }
89
90 int32_t FilePlayerImpl::Frequency() const {
91 if (_codec.plfreq == 0) {
92 return -1;
93 }
94 // Make sure that sample rate is 8,16 or 32 kHz. E.g. WAVE files may have
95 // other sampling rates.
96 if (_codec.plfreq == 11000) {
97 return 16000;
98 } else if (_codec.plfreq == 22000) {
99 return 32000;
100 } else if (_codec.plfreq == 44000) {
101 return 32000;
102 } else if (_codec.plfreq == 48000) {
103 return 48000;
104 } else {
105 return _codec.plfreq;
106 }
107 }
108
109 int32_t FilePlayerImpl::AudioCodec(CodecInst* audioCodec) const {
110 *audioCodec = _codec;
111 return 0;
112 }
113
114 int32_t FilePlayerImpl::Get10msAudioFromFile(int16_t* outBuffer,
115 size_t* lengthInSamples,
116 int frequencyInHz) {
117 if (_codec.plfreq == 0) {
118 LOG(LS_WARNING) << "Get10msAudioFromFile() playing not started!"
119 << " codec freq = " << _codec.plfreq
120 << ", wanted freq = " << frequencyInHz;
121 return -1;
122 }
123
124 AudioFrame unresampledAudioFrame;
125 if (STR_CASE_CMP(_codec.plname, "L16") == 0) {
126 unresampledAudioFrame.sample_rate_hz_ = _codec.plfreq;
127
128 // L16 is un-encoded data. Just pull 10 ms.
129 size_t lengthInBytes = AudioFrame::kMaxDataSizeBytes;
130 if (_fileModule.PlayoutAudioData(
131 reinterpret_cast<int8_t*>(unresampledAudioFrame.mutable_data()),
132 lengthInBytes) == -1) {
133 // End of file reached.
134 return -1;
135 }
136 if (lengthInBytes == 0) {
137 *lengthInSamples = 0;
138 return 0;
139 }
140 // One sample is two bytes.
141 unresampledAudioFrame.samples_per_channel_ = lengthInBytes >> 1;
142
143 } else {
144 // Decode will generate 10 ms of audio data. PlayoutAudioData(..)
145 // expects a full frame. If the frame size is larger than 10 ms,
146 // PlayoutAudioData(..) data should be called proportionally less often.
147 int16_t encodedBuffer[MAX_AUDIO_BUFFER_IN_SAMPLES];
148 size_t encodedLengthInBytes = 0;
149 if (++_numberOf10MsInDecoder >= _numberOf10MsPerFrame) {
150 _numberOf10MsInDecoder = 0;
151 size_t bytesFromFile = sizeof(encodedBuffer);
152 if (_fileModule.PlayoutAudioData(reinterpret_cast<int8_t*>(encodedBuffer),
153 bytesFromFile) == -1) {
154 // End of file reached.
155 return -1;
156 }
157 encodedLengthInBytes = bytesFromFile;
158 }
159 if (_audioDecoder.Decode(&unresampledAudioFrame, frequencyInHz,
160 reinterpret_cast<int8_t*>(encodedBuffer),
161 encodedLengthInBytes) == -1) {
162 return -1;
163 }
164 }
165
166 size_t outLen = 0;
167 if (_resampler.ResetIfNeeded(unresampledAudioFrame.sample_rate_hz_,
168 frequencyInHz, 1)) {
169 LOG(LS_WARNING) << "Get10msAudioFromFile() unexpected codec.";
170
171 // New sampling frequency. Update state.
172 outLen = static_cast<size_t>(frequencyInHz / 100);
173 memset(outBuffer, 0, outLen * sizeof(int16_t));
174 return 0;
175 }
176 _resampler.Push(unresampledAudioFrame.data(),
177 unresampledAudioFrame.samples_per_channel_, outBuffer,
178 MAX_AUDIO_BUFFER_IN_SAMPLES, outLen);
179
180 *lengthInSamples = outLen;
181
182 if (_scaling != 1.0) {
183 for (size_t i = 0; i < outLen; i++) {
184 outBuffer[i] = (int16_t)(outBuffer[i] * _scaling);
185 }
186 }
187 _decodedLengthInMS += 10;
188 return 0;
189 }
190
191 int32_t FilePlayerImpl::RegisterModuleFileCallback(FileCallback* callback) {
192 return _fileModule.SetModuleFileCallback(callback);
193 }
194
195 int32_t FilePlayerImpl::SetAudioScaling(float scaleFactor) {
196 if ((scaleFactor >= 0) && (scaleFactor <= 2.0)) {
197 _scaling = scaleFactor;
198 return 0;
199 }
200 LOG(LS_WARNING) << "SetAudioScaling() non-allowed scale factor.";
201 return -1;
202 }
203
204 int32_t FilePlayerImpl::StartPlayingFile(const char* fileName,
205 bool loop,
206 uint32_t startPosition,
207 float volumeScaling,
208 uint32_t notification,
209 uint32_t stopPosition,
210 const CodecInst* codecInst) {
211 if (_fileFormat == kFileFormatPcm16kHzFile ||
212 _fileFormat == kFileFormatPcm8kHzFile ||
213 _fileFormat == kFileFormatPcm32kHzFile) {
214 CodecInst codecInstL16;
215 strncpy(codecInstL16.plname, "L16", 32);
216 codecInstL16.pltype = 93;
217 codecInstL16.channels = 1;
218
219 if (_fileFormat == kFileFormatPcm8kHzFile) {
220 codecInstL16.rate = 128000;
221 codecInstL16.plfreq = 8000;
222 codecInstL16.pacsize = 80;
223 } else if (_fileFormat == kFileFormatPcm16kHzFile) {
224 codecInstL16.rate = 256000;
225 codecInstL16.plfreq = 16000;
226 codecInstL16.pacsize = 160;
227 } else if (_fileFormat == kFileFormatPcm32kHzFile) {
228 codecInstL16.rate = 512000;
229 codecInstL16.plfreq = 32000;
230 codecInstL16.pacsize = 320;
231 } else if (_fileFormat == kFileFormatPcm48kHzFile) {
232 codecInstL16.rate = 768000;
233 codecInstL16.plfreq = 48000;
234 codecInstL16.pacsize = 480;
235 } else {
236 LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
237 << "supported for PCM format.";
238 return -1;
239 }
240
241 if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
242 _fileFormat, &codecInstL16,
243 startPosition, stopPosition) == -1) {
244 LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
245 << "pcm file " << fileName;
246 return -1;
247 }
248 SetAudioScaling(volumeScaling);
249 } else if (_fileFormat == kFileFormatPreencodedFile) {
250 if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
251 _fileFormat, codecInst) == -1) {
252 LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
253 << "pre-encoded file " << fileName;
254 return -1;
255 }
256 } else {
257 CodecInst* no_inst = NULL;
258 if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
259 _fileFormat, no_inst, startPosition,
260 stopPosition) == -1) {
261 LOG(LS_WARNING) << "StartPlayingFile() failed to initialize file "
262 << fileName;
263 return -1;
264 }
265 SetAudioScaling(volumeScaling);
266 }
267 if (SetUpAudioDecoder() == -1) {
268 StopPlayingFile();
269 return -1;
270 }
271 return 0;
272 }
273
274 int32_t FilePlayerImpl::StartPlayingFile(InStream* sourceStream,
275 uint32_t startPosition,
276 float volumeScaling,
277 uint32_t notification,
278 uint32_t stopPosition,
279 const CodecInst* codecInst) {
280 if (_fileFormat == kFileFormatPcm16kHzFile ||
281 _fileFormat == kFileFormatPcm32kHzFile ||
282 _fileFormat == kFileFormatPcm8kHzFile ||
283 _fileFormat == kFileFormatPcm48kHzFile) {
284 CodecInst codecInstL16;
285 strncpy(codecInstL16.plname, "L16", 32);
286 codecInstL16.pltype = 93;
287 codecInstL16.channels = 1;
288
289 if (_fileFormat == kFileFormatPcm8kHzFile) {
290 codecInstL16.rate = 128000;
291 codecInstL16.plfreq = 8000;
292 codecInstL16.pacsize = 80;
293 } else if (_fileFormat == kFileFormatPcm16kHzFile) {
294 codecInstL16.rate = 256000;
295 codecInstL16.plfreq = 16000;
296 codecInstL16.pacsize = 160;
297 } else if (_fileFormat == kFileFormatPcm32kHzFile) {
298 codecInstL16.rate = 512000;
299 codecInstL16.plfreq = 32000;
300 codecInstL16.pacsize = 320;
301 } else if (_fileFormat == kFileFormatPcm48kHzFile) {
302 codecInstL16.rate = 768000;
303 codecInstL16.plfreq = 48000;
304 codecInstL16.pacsize = 480;
305 } else {
306 LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
307 << "supported for PCM format.";
308 return -1;
309 }
310 if (_fileModule.StartPlayingAudioStream(
311 *sourceStream, notification, _fileFormat, &codecInstL16,
312 startPosition, stopPosition) == -1) {
313 LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
314 << "playout.";
315 return -1;
316 }
317
318 } else if (_fileFormat == kFileFormatPreencodedFile) {
319 if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
320 _fileFormat, codecInst) == -1) {
321 LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
322 << "playout.";
323 return -1;
324 }
325 } else {
326 CodecInst* no_inst = NULL;
327 if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
328 _fileFormat, no_inst, startPosition,
329 stopPosition) == -1) {
330 LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
331 << "playout.";
332 return -1;
333 }
334 }
335 SetAudioScaling(volumeScaling);
336
337 if (SetUpAudioDecoder() == -1) {
338 StopPlayingFile();
339 return -1;
340 }
341 return 0;
342 }
343
344 int32_t FilePlayerImpl::StopPlayingFile() {
345 memset(&_codec, 0, sizeof(CodecInst));
346 _numberOf10MsPerFrame = 0;
347 _numberOf10MsInDecoder = 0;
348 return _fileModule.StopPlaying();
349 }
350
351 bool FilePlayerImpl::IsPlayingFile() const {
352 return _fileModule.IsPlaying();
353 }
354
355 int32_t FilePlayerImpl::GetPlayoutPosition(uint32_t* durationMs) {
356 return _fileModule.PlayoutPositionMs(*durationMs);
357 }
358
359 int32_t FilePlayerImpl::SetUpAudioDecoder() {
360 if ((_fileModule.codec_info(_codec) == -1)) {
361 LOG(LS_WARNING) << "Failed to retrieve codec info of file data.";
362 return -1;
363 }
364 if (STR_CASE_CMP(_codec.plname, "L16") != 0 &&
365 _audioDecoder.SetDecodeCodec(_codec) == -1) {
366 LOG(LS_WARNING) << "SetUpAudioDecoder() codec " << _codec.plname
367 << " not supported.";
368 return -1;
369 }
370 _numberOf10MsPerFrame = _codec.pacsize / (_codec.plfreq / 100);
371 _numberOf10MsInDecoder = 0;
372 return 0;
373 }
374
375 } // namespace
376
377 std::unique_ptr<FilePlayer> FilePlayer::CreateFilePlayer(
378 uint32_t instanceID,
379 FileFormats fileFormat) {
380 switch (fileFormat) {
381 case kFileFormatWavFile:
382 case kFileFormatCompressedFile:
383 case kFileFormatPreencodedFile:
384 case kFileFormatPcm16kHzFile:
385 case kFileFormatPcm8kHzFile:
386 case kFileFormatPcm32kHzFile:
387 case kFileFormatPcm48kHzFile:
388 // audio formats
389 return std::unique_ptr<FilePlayer>(
390 new FilePlayerImpl(instanceID, fileFormat));
391 default:
392 assert(false);
393 return nullptr;
394 }
395 }
396
397 } // namespace webrtc
OLDNEW
« no previous file with comments | « voice_engine/file_player.h ('k') | voice_engine/file_player_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698