Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 3D語音天氣球——在Unity中使用Android語音服務

3D語音天氣球——在Unity中使用Android語音服務

編輯:關於Android編程

轉載請注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),謝謝支持!


開篇廢話:


這個項目准備分四部分介紹:

一:創建可旋轉的“3D球”:3D語音天氣球(源碼分享)——創建可旋轉的3D球

二:通過天氣服務,從網絡獲取時實天氣信息並動態生成“3D球”:3D語音天氣球(源碼分享)——通過天氣服務動態創建3D球

三:Android語音服務和Unity的消息傳遞

四:Unity3D端和Android端的結合

前兩篇文章已經介紹了如何創建這個3D球,本篇文章介紹如何在Unity中使用Android的語音服務,最後一篇文章則會介紹如何用聲音控制這個3D球。

左邊是Unity做出後在電腦上運行效果圖(本節需要實現的效果)

右邊是Unity結合Android和語音控制之後在手機運行的效果圖(所有都介紹完後的最終效果):

\ \



語音服務:

我使用的語音服務是科大訊飛語音,他們的官網是http://open.voicecloud.cn/index.php/default/speechservice

進入官網下載Android版語音的sdk(需要注冊還有一些爛七八糟的東西,有點小麻煩)

下載後裡面有一些開發包和一個使用Demo,這個Demo運行的效果如下:

\


使用簡介:

我只用到了語音聽寫語音合成,下面簡單介紹一些這倆個功能的使用。


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1NrKudPDyrHQ6NKq09DSu9CpPHN0cm9uZz6hsLP1yry7r6GxPC9zdHJvbmc+tcS5pNf3o7o8L3A+CjxwPjxzdHJvbmc+QW5kcm9pZE1hbmlmZXN0LnhtbNbQyejWw9K70KnIqM/eo7o8L3N0cm9uZz48L3A+CjxwcmUgY2xhc3M9"brush:java;">

導入開發包:

armeabiso動態庫

mac.jar jar包


代碼中設置權限:

SpeechUtility.createUtility(this, SpeechConstant.APPID + "=540dcea0");

語音聽寫:

就是將說的話轉換成文字。識別率十分准確,基本沒出過錯。

初始化識別對象:

		// 初始化識別對象
		SpeechRecognizer mVoice = SpeechRecognizer.createRecognizer(this, mInitListener);

設置參數:

		// 設置語言
		mVoice.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
		// 設置語言區域
		mVoice.setParameter(SpeechConstant.ACCENT, "mandarin");

		// 設置語音前端點
		mVoice.setParameter(SpeechConstant.VAD_BOS, "4000");
		// 設置語音後端點
		mVoice.setParameter(SpeechConstant.VAD_EOS, "1000");
		// 設置標點符號
		mVoice.setParameter(SpeechConstant.ASR_PTT, "0");
		// 設置音頻保存路徑
		mVoice.setParameter(SpeechConstant.ASR_AUDIO_PATH, "/sdcard/iflytek/wavaudio.pcm");
設置聽寫監聽器:
	private RecognizerListener recognizerListener=new RecognizerListener(){
		@Override
		public void onBeginOfSpeech() {	
			showTip("開始說話");
		}

		@Override
		public void onError(SpeechError error) {
			showTip(error.getPlainDescription(true));
		}

		@Override
		public void onEndOfSpeech() {
			showTip("結束說話");
		}

		@Override
		public void onResult(RecognizerResult results, boolean isLast) {		
			Log.d(TAG, results.getResultString());
			String text = JsonParser.parseIatResult(results.getResultString());
			mResultText.append(text);
			mResultText.setSelection(mResultText.length());
			if(isLast) {
				//TODO 最後的結果
			}
		}

		@Override
		public void onVolumeChanged(int volume) {
			showTip("當前正在說話,音量大小:" + volume);
		}

		@Override
		public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
		}
	};
調用:
mVoice.startListening(voiceListener);


語音合成:

