Line data Source code
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/voice_engine/voe_file_impl.h"
12 :
13 : #include "webrtc/system_wrappers/include/file_wrapper.h"
14 : #include "webrtc/system_wrappers/include/trace.h"
15 : #include "webrtc/voice_engine/channel.h"
16 : #include "webrtc/voice_engine/include/voe_errors.h"
17 : #include "webrtc/voice_engine/output_mixer.h"
18 : #include "webrtc/voice_engine/transmit_mixer.h"
19 : #include "webrtc/voice_engine/voice_engine_impl.h"
20 :
21 : namespace webrtc {
22 :
23 0 : VoEFile* VoEFile::GetInterface(VoiceEngine* voiceEngine) {
24 0 : if (NULL == voiceEngine) {
25 0 : return NULL;
26 : }
27 0 : VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
28 0 : s->AddRef();
29 0 : return s;
30 : }
31 :
32 0 : VoEFileImpl::VoEFileImpl(voe::SharedData* shared) : _shared(shared) {
33 : WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
34 : "VoEFileImpl::VoEFileImpl() - ctor");
35 0 : }
36 :
37 0 : VoEFileImpl::~VoEFileImpl() {
38 : WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
39 : "VoEFileImpl::~VoEFileImpl() - dtor");
40 0 : }
41 :
42 0 : int VoEFileImpl::StartPlayingFileLocally(int channel,
43 : const char fileNameUTF8[1024],
44 : bool loop,
45 : FileFormats format,
46 : float volumeScaling,
47 : int startPointMs,
48 : int stopPointMs) {
49 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
50 : "StartPlayingFileLocally(channel=%d, fileNameUTF8[]=%s, "
51 : "loop=%d, format=%d, volumeScaling=%5.3f, startPointMs=%d,"
52 : " stopPointMs=%d)",
53 : channel, fileNameUTF8, loop, format, volumeScaling, startPointMs,
54 : stopPointMs);
55 : static_assert(1024 == FileWrapper::kMaxFileNameSize, "");
56 0 : if (!_shared->statistics().Initialized()) {
57 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
58 0 : return -1;
59 : }
60 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
61 0 : voe::Channel* channelPtr = ch.channel();
62 0 : if (channelPtr == NULL) {
63 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
64 0 : "StartPlayingFileLocally() failed to locate channel");
65 0 : return -1;
66 : }
67 :
68 0 : return channelPtr->StartPlayingFileLocally(fileNameUTF8, loop, format,
69 : startPointMs, volumeScaling,
70 0 : stopPointMs, NULL);
71 : }
72 :
73 0 : int VoEFileImpl::StartPlayingFileLocally(int channel,
74 : InStream* stream,
75 : FileFormats format,
76 : float volumeScaling,
77 : int startPointMs,
78 : int stopPointMs) {
79 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
80 : "StartPlayingFileLocally(channel=%d, stream, format=%d, "
81 : "volumeScaling=%5.3f, startPointMs=%d, stopPointMs=%d)",
82 : channel, format, volumeScaling, startPointMs, stopPointMs);
83 :
84 0 : if (!_shared->statistics().Initialized()) {
85 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
86 0 : return -1;
87 : }
88 :
89 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
90 0 : voe::Channel* channelPtr = ch.channel();
91 0 : if (channelPtr == NULL) {
92 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
93 0 : "StartPlayingFileLocally() failed to locate channel");
94 0 : return -1;
95 : }
96 :
97 : return channelPtr->StartPlayingFileLocally(stream, format, startPointMs,
98 0 : volumeScaling, stopPointMs, NULL);
99 : }
100 :
101 0 : int VoEFileImpl::StopPlayingFileLocally(int channel) {
102 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
103 : "StopPlayingFileLocally()");
104 0 : if (!_shared->statistics().Initialized()) {
105 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
106 0 : return -1;
107 : }
108 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
109 0 : voe::Channel* channelPtr = ch.channel();
110 0 : if (channelPtr == NULL) {
111 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
112 0 : "StopPlayingFileLocally() failed to locate channel");
113 0 : return -1;
114 : }
115 0 : return channelPtr->StopPlayingFileLocally();
116 : }
117 :
118 0 : int VoEFileImpl::IsPlayingFileLocally(int channel) {
119 0 : if (!_shared->statistics().Initialized()) {
120 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
121 0 : return -1;
122 : }
123 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
124 0 : voe::Channel* channelPtr = ch.channel();
125 0 : if (channelPtr == NULL) {
126 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
127 0 : "StopPlayingFileLocally() failed to locate channel");
128 0 : return -1;
129 : }
130 0 : return channelPtr->IsPlayingFileLocally();
131 : }
132 :
133 0 : int VoEFileImpl::StartPlayingFileAsMicrophone(int channel,
134 : const char fileNameUTF8[1024],
135 : bool loop,
136 : bool mixWithMicrophone,
137 : FileFormats format,
138 : float volumeScaling) {
139 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
140 : "StartPlayingFileAsMicrophone(channel=%d, fileNameUTF8=%s, "
141 : "loop=%d, mixWithMicrophone=%d, format=%d, "
142 : "volumeScaling=%5.3f)",
143 : channel, fileNameUTF8, loop, mixWithMicrophone, format,
144 : volumeScaling);
145 : static_assert(1024 == FileWrapper::kMaxFileNameSize, "");
146 0 : if (!_shared->statistics().Initialized()) {
147 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
148 0 : return -1;
149 : }
150 :
151 0 : const uint32_t startPointMs(0);
152 0 : const uint32_t stopPointMs(0);
153 :
154 0 : if (channel == -1) {
155 0 : int res = _shared->transmit_mixer()->StartPlayingFileAsMicrophone(
156 : fileNameUTF8, loop, format, startPointMs, volumeScaling, stopPointMs,
157 0 : NULL);
158 0 : if (res) {
159 : WEBRTC_TRACE(
160 : kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
161 : "StartPlayingFileAsMicrophone() failed to start playing file");
162 0 : return (-1);
163 : } else {
164 0 : _shared->transmit_mixer()->SetMixWithMicStatus(mixWithMicrophone);
165 0 : return (0);
166 : }
167 : } else {
168 : // Add file after demultiplexing <=> affects one channel only
169 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
170 0 : voe::Channel* channelPtr = ch.channel();
171 0 : if (channelPtr == NULL) {
172 0 : _shared->SetLastError(
173 : VE_CHANNEL_NOT_VALID, kTraceError,
174 0 : "StartPlayingFileAsMicrophone() failed to locate channel");
175 0 : return -1;
176 : }
177 :
178 0 : int res = channelPtr->StartPlayingFileAsMicrophone(
179 : fileNameUTF8, loop, format, startPointMs, volumeScaling, stopPointMs,
180 0 : NULL);
181 0 : if (res) {
182 : WEBRTC_TRACE(
183 : kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
184 : "StartPlayingFileAsMicrophone() failed to start playing file");
185 0 : return -1;
186 : } else {
187 0 : channelPtr->SetMixWithMicStatus(mixWithMicrophone);
188 0 : return 0;
189 : }
190 : }
191 : }
192 :
193 0 : int VoEFileImpl::StartPlayingFileAsMicrophone(int channel,
194 : InStream* stream,
195 : bool mixWithMicrophone,
196 : FileFormats format,
197 : float volumeScaling) {
198 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
199 : "StartPlayingFileAsMicrophone(channel=%d, stream,"
200 : " mixWithMicrophone=%d, format=%d, volumeScaling=%5.3f)",
201 : channel, mixWithMicrophone, format, volumeScaling);
202 :
203 0 : if (!_shared->statistics().Initialized()) {
204 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
205 0 : return -1;
206 : }
207 :
208 0 : const uint32_t startPointMs(0);
209 0 : const uint32_t stopPointMs(0);
210 :
211 0 : if (channel == -1) {
212 0 : int res = _shared->transmit_mixer()->StartPlayingFileAsMicrophone(
213 0 : stream, format, startPointMs, volumeScaling, stopPointMs, NULL);
214 0 : if (res) {
215 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
216 : "StartPlayingFileAsMicrophone() failed to start "
217 : "playing stream");
218 0 : return (-1);
219 : } else {
220 0 : _shared->transmit_mixer()->SetMixWithMicStatus(mixWithMicrophone);
221 0 : return (0);
222 : }
223 : } else {
224 : // Add file after demultiplexing <=> affects one channel only
225 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
226 0 : voe::Channel* channelPtr = ch.channel();
227 0 : if (channelPtr == NULL) {
228 0 : _shared->SetLastError(
229 : VE_CHANNEL_NOT_VALID, kTraceError,
230 0 : "StartPlayingFileAsMicrophone() failed to locate channel");
231 0 : return -1;
232 : }
233 :
234 : int res = channelPtr->StartPlayingFileAsMicrophone(
235 0 : stream, format, startPointMs, volumeScaling, stopPointMs, NULL);
236 0 : if (res) {
237 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
238 : "StartPlayingFileAsMicrophone() failed to start "
239 : "playing stream");
240 0 : return -1;
241 : } else {
242 0 : channelPtr->SetMixWithMicStatus(mixWithMicrophone);
243 0 : return 0;
244 : }
245 : }
246 : }
247 :
248 0 : int VoEFileImpl::StopPlayingFileAsMicrophone(int channel) {
249 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
250 : "StopPlayingFileAsMicrophone(channel=%d)", channel);
251 0 : if (!_shared->statistics().Initialized()) {
252 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
253 0 : return -1;
254 : }
255 0 : if (channel == -1) {
256 : // Stop adding file before demultiplexing <=> affects all channels
257 0 : return _shared->transmit_mixer()->StopPlayingFileAsMicrophone();
258 : } else {
259 : // Stop adding file after demultiplexing <=> affects one channel only
260 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
261 0 : voe::Channel* channelPtr = ch.channel();
262 0 : if (channelPtr == NULL) {
263 0 : _shared->SetLastError(
264 : VE_CHANNEL_NOT_VALID, kTraceError,
265 0 : "StopPlayingFileAsMicrophone() failed to locate channel");
266 0 : return -1;
267 : }
268 0 : return channelPtr->StopPlayingFileAsMicrophone();
269 : }
270 : }
271 :
272 0 : int VoEFileImpl::IsPlayingFileAsMicrophone(int channel) {
273 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
274 : "IsPlayingFileAsMicrophone(channel=%d)", channel);
275 0 : if (!_shared->statistics().Initialized()) {
276 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
277 0 : return -1;
278 : }
279 0 : if (channel == -1) {
280 0 : return _shared->transmit_mixer()->IsPlayingFileAsMicrophone();
281 : } else {
282 : // Stop adding file after demultiplexing <=> affects one channel only
283 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
284 0 : voe::Channel* channelPtr = ch.channel();
285 0 : if (channelPtr == NULL) {
286 0 : _shared->SetLastError(
287 : VE_CHANNEL_NOT_VALID, kTraceError,
288 0 : "IsPlayingFileAsMicrophone() failed to locate channel");
289 0 : return -1;
290 : }
291 0 : return channelPtr->IsPlayingFileAsMicrophone();
292 : }
293 : }
294 :
295 0 : int VoEFileImpl::StartRecordingPlayout(int channel,
296 : const char* fileNameUTF8,
297 : CodecInst* compression,
298 : int maxSizeBytes) {
299 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
300 : "StartRecordingPlayout(channel=%d, fileNameUTF8=%s, "
301 : "compression, maxSizeBytes=%d)",
302 : channel, fileNameUTF8, maxSizeBytes);
303 : static_assert(1024 == FileWrapper::kMaxFileNameSize, "");
304 :
305 0 : if (!_shared->statistics().Initialized()) {
306 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
307 0 : return -1;
308 : }
309 0 : if (channel == -1) {
310 0 : return _shared->output_mixer()->StartRecordingPlayout(fileNameUTF8,
311 0 : compression);
312 : } else {
313 : // Add file after demultiplexing <=> affects one channel only
314 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
315 0 : voe::Channel* channelPtr = ch.channel();
316 0 : if (channelPtr == NULL) {
317 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
318 0 : "StartRecordingPlayout() failed to locate channel");
319 0 : return -1;
320 : }
321 0 : return channelPtr->StartRecordingPlayout(fileNameUTF8, compression);
322 : }
323 : }
324 :
325 0 : int VoEFileImpl::StartRecordingPlayout(int channel,
326 : OutStream* stream,
327 : CodecInst* compression) {
328 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
329 : "StartRecordingPlayout(channel=%d, stream, compression)",
330 : channel);
331 0 : if (!_shared->statistics().Initialized()) {
332 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
333 0 : return -1;
334 : }
335 0 : if (channel == -1) {
336 0 : return _shared->output_mixer()->StartRecordingPlayout(stream, compression);
337 : } else {
338 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
339 0 : voe::Channel* channelPtr = ch.channel();
340 0 : if (channelPtr == NULL) {
341 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
342 0 : "StartRecordingPlayout() failed to locate channel");
343 0 : return -1;
344 : }
345 0 : return channelPtr->StartRecordingPlayout(stream, compression);
346 : }
347 : }
348 :
349 0 : int VoEFileImpl::StopRecordingPlayout(int channel) {
350 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
351 : "StopRecordingPlayout(channel=%d)", channel);
352 0 : if (!_shared->statistics().Initialized()) {
353 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
354 0 : return -1;
355 : }
356 0 : if (channel == -1) {
357 0 : return _shared->output_mixer()->StopRecordingPlayout();
358 : } else {
359 0 : voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
360 0 : voe::Channel* channelPtr = ch.channel();
361 0 : if (channelPtr == NULL) {
362 0 : _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
363 0 : "StopRecordingPlayout() failed to locate channel");
364 0 : return -1;
365 : }
366 0 : return channelPtr->StopRecordingPlayout();
367 : }
368 : }
369 :
370 0 : int VoEFileImpl::StartRecordingMicrophone(const char* fileNameUTF8,
371 : CodecInst* compression,
372 : int maxSizeBytes) {
373 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
374 : "StartRecordingMicrophone(fileNameUTF8=%s, compression, "
375 : "maxSizeBytes=%d)",
376 : fileNameUTF8, maxSizeBytes);
377 : static_assert(1024 == FileWrapper::kMaxFileNameSize, "");
378 :
379 0 : if (!_shared->statistics().Initialized()) {
380 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
381 0 : return -1;
382 : }
383 0 : if (_shared->transmit_mixer()->StartRecordingMicrophone(fileNameUTF8,
384 : compression)) {
385 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
386 : "StartRecordingMicrophone() failed to start recording");
387 0 : return -1;
388 : }
389 0 : if (!_shared->audio_device()->Recording()) {
390 0 : if (_shared->audio_device()->InitRecording() != 0) {
391 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
392 : "StartRecordingMicrophone() failed to initialize recording");
393 0 : return -1;
394 : }
395 0 : if (_shared->audio_device()->StartRecording() != 0) {
396 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
397 : "StartRecordingMicrophone() failed to start recording");
398 0 : return -1;
399 : }
400 : }
401 0 : return 0;
402 : }
403 :
404 0 : int VoEFileImpl::StartRecordingMicrophone(OutStream* stream,
405 : CodecInst* compression) {
406 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
407 : "StartRecordingMicrophone(stream, compression)");
408 :
409 0 : if (!_shared->statistics().Initialized()) {
410 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
411 0 : return -1;
412 : }
413 0 : if (_shared->transmit_mixer()->StartRecordingMicrophone(stream,
414 : compression) == -1) {
415 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
416 : "StartRecordingMicrophone() failed to start recording");
417 0 : return -1;
418 : }
419 0 : if (!_shared->audio_device()->Recording()) {
420 0 : if (_shared->audio_device()->InitRecording() != 0) {
421 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
422 : "StartRecordingMicrophone() failed to initialize recording");
423 0 : return -1;
424 : }
425 0 : if (_shared->audio_device()->StartRecording() != 0) {
426 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
427 : "StartRecordingMicrophone() failed to start recording");
428 0 : return -1;
429 : }
430 : }
431 0 : return 0;
432 : }
433 :
434 0 : int VoEFileImpl::StopRecordingMicrophone() {
435 : WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
436 : "StopRecordingMicrophone()");
437 0 : if (!_shared->statistics().Initialized()) {
438 0 : _shared->SetLastError(VE_NOT_INITED, kTraceError);
439 0 : return -1;
440 : }
441 :
442 0 : int err = 0;
443 :
444 : // TODO(xians): consider removing Start/StopRecording() in
445 : // Start/StopRecordingMicrophone() if no channel is recording.
446 0 : if (_shared->NumOfSendingChannels() == 0 &&
447 0 : _shared->audio_device()->Recording()) {
448 : // Stop audio-device recording if no channel is recording
449 0 : if (_shared->audio_device()->StopRecording() != 0) {
450 0 : _shared->SetLastError(
451 : VE_CANNOT_STOP_RECORDING, kTraceError,
452 0 : "StopRecordingMicrophone() failed to stop recording");
453 0 : err = -1;
454 : }
455 : }
456 :
457 0 : if (_shared->transmit_mixer()->StopRecordingMicrophone() != 0) {
458 : WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_shared->instance_id(), -1),
459 : "StopRecordingMicrophone() failed to stop recording to mixer");
460 0 : err = -1;
461 : }
462 :
463 0 : return err;
464 : }
465 :
466 : } // namespace webrtc
|