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 #if defined(WEBRTC_ANDROID)
12 #include "webrtc/modules/audio_device/android/audio_device_template.h"
13 #if !defined(WEBRTC_GONK)
14 #include "webrtc/modules/audio_device/android/audio_record_jni.h"
15 #include "webrtc/modules/audio_device/android/audio_track_jni.h"
16 #endif
17 #if !defined(WEBRTC_CHROMIUM_BUILD)
18 #include "webrtc/modules/audio_device/android/opensles_input.h"
19 #include "webrtc/modules/audio_device/android/opensles_output.h"
20 #endif
21 #endif
22 
23 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
24 #include "webrtc/system_wrappers/interface/trace.h"
25 #include "webrtc/voice_engine/voice_engine_impl.h"
26 
27 namespace webrtc
28 {
29 
30 // Counter to be ensure that we can add a correct ID in all static trace
31 // methods. It is not the nicest solution, especially not since we already
32 // have a counter in VoEBaseImpl. In other words, there is room for
33 // improvement here.
34 static int32_t gVoiceEngineInstanceCounter = 0;
35 
GetVoiceEngine(const Config * config,bool owns_config)36 VoiceEngine* GetVoiceEngine(const Config* config, bool owns_config)
37 {
38 #if (defined _WIN32)
39   HMODULE hmod = LoadLibrary(TEXT("VoiceEngineTestingDynamic.dll"));
40 
41   if (hmod) {
42     typedef VoiceEngine* (*PfnGetVoiceEngine)(void);
43     PfnGetVoiceEngine pfn = (PfnGetVoiceEngine)GetProcAddress(
44         hmod,"GetVoiceEngine");
45     if (pfn) {
46       VoiceEngine* self = pfn();
47       if (owns_config) {
48         delete config;
49       }
50       return (self);
51     }
52   }
53 #endif
54 
55     VoiceEngineImpl* self = new VoiceEngineImpl(config, owns_config);
56     if (self != NULL)
57     {
58         self->AddRef();  // First reference.  Released in VoiceEngine::Delete.
59         gVoiceEngineInstanceCounter++;
60     }
61     return self;
62 }
63 
AddRef()64 int VoiceEngineImpl::AddRef() {
65   return ++_ref_count;
66 }
67 
68 // This implements the Release() method for all the inherited interfaces.
Release()69 int VoiceEngineImpl::Release() {
70   int new_ref = --_ref_count;
71   assert(new_ref >= 0);
72   if (new_ref == 0) {
73     WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1,
74                  "VoiceEngineImpl self deleting (voiceEngine=0x%p)",
75                  this);
76 
77     // Clear any pointers before starting destruction. Otherwise worker-
78     // threads will still have pointers to a partially destructed object.
79     // Example: AudioDeviceBuffer::RequestPlayoutData() can access a
80     // partially deconstructed |_ptrCbAudioTransport| during destruction
81     // if we don't call Terminate here.
82     Terminate();
83     delete this;
84   }
85 
86   return new_ref;
87 }
88 
Create()89 VoiceEngine* VoiceEngine::Create() {
90   Config* config = new Config();
91   return GetVoiceEngine(config, true);
92 }
93 
Create(const Config & config)94 VoiceEngine* VoiceEngine::Create(const Config& config) {
95   return GetVoiceEngine(&config, false);
96 }
97 
SetTraceFilter(unsigned int filter)98 int VoiceEngine::SetTraceFilter(unsigned int filter)
99 {
100     WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
101                  VoEId(gVoiceEngineInstanceCounter, -1),
102                  "SetTraceFilter(filter=0x%x)", filter);
103 
104     // Remember old filter
105     uint32_t oldFilter = Trace::level_filter();
106     Trace::set_level_filter(filter);
107 
108     // If previous log was ignored, log again after changing filter
109     if (kTraceNone == oldFilter)
110     {
111         WEBRTC_TRACE(kTraceApiCall, kTraceVoice, -1,
112                      "SetTraceFilter(filter=0x%x)", filter);
113     }
114 
115     return 0;
116 }
117 
SetTraceFile(const char * fileNameUTF8,bool addFileCounter)118 int VoiceEngine::SetTraceFile(const char* fileNameUTF8,
119                               bool addFileCounter)
120 {
121     int ret = Trace::SetTraceFile(fileNameUTF8, addFileCounter);
122     WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
123                  VoEId(gVoiceEngineInstanceCounter, -1),
124                  "SetTraceFile(fileNameUTF8=%s, addFileCounter=%d)",
125                  fileNameUTF8, addFileCounter);
126     return (ret);
127 }
128 
SetTraceCallback(TraceCallback * callback)129 int VoiceEngine::SetTraceCallback(TraceCallback* callback)
130 {
131     WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
132                  VoEId(gVoiceEngineInstanceCounter, -1),
133                  "SetTraceCallback(callback=0x%x)", callback);
134     return (Trace::SetTraceCallback(callback));
135 }
136 
Delete(VoiceEngine * & voiceEngine)137 bool VoiceEngine::Delete(VoiceEngine*& voiceEngine)
138 {
139     if (voiceEngine == NULL)
140         return false;
141 
142     VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
143     // Release the reference that was added in GetVoiceEngine.
144     int ref = s->Release();
145     voiceEngine = NULL;
146 
147     if (ref != 0) {
148         WEBRTC_TRACE(kTraceWarning, kTraceVoice, -1,
149             "VoiceEngine::Delete did not release the very last reference.  "
150             "%d references remain.", ref);
151     }
152 
153     return true;
154 }
155 
156 #if !defined(WEBRTC_CHROMIUM_BUILD)
SetAndroidObjects(void * javaVM,void * context)157 int VoiceEngine::SetAndroidObjects(void* javaVM, void* context)
158 {
159 #ifdef WEBRTC_ANDROID
160 #ifdef WEBRTC_ANDROID_OPENSLES
161   typedef AudioDeviceTemplate<OpenSlesInput, OpenSlesOutput>
162       AudioDeviceInstance;
163 #endif
164 #if !defined(WEBRTC_GONK) && defined(ANDROID)
165   typedef AudioDeviceTemplate<AudioRecordJni, AudioTrackJni>
166       AudioDeviceInstanceJni;
167 #endif
168   if (javaVM && context) {
169 #if !defined(WEBRTC_GONK) && defined(ANDROID)
170     AudioDeviceInstanceJni::SetAndroidAudioDeviceObjects(javaVM, context);
171 #endif
172 #ifdef WEBRTC_ANDROID_OPENSLES
173     AudioDeviceInstance::SetAndroidAudioDeviceObjects(javaVM, context);
174 #endif
175   } else {
176 #if !defined(WEBRTC_GONK) && defined(ANDROID)
177     AudioDeviceInstanceJni::ClearAndroidAudioDeviceObjects();
178 #endif
179 #ifdef WEBRTC_ANDROID_OPENSLES
180     AudioDeviceInstance::ClearAndroidAudioDeviceObjects();
181 #endif
182   }
183   return 0;
184 #else
185   return -1;
186 #endif
187 }
188 #endif
189 
190 }  // namespace webrtc
191