將文字轉換成語音讀出來。

使用方法和上面的語音識別大同小異,大家可以看代碼,這裡我就不浪費大家時間了。

在設置參數時可以選擇說話人性別,而且還可以選擇方言。

我之前用方言合成了點罵人的話聽著特搞siao。。。

PS:我只是非常簡單的介紹一下,如果大家真要使用建議示例代碼配合文檔(下載的壓縮包中可以找到)好好研究一下。



Unity中使用Android語音服務:

上面簡單介紹了如何使用這個語音服務,現在的問題是如何在Unity中調用這個服務。

思路就是將Android項目整體當成一個包/服務/插件,放入Unity的項目中,這樣我們就可以在Unity中調用Android的方法。

說到這裡就需要了解一下Unity和Android項目結合的知識,相關內容都在我之前寫的一個文章:

ANDROID應用中嵌入Unity3D視圖(展示3D模型)



Android端代碼:

我們需要做的就是讓Android的activity都繼承自UnityPlayerActivity。

下面我把Android端的代碼貼出來,結合上面介紹的內容相信大家一看就懂:

public class MainActivity extends UnityPlayerActivity {
	// 四個按鈕
	private Button voiceButton;
	private Button detailButton;
	private Button returnButton;
	private Button quitButton;
	
	private Map mapAllNameID;
	boolean isFaild = false;
	
