2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
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 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
14 #include "ttsd_main.h"
15 #include "ttsd_data.h"
16 #include "PlayerThread.h"
21 void PlayerThread::runThread(PlayerThread* player)
23 SLOG(LOG_INFO, tts_tag(), "[Player] Run player thread");
25 SLOG(LOG_INFO, tts_tag(), "[Player] Exit player thread");
28 PlayerThread::PlayerThread(PlayUtteranceCallback threadFucntion)
30 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Constructor");
31 __currentUid = TTS_INVALID_UID;
32 __playerAvailable = true;
33 __playUtterance = threadFucntion;
35 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Start thread");
36 __playerThread = thread(runThread, this);
39 PlayerThread::~PlayerThread()
41 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Destructor");
42 unique_lock<mutex> controlLock(__controlMutex);
43 __playerAvailable = false;
44 __playUtterance = nullptr;
47 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Thread is stopped or waiting");
49 __threadCond.notify_all();
50 __playerThread.join();
51 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Finish thread");
54 void PlayerThread::tryToStopPlayer()
56 __currentUid = TTS_INVALID_UID;
58 unique_lock<mutex> stopCheckLock(__stopCheckMutex);
59 cv_status ret = __stopCheckCond.wait_for(stopCheckLock, chrono::milliseconds(500));
60 if (ret == cv_status::timeout) {
61 SLOG(LOG_WARN, tts_tag(), "[PlayerThread] Timeout stop request");
65 bool PlayerThread::isPlayerAvailable()
67 return __playerAvailable.load();
70 unsigned int PlayerThread::getCurrentUid()
72 return __currentUid.load();
75 bool PlayerThread::isCurrentUid(unsigned int uid)
77 if (0 > ttsd_data_is_client(uid)) {
81 if (uid != __currentUid.load()) {
88 void PlayerThread::requestPlay(unsigned int uid)
90 lock_guard<mutex> lock(__controlMutex);
91 if (false == isPlayerAvailable()) {
92 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Player is already finished.");
96 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Play request. uid(%u)", uid);
98 __threadCond.notify_all();
101 void PlayerThread::requestStop()
103 lock_guard<mutex> lock(__controlMutex);
104 if (false == isPlayerAvailable()) {
105 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Player is already finished.");
109 unsigned int uid = __currentUid.load();
110 if (uid == TTS_INVALID_UID) {
111 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Thread is already stopped");
115 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Stop request. current played uid(%u)", uid);
117 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Stop playing");
120 void PlayerThread::runPlayer()
122 unique_lock<mutex> lock(__threadMutex);
123 if (nullptr == __playUtterance) {
124 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Play utterance callback is not set");
128 while (isPlayerAvailable()) {
129 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Wait playing");
130 if (isThreadStopped()) {
131 __threadCond.wait(lock);
134 while (false == isThreadStopped()) {
135 unsigned int uid = getCurrentUid();
136 SLOG(LOG_INFO, tts_tag(), "[Player] Current player uid(%u)", uid);
137 __playUtterance(this, uid);
140 __stopCheckCond.notify_all();
144 bool PlayerThread::isThreadStopped()
146 bool isStopped = (TTS_INVALID_UID == __currentUid.load()) || (false == isPlayerAvailable());