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