	// 語音結果
	String voiceResult = null;
	// 所有的市
	private String[] strNamePro;
	// 所有的城市
	private String[][] strNameCity;
	// 語音聽寫對象
	private SpeechRecognizer mVoice;
	// 語音合成對象
	private SpeechSynthesizer mTts;
	// 默認發音人
	private String voicer = "xiaoyan";
	// 引擎類型
	private String mEngineType = SpeechConstant.TYPE_CLOUD;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test);

		View playerView = mUnityPlayer.getView();
		LinearLayout ll = (LinearLayout) findViewById(R.id.unity_layout);
		ll.addView(playerView);

		SpeechUtility.createUtility(this, SpeechConstant.APPID + "=540dcea0");
		// 初始化識別對象
		mVoice = SpeechRecognizer.createRecognizer(this, mInitListener);
		// 初始化合成對象
		mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener);

		voiceButton = (Button) findViewById(R.id.voice_btn);
		voiceButton.setOnClickListener(new voiceListener());

		returnButton = (Button) findViewById(R.id.return_btn);
		returnButton.setOnClickListener(new returnListener());

		detailButton = (Button) findViewById(R.id.detail_btn);
		detailButton.setOnClickListener(new detailListener());

		quitButton = (Button) findViewById(R.id.quit_btn);
		quitButton.setOnClickListener(new quitListener());
		initVar();
	}

	public class voiceListener implements OnClickListener {
		@Override
		public void onClick(View arg0) {
			voiceResult = "";
			// 設置參數
			setParam();
			mVoice.startListening(voiceListener);
		}
	}

	public class returnListener implements OnClickListener {
		@Override
		public void onClick(View arg0) {
			UnityPlayer.UnitySendMessage("Main Camera", "back", "");
		}
	}

	public class detailListener implements OnClickListener {
		@Override
		public void onClick(View arg0) {
			UnityPlayer.UnitySendMessage("Main Camera", "detail", "");
		}
	}

	public class quitListener implements OnClickListener {
		@Override
		public void onClick(View arg0) {
			System.exit(0);
		}
	}

	public void quitApp(String str) {
		Toast.makeText(getApplicationContext(), "退出", Toast.LENGTH_SHORT).show();
		System.exit(0);
	}

	private RecognizerListener voiceListener = new RecognizerListener() {
		@Override
		public void onBeginOfSpeech() {
			Toast.makeText(getApplicationContext(), "開始說話", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onError(SpeechError error) {
			Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onEndOfSpeech() {
			Toast.makeText(getApplicationContext(), "結束說話", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onResult(RecognizerResult results, boolean isLast) {
			voiceResult = voiceResult + JsonParser.parseIatResult(results.getResultString());
			if (isLast) {
				setSpeakParam();
				mTts.startSpeaking(checkResult(voiceResult), mTtsListener);
				// UnityPlayer.UnitySendMessage("Main Camera","voice",getResults(voiceResult));
			}
		}

		@Override
		public void onVolumeChanged(int volume) {
			// Toast.makeText(getApplicationContext(), "當前正在說話,音量大小:" + volume, Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
		}
	};

	/**
	 * 合成回調監聽。
	 */
	private SynthesizerListener mTtsListener = new SynthesizerListener() {
		@Override
		public void onSpeakBegin() {

		}

		@Override
		public void onSpeakPaused() {

		}

		@Override
		public void onSpeakResumed() {

		}

		@Override
		public void onBufferProgress(int percent, int beginPos, int endPos, String info) {
		}

		@Override
		public void onSpeakProgress(int percent, int beginPos, int endPos) {

		}

		@Override
		public void onCompleted(SpeechError error) {
			if (error == null) {
				if (!isFaild) {
					// 向Unity發送語音得到結果
					UnityPlayer.UnitySendMessage("Main Camera", "voice", voiceResult);
				}
			} else if (error != null) {
				Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
			}
		}

		@Override
		public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {

		}
	};

	// 設置語音識別的參數
	public void setParam() {
		// 設置語言
		mVoice.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
		// 設置語言區域
		mVoice.setParameter(SpeechConstant.ACCENT, "mandarin");
		// 設置語音前端點
		mVoice.setParameter(SpeechConstant.VAD_BOS, "4000");
		// 設置語音後端點
		mVoice.setParameter(SpeechConstant.VAD_EOS, "1000");
		// 設置標點符號
		mVoice.setParameter(SpeechConstant.ASR_PTT, "0");
		// 設置音頻保存路徑
		mVoice.setParameter(SpeechConstant.ASR_AUDIO_PATH, "/sdcard/iflytek/wavaudio.pcm");
	}
	
	// 設置語音合成參數
	private void setSpeakParam() {
		// 設置合成
		if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
			mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
			// 設置發音人
			mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
		} else {
			mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
			// 設置發音人 voicer為空默認通過語音+界面指定發音人。
			mTts.setParameter(SpeechConstant.VOICE_NAME, "");
		}
		// 設置語速
		mTts.setParameter(SpeechConstant.SPEED, "50");
		// 設置音調
		mTts.setParameter(SpeechConstant.PITCH, "50");
		// 設置音量
		mTts.setParameter(SpeechConstant.VOLUME, "50");
		// 設置播放器音頻流類型
		mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
	}
	
	/**
	 * 初始化監聽器。
	 */
	private InitListener mInitListener = new InitListener() {

		@Override
		public void onInit(int code) {
			if (code != ErrorCode.SUCCESS) {
				Toast.makeText(getApplicationContext(), "初始化失敗,錯誤碼:" + code, Toast.LENGTH_SHORT).show();
			}
		}
	};

	/**
	 * 初期化監聽。
	 */
	private InitListener mTtsInitListener = new InitListener() {
		@Override
		public void onInit(int code) {

			if (code != ErrorCode.SUCCESS) {
				Toast.makeText(getApplicationContext(), "初始化失敗,錯誤碼:" + code, Toast.LENGTH_SHORT).show();
			}
		}
	};
}


上面並不是全部的代碼,Android端的全部代碼我已經上傳到GitHub:

https://github.com/a396901990/3D_Sphere/tree/feature/Voice_Weather_3D_Sphere

項目中3DVoiceWeather文件就是Android項目,大家可以導入到Eclipse中查看。


上面代碼已經是完整代碼了,按照網上教程中的方法,將Android項目以插件的形式放入Unity中,最後在Unity中build成apk就可以在手機中使用了。

如何使用語音控制3D球旋轉我會在最後一篇文章中介紹。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved