簡 介: 本文測試了將AZure的文本生成的語音信號分割成不同的片段,適合進行視頻的后期配音。分割利用了每一段語音之間的 0.5 秒中的間隔,這樣可以將每一段的語音對應的分割出來。
**關鍵詞**: AZure
??如下是Azure網站提供的文字轉換成語音的界面。文本轉語音[1]

??TEASOFT語音配音的轉換布置:
??利用BSIRFORM上的 “Action” 按鈕生成視頻配音文字。具體操作:alt+點擊Action 。

??TEASOFT 生成文字時,每一個Action中的文字形成一行。并對每一行進行如下的處理:
??下面是轉化后的文字樣本。
今天在Youtube上,
看到一位Up主介紹了波形折疊電路,
并展示了它應用在電子音樂信號處理方面,
那么什么是波形折疊?
如何利用電路來實現呢?
首先討論一下什么是波形折疊?
以這三個波形為例進行說明,
對于三角信號波形,
如果它的幅值超過一個閾值,
上面的波形則鏡像折疊到閾值下面,
這就是波形折疊,
對于鋸齒信號波形,
同樣,
進行折疊之后,它變成了三角波,
對于方波信號,
信號折疊之后,
波形仍然是方波,
只是幅值下降,
波形沒有變化,
下面,
如何利用電路來實現呢?
視頻中給出了從簡單到復雜的實現方法,
下面對此進行測試一下,
下面搭建單管折疊電路,
總共有三個器件,
這是電路原理圖,NPN三極管使用8050.
從MSO24的信號源輸出500Hz,
峰峰值為5V的三角波,
藍色波形是輸出的波形,
這是讀入內存后的波形數據,
下面測量PNP折疊電路,
這是電路輸出波形,
從MSO24讀取的波形數據,
將上面兩個電路并聯在一起,形成雙邊這點電路,
這對峰峰值為1V的三角波處理結果,
調整不同幅值,
可以看到折疊信號始終維持在正負0.25V之內,
本文討論了波形折疊電路,
根據Youtube上的UP主介紹的簡單點路,
搭建了基于三極管的波形折疊電路,
驗證了相關電路的工作原理,
??進入 AZure 文本轉語音界面。文本轉語音[2] : https://azure.microsoft.com/zh-cn/products/cognitive-services/text-to-speech/#overview

??將上述文字拷貝到界面中的對話框內。選擇合適的語言,語音,說話風格以及角色扮演等。

??使用 Audacity軟件進行錄制語音合成結果,并存儲到 .WAV 文件。
三、語音分割
??分割每個語音利用了每一段之間存在 0.5秒的時間間隔。搜尋語音文件中所有長度大于等于 0.5 秒的時間間隔,將對應的數據存儲在各自的語音文件中。

??根據 ?電話雙音頻撥碼信號采集[2] 所采用的 Python 對于語音處理的相關算法,進行上述合成語音的分割。
??讀取語音波形文件,獲得相應的參數和數據。
from?headm?import?*
from?scipy.io?import?wavfile
wavefile?=?r'D:\Temp\11.wav'
sample_rate,?sig?=?wavfile.read(wavefile)
printf(sample_rate,?shape(sig))
??保存的語音文件的采樣率為 44100Hz,通過數量長度除以采樣率,可以知道語音文件時間長度為 115.8s 。
44100 (5107840, 2)
??繪制其中一個聲道的數據波形如下:

??對于上述錄制的音頻文件波形進行分析,獲得語音分割參數:
? ● ?語音分割參數:
???靜音幅值:±25,這個數值最終定位50
???靜音時間長度:0.5s

