文章

顯示從 2019 起發佈的文章

[應用] 以 RESTful API 通訊的雲端語音合成 (Text To Speech) in C++ 開發

圖片
語音合成介紹         最近在研究語音合成技術,各家的平台大都以雲端的語音合成為主,少數還提供離線的語音合成。本文找了三家 (阿里 、百度 、同花順 ) 提供語音合成的平台,平台會提供各類開發的 SDK 和 RESTful API 兩種接口,其中它的SDK 就是根據自己使用的程式語言調用SDK的接口,例如在之前 「 中文語音合成+語音辨識 以百度的AI開放平台 in Python 開發   」 一文中我們用 Python 語法調用它的 SDK 函數。 設計方式         另一種開發的接口是 RESTful API,這是一種通用的網路通訊接口。它的通訊方式是靠 HTTP 的 GET 、 POST...的協定上傳文本和語音合成的參數,經過雲端系統的運算後,再回傳音檔給開發者。開發 RESTful API in C++ 過程需要先整合 curl 和 json 兩個開源代碼,如下圖所示。因為要 HTTP 網路上傳到雲端,我們必須在這些平台上註冊自己的帳號,使用語音合成的過程需要經過用戶認證。認證後,每個平台上傳文本的步驟與細節有些許不同,請參考各家的說明。         最後,將三家平台整合成一個小的測試工具,如下圖一~圖三所示。圖一是阿里雲的平台與參數,圖二是百度平台的參數,圖三是同花順的平台與參數。該工具使用的過程記錄成影片,如下。未來隨著行動網路越來越快,雲端計算的應用也會越來越多且複雜,語音和影像處理的應用會更多。 圖一:阿里雲的語音合成之參數表 圖二:百度的語音合成之參數表 圖三:同花順的語音合成之參數表 實現展示 影片: 實際操作的過程

[應用] 以 STM32 晶片的 ADC 為基礎, 設計一個簡易示波器

圖片
目的         以 ADC 模組為基礎,設計一個簡易示波器觀察訊號變化,同時能記錄每筆資料以便數值分析。 設計         使用 STM32 系列晶片內的 ADC 模組,將類比訊號轉換成數位資料,然後將整筆數據從網路傳送到 PC 端,再由 PC 程式接收後繪製成曲線圖。開發過程,利用前面一文 「 以 STM32 晶片的 DAC 為架構設計一個訊號產生器 」 所產生的方波當做待測訊號源,此訊號源輸入到 ADC 接腳,如下圖一所示。 圖一:設計完整示波器的方塊圖 STM32F207        下圖是程式碼設定 ADC 的參數,第一個要先設定 ADC 取樣率的刻度,再來設定取樣率,如下面紅線標示。取樣率跟晶片的 operating clock 有關,從系統的高速時脈降頻到 ADC 的取樣率。第二個是選定 ADC 轉換資料的精密度,精密度越高,資料量則越大。最後,設定 ADC 轉換完畢後產生中斷通知 CPU,每次 ADC 轉換資料後,中斷的 IRQ 便會把數值從暫存器搬到記憶體裡。在設計裡,我們宣告兩塊 buffer 存放數值。 圖二:ADC 參數設定         下圖是在 PC 端寫一個網路接收資料的程式,並把資料繪製成曲線圖。當 ADC 取樣率為 15.2KHz時,從PC端看到的圖形比較像弦波,當我把 ADC 取樣率提高為 48KHz 時,PC端看到的圖形就像一個方波了。不過,取樣率高低對設計來說是一項架構問題,取樣率越高,代表資料量越高,傳輸速率越大,所需要的網路頻寬要夠,還要晶片的CPU有足夠的效能才行。 圖三-1:ADC 取樣率 15.2K 所顯示的方波 圖三-2:ADC 取樣率為 48K 所顯示的方波 問題         DMA資料搬運過程不穩定,當取樣率越高的時候,DMA搬運出現資料錯亂的情況。將這個問題放到 StackOverflow 網站尋求解答,連結如下「 ADC 與 DMA 資料搬運的問題 」。所以,在上面的測試過程,我們都採用 ADC 中斷的方式搬運資料到記憶體,而不是 DMA。 影片: [單晶片應用] 利用控制板設計一個簡單的示波器

[應用] 以 STM32 晶片的 DAC 為架構設計一個訊號產生器

