001package com.aispeech.dui.dds.agent.vprint;
002
003import android.text.TextUtils;
004import android.util.Log;
005
006import com.aispeech.dui.BaseNode;
007import com.aispeech.dui.BusClient;
008import com.aispeech.dui.dds.DDS;
009import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException;
010import com.aispeech.dui.manager.AILog;
011import com.aispeech.libbase.export.bean.VprintIntent;
012import com.aispeech.libcomm.business.call.VprintCallUtil;
013import com.aispeech.libcomm.business.config.PlayerConfig;
014import com.aispeech.libcomm.business.topic.Topic;
015import com.aispeech.libcomm.business.topic.VprintTopicUtil;
016import com.aispeech.libcomm.business.util.CompatibleTool;
017
018import org.json.JSONObject;
019
020public class VprintEngine {
021    private static final String TAG = "VprintEngine";
022
023    private volatile static VprintEngine mInstance;
024    private VprintListener mListener;
025    private BusClient mBc;
026    private String[] mTopicList = new String[]{
027            Topic.Vprint.VprintResult.TOPIC_NAME,
028            Topic.Vprint.VprintState.TOPIC_NAME,
029            Topic.Vprint.VprintError.TOPIC_NAME
030    };
031
032    private BaseNode mNode = new BaseNode() {
033        @Override
034        public String getName() {
035            return TAG;
036        }
037
038        @Override
039        public String getAddress() {
040            return DDS.BUS_SERVER_ADDR;
041        }
042
043        @Override
044        public BusClient.RPCResult onCall(String url, Object... args) throws Exception {
045            return null;
046        }
047
048        @Override
049        public void onJoin() {
050            super.onJoin();
051            mBc = bc;
052            subscribe();
053        }
054
055        @Override
056        public void onMessage(String topic, Object... parts) throws Exception {
057            Log.e(TAG, "onMessage topic: " + topic);
058            switch (topic) {
059                case Topic.Vprint.VprintResult.TOPIC_NAME:
060                    onCallback((String) parts[0], 0);
061                    break;
062                case Topic.Vprint.VprintState.TOPIC_NAME:
063                    onCallback(CompatibleTool.getString((JSONObject) parts[0], Topic.Vprint.VprintState.STATE), 1);
064                    break;
065                case Topic.Vprint.VprintError.TOPIC_NAME:
066                    onCallback(CompatibleTool.getString(parts[0]), 2);
067                    break;
068            }
069        }
070
071        @Override
072        public void onExit() {
073            unSubscribe();
074        }
075    };
076
077    private void onCallback(String result, int type) {
078        if (mListener != null) {
079            if (type == 0) {
080                mListener.onResults(result);
081            } else if (type == 1) {
082                mListener.onState(result);
083            } else if (type == 2) {
084                mListener.onError(result);
085            }
086        }
087    }
088
089    private VprintEngine() {
090        mNode.start();
091    }
092
093    private static VprintEngine getInstance() {
094        VprintEngine localResource = mInstance;
095        if (localResource == null) {
096            synchronized (VprintEngine.class) {
097                localResource = mInstance;
098                if (localResource == null) {
099                    mInstance = localResource = new VprintEngine();
100                }
101            }
102        }
103        return localResource;
104    }
105
106    /**
107     * 设置声纹状态信息监听器
108     *
109     * @param listener 声纹监听器
110     */
111    public void setVprintListener(VprintListener listener) throws DDSNotInitCompleteException {
112        checkInitComplete();
113        AILog.userI(TAG, "setVprintListener input =", (listener != null));
114
115        this.mListener = listener;
116        if (listener != null) {
117            subscribe();
118        } else {
119            unSubscribe();
120        }
121    }
122
123    private void subscribe() {
124        if (mBc != null && mListener != null) {
125            mBc.subscribe(mTopicList);
126        }
127    }
128
129    private void unSubscribe() {
130        if (mBc != null) {
131            mBc.unsubscribe(mTopicList);
132        }
133    }
134
135    /**
136     * 开启声纹意图
137     *
138     * @param intent
139     * @throws DDSNotInitCompleteException
140     */
141    public void start(VprintIntent intent) throws DDSNotInitCompleteException {
142        if (intent == null)
143            return;
144        checkInitComplete();
145        AILog.userI(TAG, "start input =", (intent != null ? intent.toJSONObject().toString() : "null"));
146
147
148        BusClient bc = DDS.getInstance().getAgent().getBusClient();
149        VprintTopicUtil.publishVprintStart(bc, intent);
150    }
151
152    /**
153     * 获取声纹模型
154     * <p>
155     *
156     * @throws DDSNotInitCompleteException 如果DDS没有初始化完成,会抛出exception
157     */
158    public String getMode() throws DDSNotInitCompleteException {
159        checkInitComplete();
160
161        BusClient bc = DDS.getInstance().getAgent().getBusClient();
162        String result = VprintCallUtil.callVprintMode(bc);
163        AILog.userI(TAG, "getMode result =", result);
164        return result;
165    }
166
167    /**
168     *
169     * @return 返回Vprint mode文件路径
170     * @throws DDSNotInitCompleteException
171     */
172    public String getVprintModeFilePath() throws DDSNotInitCompleteException  {
173        checkInitComplete();
174        String modeFilePath = PlayerConfig.getInstance().getStringConfig("VPRINT_MODE_FILEPATH");
175        if(TextUtils.isEmpty(modeFilePath)) {
176            String vprintModeName = PlayerConfig.getInstance().getStringConfig("VPRINT_MODE_NAME");
177            if (TextUtils.isEmpty(vprintModeName)) {
178                vprintModeName = "hw_" + PlayerConfig.getInstance().getStringConfig("MIC_TYPE","0");
179            }
180            modeFilePath = PlayerConfig.getInstance().getDataPath("model_data/vprint_mode_" + vprintModeName + ".bin");
181        }
182        return modeFilePath;
183    }
184
185    /**
186     * 停止声纹
187     * <p>
188     *
189     * @throws DDSNotInitCompleteException 如果DDS没有初始化完成,会抛出exception
190     */
191    public void stop() throws DDSNotInitCompleteException {
192        checkInitComplete();
193        AILog.userI(TAG, "stop");
194        BusClient bc = DDS.getInstance().getAgent().getBusClient();
195        VprintTopicUtil.publishVprintStop(bc);
196    }
197
198    /**
199     * 重启Vprint engine,如果已经start了Vprint Intent,需要应用层重新start
200     * @throws DDSNotInitCompleteException
201     */
202    public void reset() throws DDSNotInitCompleteException {
203        checkInitComplete();
204        AILog.userI(TAG, "reset vprint...");
205        BusClient bc = DDS.getInstance().getAgent().getBusClient();
206        VprintTopicUtil.publishVprintReset(bc);
207    }
208
209    /**
210     * 动态设置声纹功能是否可用,前提是初始化时声纹可用
211     *
212     * @param enable 声纹功能是否可用
213     * @throws DDSNotInitCompleteException
214     */
215    public void setVprintEnable(boolean enable) throws DDSNotInitCompleteException {
216        checkInitComplete();
217        AILog.userI(TAG, "setVprintEnable enable = ",enable);
218        BusClient bc = DDS.getInstance().getAgent().getBusClient();
219        VprintTopicUtil.publishVprintEnable(bc, enable);
220    }
221
222    private void checkInitComplete() throws DDSNotInitCompleteException {
223        if (DDS.getInstance().getInitStatus() != DDS.INIT_COMPLETE_FULL) {
224            throw new DDSNotInitCompleteException();
225        }
226    }
227
228    /**
229     * 获取 ASREngine 实例快照
230     *
231     * @return ASREngine
232     */
233    public static VprintEngine getInstanceSnapshot() {
234        return mInstance;
235    }
236
237    public void destroy() {
238        if (mInstance != null) {
239            if (mInstance.mNode != null) {
240                mInstance.mNode.stop();
241            }
242            mInstance = null;
243        }
244    }
245
246}