#!/usr/local/bin/python
#?-*-?coding:?gbk?-*-
#******************************
#?SPS.PY???????????????????????--?by?Dr.?ZhuoQing?2022-10-03
#???Seperate?speak?signal?into?segment.
#???Usage:??sps?wavefile?silencevalue(int)?silencetime(float)
#
#???Before?using?sps,?copy?all?voice?string?into?clipboard.
#
#?Note:
#******************************
from?headm?import?*
from?scipy.io?import?wavfile
from?pydub?import?AudioSegment
wavefile?=?r'D:\Temp\11.wav'
#------------------------------------------------------------
try:
????if?not?os.path.exists(r'd:\temp'):
????????os.makedirs(r'd:\temp')
????if?not?os.path.exists(r'd:\temp\VOICE'):
????????os.makedirs(r'd:\temp\VOICE')
except?OSError:
????printf("Error?:Creating?directory?of?data.")
#------------------------------------------------------------
silencevalue?=?25???????????????????#?Silence?max?value
silencetime??=?0.5??????????????????#
mp3flag?=?0
#------------------------------------------------------------
strall?=?[s.strip('\r')?for?s?in?clipboard.paste().split('\n')?if?len(s)?>?0]
for?s?in?sys.argv:
????fname?=?os.path.join(r'd:\temp',?'%s.WAV'%s)
????if?os.path.isfile(fname):
????????wavefile?=?fname
????????continue
????fname?=?os.path.join(r'd:\temp',?'%s.MP3'%s)
????if?os.path.isfile(fname):
????????wavefile?=?fname
????????mp3flag?=?1
????????continue
????if?s.isdigit():
????????silcencevalue?=?int(s)
????????if?silencevalue?>?1000:
????????????silencevalue?=?1000
????????continue
????if?s.replace('.',?'').isdigit():
????????silcentime?=?float(s)
printff(wavefile,?silencevalue,?silencetime)
#------------------------------------------------------------
if?mp3flag?==?0:
????sample_rate,?sig?=?wavfile.read(wavefile)
????sigdata?=?array(sig[:,0])
else:
????sample_rate?=?44100
????sound?=?AudioSegment.from_file(file=wavefile)
????left?=?sound.split_to_mono()[0]
????sig?=?frombuffer(left._data,?int16)
????sigdata?=?array(sig)
#------------------------------------------------------------
sigdata[(sigdata?>?-silencevalue)?&?(sigdata?0
sigdata[(sigdata?<=?-silencevalue)?|?(sigdata?>=?silencevalue)]?=?1
sigone?=?where(sigdata?==?1)[0]
sigdelta?=?array([x2-x1?for?x1,x2?in?zip(sigone[0:-1],?sigone[1:])])
deltamin?=?int(sample_rate*silencetime)
sigmax?=?where(sigdelta?>?deltamin)[0]
sigsegment?=[sigone[0]]
for?sm?in?sigmax:
????sigsegment.append(sigone[sm+1])
sigsegment.append(sigone[-1])
#------------------------------------------------------------
printff('Voice?Segment:%d'%len(sigsegment),?'Voice?String:%d'%len(strall))
printf('\a')
if?len(sigsegment)?-?len(strall)?!=?1:
????printf("Voice?String?Number?error?!\a")
????exit()
#------------------------------------------------------------
for?i?in?range(len(sigsegment)?-?1):
????startid?=?sigsegment[i]
????endid?=?sigsegment[i+1]?-?sample_rate*3//4
????wavefilename?=?'%04d.wav'%i
????if?i?????????sa?=?strall[i].replace(',',?'').replace(',','').replace('.','').replace('。',?'').replace(';','')
????????wavefilename?=?'%s.wav'%sa
????outfile?=?os.path.join(r'd:\temp\VOICE',?wavefilename)
????if?mp3flag?==?0:
????????wavfile.write(outfile,?sample_rate,?sig[startid:endid,?:])
????else:?wavfile.write(outfile,?sample_rate,?sig[startid:endid])
????printf(outfile)
tspbeep(1800,?100)
#------------------------------------------------------------
#????????END?OF?FILE?:?SPS.PY
#******************************
??在 sps 命令后面可以添加 wave 文件, 靜音幅度, 靜音時間等參數。需要注意的是, 在使用 sps 之前,需要將聲音的文本拷貝到剪切板中。
??分割后的文件存儲在 d:\temp\VOICE 目錄中。
??對于上述程序進行了測試,它準確的將所有的語音進行了分割。

??本文測試了將AZure的文本生成的語音信號分割成不同的片段,適合進行視頻的后期配音。分割利用了每一段語音之間的 0.5 秒中的間隔,這樣可以將每一段的語音對應的分割出來。
下面是利用AZure配音的短片:
文本轉語音: https://azure.microsoft.com/zh-cn/products/cognitive-services/text-to-speech/#overview
[2]電話雙音頻撥碼信號采集: https://blog.csdn.net/zhuoqingjoking97298/article/details/122606221?spm=1001.2014.3001.5501