圖片
目的:產生方波或正弦波的訊號 設計:以 STM32 系列內建的 DAC 模組為架構,搭配內部的 Timer 當做取樣率,讓 DAC 輸出週期性訊號。         我們設計訊號產生器靠 DAC 模組將數值轉換成類比訊號,接著產生一個週期性訊號需要使用 Timer,利用它產生的 event 通知我們產生一個訊號數值,簡單說就是一個取樣點,而取樣率就是 Timer 的參數設置。這裡會有個效能的問題,如果取樣速率越高,那麼系統核心每次要 DAC 轉換數值的頻率就會增加,這會占用到系統 CPU 的運算時間。因此,DAC 需要配合 DMA 模組以達到系統效能。         圖一所示為上述三個模組的運作流程圖,第一步 Timer 產生取樣點的事件,驅動第二步的 DAC 模組,因為設定 DAC 與 DMA 搭配合作,第三步 DAC 會對 DMA 發出一個請求,要求 DMA 將波形訊號數值搬到 DAC 暫存器裡面,最後 DMA 執行這個請求。 圖一:STM32 DAC 運作的流程圖         圖二和圖三所示為程式碼的說明,首先要宣告一塊記憶體存放波形資料,這陣列代表一個波形的完整週期。接著,我們要初始化 Timer 、 DAC 、 DMA 模組,Timer 設定取樣率,DMA 和 DAC 要設定資料搬運的位址與長度。設計到這裡,比較困難的地方在怎麼計算適當的取樣率,它會影響到波形的週期大小。我們以 STM32F207 晶片為例,Timer 模組的 clock 是 60MHz,當 TIM_Period 設定為 500 時,每個取樣點產生的頻率為 120KHz = 60MHz/500,再來看一個完整波形的週期需要 30 個取樣點,所以這個波形頻率為 4KHz = 120KHz/30,其週期為 250us 。程式在 STM32F207 板卡上運行的結果顯示在最後一張圖。 圖二:波形資料的定義 圖三:每個模組參數的初始化

[概念] 兩個程序以 IPC 方式建立一個能互相通訊的共享空間

圖片
        在同一Windows系統內的兩個程序要互傳資料,可以用建立內部 TCP 連線方式傳送,不過這種方式不適合大量資料的存取。還有一種方式稱為 IPC (Inter Process Communication),兩個程序之間建立一個共享的空間,透過這塊空間互傳資料互相通訊,參考[1],我們可以把這塊空間看成是一個虛擬檔案,類似開啟檔案的步驟來讀寫它。         首先,雙方有一方要建立共享空間,另一方則是開啟共享空間,如下圖一所示。建立的這方要對這塊空間命名,如果沒有命名,另一方就無法開啟正確的空間。如果我們建立一個很大的空間時,要先讀取目前系統的 available page file 還剩多少,如果不足,那就要加大系統的記憶體容量,參考[2]。當雙方能成功取得這塊共享空間的控制權後,這樣才能利用 MapViewOfFile 函數獲得位址,要留意的一點是位址的 alignment,這塊空間並不是想要指定 到某一位址就能任一指定,它有限制位址必須對齊系統的 AllocationGranularity,所以在規劃空間內部的資料結構時就要先設計安排妥當。         接著,因為存取資料是一個共享空間,所以我們要設計一個互斥鎖保護資料,避免雙方同時存取同一位址而產生資料錯亂,如下圖所示,同樣地建立的互斥鎖也要命名。最後,建立一個事件通知也是需要的,總不能雙方都要輪詢方式來查看資料有沒有更新吧? 當一方寫完資料後,發個事件通知告訴對方,再由對方來讀取,這樣效率會比較好。 圖一:IPC 操作所調用的相關API 參考資料 [1]  Interprocess Communication Between 32-bit and 64-bit Applications [2]  Creating Named Shared Memory

[筆記] Visual Studio 遠端偵錯的設定步驟

圖片
        通常我們用微軟Visual Studio IDE開發程式並且在本機上運行與除錯,但隨著開發系統越來越複雜,程式運行在某台服務器上而不是自己的機器,這時候需要進行遠端程式的除錯,架構如下圖一所示。自己的主機要安裝微軟的Visual Studio 2017 IDE,待測的機器上面要有Remote Debugger工具,雙方透過網路的連線進行除錯。 圖一:遠端除錯與待測機器 [步驟]: 1) 在自己主機上的Visual Studio目錄下面找Remote Debugger這個工具目錄,然後把Remote Debugger工具複製到待測機器上。 2) 程式的除錯屬性要設定正確,屬性頁的遠端Windows偵測工具,如下圖二所示。我們必須設定遠端命令 、 工作目錄 、 遠端機器IP 、連接是否驗證...等等,連線的權限要配合遠端機器的設定。 3) 在遠端機器上的Remote Debugger目錄,開啟 msvsmon.exe,這時只要到工具選單設定連線的權限,如下圖三所示。圖中是設為無權限的方式,不需要驗證使用者。 4) 在VS IDE環境運行遠端Windows偵錯工具,如果發現遠端機器上出現錯誤,錯誤的原因是缺少某些 dll 檔案,如:msvcp140D.dll 、ucrtbased.dll... 。我們在本地主機上找找看這些缺少的檔案,應該能找到,然後再複製到遠端機器的 \Windows\System32 目錄底下。 5) 最後,編譯我們的程式後,要再把exe 、 pdb檔案複製到遠端機器的工作目錄上。接著,運行我們的程式遠端 debug,這樣就可以一步步看著遠端機器上的程式怎麼執行了。 C++遠程偵錯 圖二:C++程式的遠端屬性設定 圖三:遠端機器的連線權限設定 C#遠程偵錯 圖四:C# 程式的遠端偵錯設定