• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <unistd.h>
16 #include "media_errors.h"
17 #include "media_log.h"
18 #include "soundpool_manager.h"
19 #include "soundpool.h"
20 
21 namespace OHOS {
22 namespace Media {
CreateSoundPool(int maxStreams,AudioStandard::AudioRendererInfo audioRenderInfo)23 std::shared_ptr<ISoundPool> SoundPoolFactory::CreateSoundPool(int maxStreams,
24     AudioStandard::AudioRendererInfo audioRenderInfo)
25 {
26     std::shared_ptr<SoundPool> impl;
27     if (!SoundPool::CheckInitParam(maxStreams, audioRenderInfo)) {
28         return nullptr;
29     }
30     SoundPoolManager::GetInstance().SetSoundPool(getpid(), impl);
31     SoundPoolManager::GetInstance().GetSoundPool(getpid(), impl);
32     CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr, "failed to get SoundPool");
33 
34     int32_t ret = impl->Init(maxStreams, audioRenderInfo);
35     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to init SoundPool");
36 
37     return impl;
38 }
39 
SoundPool()40 SoundPool::SoundPool()
41 {
42     MEDIA_INFO_LOG("Construction SoundPool.");
43 }
44 
~SoundPool()45 SoundPool::~SoundPool()
46 {
47     MEDIA_INFO_LOG("Destruction SoundPool.");
48     Release();
49 }
50 
Init(int maxStreams,AudioStandard::AudioRendererInfo audioRenderInfo)51 int32_t SoundPool::Init(int maxStreams, AudioStandard::AudioRendererInfo audioRenderInfo)
52 {
53     // start contruct stream manager
54     streamIdManager_ = std::make_shared<StreamIDManager>(maxStreams, audioRenderInfo);
55     soundIDManager_ = std::make_shared<SoundIDManager>();
56     return MSERR_OK;
57 }
58 
CheckInitParam(int maxStreams,AudioStandard::AudioRendererInfo audioRenderInfo)59 bool SoundPool::CheckInitParam(int maxStreams, AudioStandard::AudioRendererInfo audioRenderInfo)
60 {
61     if (maxStreams <= 0) {
62         return false;
63     }
64     if (audioRenderInfo.contentType < AudioStandard::CONTENT_TYPE_UNKNOWN
65         || audioRenderInfo.contentType > AudioStandard::CONTENT_TYPE_ULTRASONIC
66         || audioRenderInfo.streamUsage < AudioStandard::STREAM_USAGE_UNKNOWN
67         || audioRenderInfo.streamUsage > AudioStandard::STREAM_USAGE_VOICE_MODEM_COMMUNICATION
68         || audioRenderInfo.rendererFlags < 0 || audioRenderInfo.rendererFlags > 1) {
69         return false;
70     }
71     return true;
72 }
73 
Load(const std::string url)74 int32_t SoundPool::Load(const std::string url)
75 {
76     MEDIA_INFO_LOG("SoundPool::Load url::%{public}s", url.c_str());
77     CHECK_AND_RETURN_RET_LOG(!url.empty(), -1, "Failed to obtain SoundPool for load");
78     std::lock_guard lock(soundPoolLock_);
79     return soundIDManager_->Load(url);
80 }
81 
Load(int32_t fd,int64_t offset,int64_t length)82 int32_t SoundPool::Load(int32_t fd, int64_t offset, int64_t length)
83 {
84     MEDIA_INFO_LOG("SoundPool::Load fd::%{public}d", fd);
85     CHECK_AND_RETURN_RET_LOG((fd > 0 && length > 0 && offset >= 0), -1, "Invalid fd param.");
86     std::lock_guard lock(soundPoolLock_);
87     return soundIDManager_->Load(fd, offset, length);
88 }
89 
Play(int32_t soundID,PlayParams playParameters)90 int32_t SoundPool::Play(int32_t soundID, PlayParams playParameters)
91 {
92     MEDIA_INFO_LOG("SoundPool::Play soundID::%{public}d ,priority::%{public}d", soundID, playParameters.priority);
93     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, -1, "sound pool have released.");
94     std::lock_guard lock(soundPoolLock_);
95     std::shared_ptr<SoundParser> soundParser = soundIDManager_->FindSoundParser(soundID);
96 
97     CHECK_AND_RETURN_RET_LOG(soundParser != nullptr, -1, "Invalid sound.");
98     if (!soundParser->IsSoundParserCompleted()) {
99         MEDIA_ERR_LOG("sound load no completed. ");
100         return -1;
101     }
102     const int32_t streamID = streamIdManager_->Play(soundParser, playParameters);
103     MEDIA_INFO_LOG("SoundPool::Play streamID::%{public}d", streamID);
104     return streamID;
105 }
106 
Stop(int32_t streamID)107 int32_t SoundPool::Stop(int32_t streamID)
108 {
109     MEDIA_INFO_LOG("SoundPool::Stop streamID::%{public}d", streamID);
110     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, MSERR_INVALID_VAL, "sound pool have released.");
111     std::lock_guard lock(soundPoolLock_);
112     if (std::shared_ptr<CacheBuffer> cacheBuffer = streamIdManager_->FindCacheBuffer(streamID)) {
113         return cacheBuffer->Stop(streamID);
114     }
115     return MSERR_INVALID_OPERATION;
116 }
117 
SetLoop(int32_t streamID,int32_t loop)118 int32_t SoundPool::SetLoop(int32_t streamID, int32_t loop)
119 {
120     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, MSERR_INVALID_VAL, "sound pool have released.");
121     std::lock_guard lock(soundPoolLock_);
122     if (std::shared_ptr<CacheBuffer> cacheBuffer = streamIdManager_->FindCacheBuffer(streamID)) {
123         return cacheBuffer->SetLoop(streamID, loop);
124     }
125     return MSERR_INVALID_OPERATION;
126 }
127 
SetPriority(int32_t streamID,int32_t priority)128 int32_t SoundPool::SetPriority(int32_t streamID, int32_t priority)
129 {
130     MEDIA_INFO_LOG("SoundPool::SetPriority streamID::%{public}d ,priority::%{public}d", streamID, priority);
131     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, MSERR_INVALID_VAL, "sound pool have released.");
132     std::lock_guard lock(soundPoolLock_);
133     if (std::shared_ptr<CacheBuffer> cacheBuffer = streamIdManager_->FindCacheBuffer(streamID)) {
134         if (priority < MIN_STREAM_PRIORITY) {
135             MEDIA_INFO_LOG("Invalid priority, align priority to min.");
136             priority = MIN_STREAM_PRIORITY;
137         }
138         int32_t ret = cacheBuffer->SetPriority(streamID, priority);
139         streamIdManager_->ReorderStream(streamID, priority);
140         return ret;
141     }
142     return MSERR_INVALID_OPERATION;
143 }
144 
SetRate(int32_t streamID,AudioStandard::AudioRendererRate renderRate)145 int32_t SoundPool::SetRate(int32_t streamID, AudioStandard::AudioRendererRate renderRate)
146 {
147     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, MSERR_INVALID_VAL, "sound pool have released.");
148     std::lock_guard lock(soundPoolLock_);
149     if (std::shared_ptr<CacheBuffer> cacheBuffer = streamIdManager_->FindCacheBuffer(streamID)) {
150         return cacheBuffer->SetRate(streamID, renderRate);
151     }
152     return MSERR_INVALID_OPERATION;
153 }
154 
SetVolume(int32_t streamID,float leftVolume,float rightVolume)155 int32_t SoundPool::SetVolume(int32_t streamID, float leftVolume, float rightVolume)
156 {
157     if (!CheckVolumeVaild(&leftVolume, &rightVolume)) {
158         return MSERR_INVALID_VAL;
159     }
160 
161     CHECK_AND_RETURN_RET_LOG(streamIdManager_ != nullptr, MSERR_INVALID_VAL, "sound pool have released.");
162     std::lock_guard lock(soundPoolLock_);
163     if (std::shared_ptr<CacheBuffer> cacheBuffer = streamIdManager_->FindCacheBuffer(streamID)) {
164         return cacheBuffer->SetVolume(streamID, leftVolume, rightVolume);
165     }
166     return MSERR_INVALID_OPERATION;
167 }
168 
Unload(int32_t soundID)169 int32_t SoundPool::Unload(int32_t soundID)
170 {
171     MEDIA_INFO_LOG("SoundPool::Unload soundID::%{public}d", soundID);
172     return soundIDManager_->Unload(soundID);
173 }
174 
Release()175 int32_t SoundPool::Release()
176 {
177     MEDIA_INFO_LOG("Release SoundPool.");
178     SoundPoolManager::GetInstance().Release(getpid());
179 
180     if (streamIdManager_ != nullptr) {
181         streamIdManager_.reset();
182     }
183     if (soundIDManager_ != nullptr) {
184         soundIDManager_.reset();
185     }
186     if (callback_ != nullptr) {
187         callback_.reset();
188     }
189     return MSERR_OK;
190 }
191 
SetSoundPoolCallback(const std::shared_ptr<ISoundPoolCallback> & soundPoolCallback)192 int32_t SoundPool::SetSoundPoolCallback(const std::shared_ptr<ISoundPoolCallback> &soundPoolCallback)
193 {
194     MEDIA_INFO_LOG("SoundPool::%{public}s", __func__);
195     if (soundIDManager_ != nullptr) soundIDManager_->SetCallback(soundPoolCallback);
196     if (streamIdManager_ != nullptr) streamIdManager_->SetCallback(soundPoolCallback);
197     callback_ = soundPoolCallback;
198     return MSERR_OK;
199 }
200 
CheckVolumeVaild(float * leftVol,float * rightVol)201 bool SoundPool::CheckVolumeVaild(float *leftVol, float *rightVol)
202 {
203     if (*leftVol != std::clamp(*leftVol, 0.f, 1.f) ||
204         *rightVol != std::clamp(*rightVol, 0.f, 1.f)) {
205         MEDIA_INFO_LOG("volume l=%{public}f r=%{public}f out of (0.f, 1.f) bounds, using 1.f", *leftVol, *rightVol);
206         *leftVol = *rightVol = 1.f;
207     }
208     if (*leftVol != *rightVol) {
209         MEDIA_INFO_LOG("left volume %{public}f set not eq the right volume %{public}f ,use the left volume",
210                        *leftVol, *rightVol);
211         *rightVol = *leftVol;
212     }
213     return true;
214 }
215 } // namespace Media
216 } // namespace OHOS
217