blob: 324dfec526fb5dbd37f7a491ded197f1c7ce4cd7 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org79af7342012-01-31 12:22:14 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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 "voe_external_media_impl.h"
12
13#include "channel.h"
14#include "critical_section_wrapper.h"
15#include "output_mixer.h"
16#include "trace.h"
17#include "transmit_mixer.h"
18#include "voice_engine_impl.h"
19#include "voe_errors.h"
20
21namespace webrtc {
22
23VoEExternalMedia* VoEExternalMedia::GetInterface(VoiceEngine* voiceEngine)
24{
25#ifndef WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API
26 return NULL;
27#else
28 if (NULL == voiceEngine)
29 {
30 return NULL;
31 }
tommi@webrtc.org0989fb72013-02-15 15:07:32 +000032 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
tommi@webrtc.orga990e122012-04-26 15:28:22 +000033 s->AddRef();
34 return s;
niklase@google.com470e71d2011-07-07 08:21:25 +000035#endif
36}
37
38#ifdef WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API
39
tommi@webrtc.org851becd2012-04-04 14:57:19 +000040VoEExternalMediaImpl::VoEExternalMediaImpl(voe::SharedData* shared)
wjia@webrtc.org3f9db372013-01-12 01:09:03 +000041 :
42#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
43 playout_delay_ms_(0),
44#endif
45 shared_(shared)
niklase@google.com470e71d2011-07-07 08:21:25 +000046{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000047 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000048 "VoEExternalMediaImpl() - ctor");
49}
50
51VoEExternalMediaImpl::~VoEExternalMediaImpl()
52{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000053 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000054 "~VoEExternalMediaImpl() - dtor");
55}
56
niklase@google.com470e71d2011-07-07 08:21:25 +000057int VoEExternalMediaImpl::RegisterExternalMediaProcessing(
58 int channel,
59 ProcessingTypes type,
60 VoEMediaProcess& processObject)
61{
tommi@webrtc.org851becd2012-04-04 14:57:19 +000062 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +000063 "RegisterExternalMediaProcessing(channel=%d, type=%d, "
64 "processObject=0x%x)", channel, type, &processObject);
tommi@webrtc.org851becd2012-04-04 14:57:19 +000065 if (!shared_->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +000066 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000067 shared_->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +000068 return -1;
69 }
70 switch (type)
71 {
72 case kPlaybackPerChannel:
73 case kRecordingPerChannel:
74 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000075 voe::ScopedChannel sc(shared_->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +000076 voe::Channel* channelPtr = sc.ChannelPtr();
77 if (channelPtr == NULL)
78 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000079 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
80 "RegisterExternalMediaProcessing() failed to locate "
81 "channel");
niklase@google.com470e71d2011-07-07 08:21:25 +000082 return -1;
83 }
84 return channelPtr->RegisterExternalMediaProcessing(type,
85 processObject);
86 }
87 case kPlaybackAllChannelsMixed:
88 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000089 return shared_->output_mixer()->RegisterExternalMediaProcessing(
niklase@google.com470e71d2011-07-07 08:21:25 +000090 processObject);
91 }
92 case kRecordingAllChannelsMixed:
andrew@webrtc.org21ab3ba2012-10-19 17:30:56 +000093 case kRecordingPreprocessing:
niklase@google.com470e71d2011-07-07 08:21:25 +000094 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +000095 return shared_->transmit_mixer()->RegisterExternalMediaProcessing(
andrew@webrtc.org21ab3ba2012-10-19 17:30:56 +000096 &processObject, type);
niklase@google.com470e71d2011-07-07 08:21:25 +000097 }
niklase@google.com470e71d2011-07-07 08:21:25 +000098 }
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +000099 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100}
101
102int VoEExternalMediaImpl::DeRegisterExternalMediaProcessing(
103 int channel,
104 ProcessingTypes type)
105{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000106 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000107 "DeRegisterExternalMediaProcessing(channel=%d)", channel);
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000108 if (!shared_->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000109 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000110 shared_->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111 return -1;
112 }
113 switch (type)
114 {
115 case kPlaybackPerChannel:
116 case kRecordingPerChannel:
117 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000118 voe::ScopedChannel sc(shared_->channel_manager(), channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 voe::Channel* channelPtr = sc.ChannelPtr();
120 if (channelPtr == NULL)
121 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000122 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000123 "RegisterExternalMediaProcessing() "
124 "failed to locate channel");
125 return -1;
126 }
127 return channelPtr->DeRegisterExternalMediaProcessing(type);
128 }
129 case kPlaybackAllChannelsMixed:
130 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000131 return shared_->output_mixer()->
132 DeRegisterExternalMediaProcessing();
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 }
134 case kRecordingAllChannelsMixed:
andrew@webrtc.org21ab3ba2012-10-19 17:30:56 +0000135 case kRecordingPreprocessing:
niklase@google.com470e71d2011-07-07 08:21:25 +0000136 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000137 return shared_->transmit_mixer()->
andrew@webrtc.org21ab3ba2012-10-19 17:30:56 +0000138 DeRegisterExternalMediaProcessing(type);
niklase@google.com470e71d2011-07-07 08:21:25 +0000139 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 }
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +0000141 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000142}
143
144int VoEExternalMediaImpl::SetExternalRecordingStatus(bool enable)
145{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000146 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000147 "SetExternalRecordingStatus(enable=%d)", enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000148#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000149 if (shared_->audio_device()->Recording())
niklase@google.com470e71d2011-07-07 08:21:25 +0000150 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000151 shared_->SetLastError(VE_ALREADY_SENDING, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000152 "SetExternalRecordingStatus() cannot set state while sending");
153 return -1;
154 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000155 shared_->set_ext_recording(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000156 return 0;
157#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000158 shared_->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000159 "SetExternalRecordingStatus() external recording is not supported");
160 return -1;
161#endif
162}
163
164int VoEExternalMediaImpl::ExternalRecordingInsertData(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000165 const int16_t speechData10ms[],
niklase@google.com470e71d2011-07-07 08:21:25 +0000166 int lengthSamples,
167 int samplingFreqHz,
168 int current_delay_ms)
169{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000170 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000171 "ExternalRecordingInsertData(speechData10ms=0x%x,"
172 " lengthSamples=%u, samplingFreqHz=%d, current_delay_ms=%d)",
173 &speechData10ms[0], lengthSamples, samplingFreqHz,
174 current_delay_ms);
niklase@google.com470e71d2011-07-07 08:21:25 +0000175#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000176 if (!shared_->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000177 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000178 shared_->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000179 return -1;
180 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000181 if (!shared_->ext_recording())
niklase@google.com470e71d2011-07-07 08:21:25 +0000182 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000183 shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000184 "ExternalRecordingInsertData() external recording is not enabled");
185 return -1;
186 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000187 if (shared_->NumOfSendingChannels() == 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000188 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000189 shared_->SetLastError(VE_ALREADY_SENDING, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000190 "SetExternalRecordingStatus() no channel is sending");
191 return -1;
192 }
193 if ((16000 != samplingFreqHz) && (32000 != samplingFreqHz) &&
194 (48000 != samplingFreqHz) && (44000 != samplingFreqHz))
195 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000196 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000197 "SetExternalRecordingStatus() invalid sample rate");
198 return -1;
199 }
200 if ((0 == lengthSamples) ||
201 ((lengthSamples % (samplingFreqHz / 100)) != 0))
202 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000203 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000204 "SetExternalRecordingStatus() invalid buffer size");
205 return -1;
206 }
207 if (current_delay_ms < 0)
208 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000209 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000210 "SetExternalRecordingStatus() invalid delay)");
211 return -1;
212 }
213
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000214 uint16_t blockSize = samplingFreqHz / 100;
215 uint32_t nBlocks = lengthSamples / blockSize;
216 int16_t totalDelayMS = 0;
217 uint16_t playoutDelayMS = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000218
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000219 for (uint32_t i = 0; i < nBlocks; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000220 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000221 if (!shared_->ext_playout())
niklase@google.com470e71d2011-07-07 08:21:25 +0000222 {
223 // Use real playout delay if external playout is not enabled.
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000224 if (shared_->audio_device()->PlayoutDelay(&playoutDelayMS) != 0) {
225 shared_->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning,
xians@webrtc.org79af7342012-01-31 12:22:14 +0000226 "PlayoutDelay() unable to get the playout delay");
227 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000228 totalDelayMS = current_delay_ms + playoutDelayMS;
229 }
230 else
231 {
232 // Use stored delay value given the last call
233 // to ExternalPlayoutGetData.
234 totalDelayMS = current_delay_ms + playout_delay_ms_;
235 // Compensate for block sizes larger than 10ms
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000236 totalDelayMS -= (int16_t)(i*10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000237 if (totalDelayMS < 0)
238 totalDelayMS = 0;
239 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000240 shared_->transmit_mixer()->PrepareDemux(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000241 (const int8_t*)(&speechData10ms[i*blockSize]),
niklase@google.com470e71d2011-07-07 08:21:25 +0000242 blockSize,
243 1,
244 samplingFreqHz,
245 totalDelayMS,
246 0,
247 0);
248
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000249 shared_->transmit_mixer()->DemuxAndMix();
250 shared_->transmit_mixer()->EncodeAndSend();
niklase@google.com470e71d2011-07-07 08:21:25 +0000251 }
252 return 0;
253#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000254 shared_->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000255 "ExternalRecordingInsertData() external recording is not supported");
256 return -1;
257#endif
258}
259
260int VoEExternalMediaImpl::SetExternalPlayoutStatus(bool enable)
261{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000262 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000263 "SetExternalPlayoutStatus(enable=%d)", enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000264#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000265 if (shared_->audio_device()->Playing())
niklase@google.com470e71d2011-07-07 08:21:25 +0000266 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000267 shared_->SetLastError(VE_ALREADY_SENDING, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000268 "SetExternalPlayoutStatus() cannot set state while playing");
269 return -1;
270 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000271 shared_->set_ext_playout(enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000272 return 0;
273#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000274 shared_->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000275 "SetExternalPlayoutStatus() external playout is not supported");
276 return -1;
277#endif
278}
279
280int VoEExternalMediaImpl::ExternalPlayoutGetData(
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000281 int16_t speechData10ms[],
niklase@google.com470e71d2011-07-07 08:21:25 +0000282 int samplingFreqHz,
283 int current_delay_ms,
284 int& lengthSamples)
285{
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000286 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(shared_->instance_id(), -1),
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 "ExternalPlayoutGetData(speechData10ms=0x%x, samplingFreqHz=%d"
288 ", current_delay_ms=%d)", &speechData10ms[0], samplingFreqHz,
289 current_delay_ms);
niklase@google.com470e71d2011-07-07 08:21:25 +0000290#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000291 if (!shared_->statistics().Initialized())
niklase@google.com470e71d2011-07-07 08:21:25 +0000292 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000293 shared_->SetLastError(VE_NOT_INITED, kTraceError);
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 return -1;
295 }
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000296 if (!shared_->ext_playout())
niklase@google.com470e71d2011-07-07 08:21:25 +0000297 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000298 shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 "ExternalPlayoutGetData() external playout is not enabled");
300 return -1;
301 }
302 if ((16000 != samplingFreqHz) && (32000 != samplingFreqHz) &&
303 (48000 != samplingFreqHz) && (44000 != samplingFreqHz))
304 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000305 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000306 "ExternalPlayoutGetData() invalid sample rate");
307 return -1;
308 }
309 if (current_delay_ms < 0)
310 {
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000311 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 "ExternalPlayoutGetData() invalid delay)");
313 return -1;
314 }
315
316 AudioFrame audioFrame;
317
318 // Retrieve mixed output at the specified rate
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000319 shared_->output_mixer()->MixActiveChannels();
320 shared_->output_mixer()->DoOperationsOnCombinedSignal();
andrew@webrtc.org4ecea3e2012-06-27 03:25:31 +0000321 shared_->output_mixer()->GetMixedAudio(samplingFreqHz, 1, &audioFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322
323 // Deliver audio (PCM) samples to the external sink
324 memcpy(speechData10ms,
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000325 audioFrame.data_,
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000326 sizeof(int16_t)*(audioFrame.samples_per_channel_));
andrew@webrtc.org63a50982012-05-02 23:56:37 +0000327 lengthSamples = audioFrame.samples_per_channel_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000328
329 // Store current playout delay (to be used by ExternalRecordingInsertData).
330 playout_delay_ms_ = current_delay_ms;
331
332 return 0;
333#else
tommi@webrtc.org851becd2012-04-04 14:57:19 +0000334 shared_->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 "ExternalPlayoutGetData() external playout is not supported");
336 return -1;
337#endif
338}
339
roosa@google.com1b60ceb2012-12-12 23:00:29 +0000340int VoEExternalMediaImpl::GetAudioFrame(int channel, int desired_sample_rate_hz,
341 AudioFrame* frame) {
342 WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
343 VoEId(shared_->instance_id(), channel),
344 "GetAudioFrame(channel=%d, desired_sample_rate_hz=%d)",
345 channel, desired_sample_rate_hz);
346 if (!shared_->statistics().Initialized())
347 {
348 shared_->SetLastError(VE_NOT_INITED, kTraceError);
349 return -1;
350 }
351 voe::ScopedChannel sc(shared_->channel_manager(), channel);
352 voe::Channel* channelPtr = sc.ChannelPtr();
353 if (channelPtr == NULL)
354 {
355 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
356 "GetAudioFrame() failed to locate channel");
357 return -1;
358 }
359 if (!channelPtr->ExternalMixing()) {
360 shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
361 "GetAudioFrame() was called on channel that is not"
362 " externally mixed.");
363 return -1;
364 }
365 if (!channelPtr->Playing()) {
366 shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
367 "GetAudioFrame() was called on channel that is not playing.");
368 return -1;
369 }
370 if (desired_sample_rate_hz == -1) {
371 shared_->SetLastError(VE_BAD_ARGUMENT, kTraceError,
372 "GetAudioFrame() was called with bad sample rate.");
373 return -1;
374 }
375 frame->sample_rate_hz_ = desired_sample_rate_hz == 0 ? -1 :
376 desired_sample_rate_hz;
377 return channelPtr->GetAudioFrame(channel, *frame);
378}
379
380int VoEExternalMediaImpl::SetExternalMixing(int channel, bool enable) {
381 WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
382 VoEId(shared_->instance_id(), channel),
383 "SetExternalMixing(channel=%d, enable=%d)", channel, enable);
384 if (!shared_->statistics().Initialized())
385 {
386 shared_->SetLastError(VE_NOT_INITED, kTraceError);
387 return -1;
388 }
389 voe::ScopedChannel sc(shared_->channel_manager(), channel);
390 voe::Channel* channelPtr = sc.ChannelPtr();
391 if (channelPtr == NULL)
392 {
393 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
394 "SetExternalMixing() failed to locate channel");
395 return -1;
396 }
397 return channelPtr->SetExternalMixing(enable);
398}
399
niklase@google.com470e71d2011-07-07 08:21:25 +0000400#endif // WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API
401
402} // namespace webrtc