前要
20200229 本文後續提供的是不完整的,僅提供matlab窗口程序編寫參考,由於是採用將音進行切分的,存在音損等,因此調整的效果還是比較機械的,無法提供正常編譯,matlab生成的文件沒有在其他乾淨的電腦上面具體操作使用,因此,可執行文件在缺少JRE設置或者JRE版本不一致,以及缺少matlab必要的dll將無法運行。
1.由於時間間隔比較久,有些需要根據需求更改的代碼部分後期在指出
2.其中使用的STRAIGHT我記得以前我忘記去那裏要了最新的,然後不會用,使用的是學姐當初給我的。這個是日本的,他們網站有提供學術的申請和商業合作之類的聯繫方式。這裏我將不會提供這個代碼。具體用到的代碼地方,後續有空再指出
遲到的致謝
由於其他部分涉及真名,我就只截圖了後半部分
工具環境
xjytool -將提供
voicebox--將提供該第三方庫
STRAIGHT --不提供
miditoolbox11-將提供該第三方庫
提供的代碼部分鏈接:
https://download.csdn.net/download/u014646950/12203343
界面展示
文件目錄分佈
代碼部分以及說明
在matlab上進行編譯的編譯命令行文件,matlab在目錄下可直接通過文件名調用編譯(由於當前不提供STRAIGHT因此無法正常編譯)。
類似C程序的編譯工具gcc,該命令中的 .m 文件之直接調用的,界面設計時lrcxjy.m,lrcxjy_activex3是播放控件窗口,由於不知道怎麼刪掉2那個,因此在調整過程中直接使用了3。
%% win7 下編譯 matlabR2014a lrcmcc.m
%待黑框測試編譯是否正確
%{
mcc -m lrcxjy.m mdlMStrToNMat.m writeNMatToSmf.m mdlMidiToMStr.m ...
onset.m dur.m midi2hz.m velocity.m pitch.m UI_lrcChangeMelodies.m ...
lrcvadini_vow.m vadsohn.m estnoiseg.m estnoisem.m enframe.m rfft.m ...
lrcttsV3.m ...
-a lrcxjy_activex3
%}
%不帶黑框最終版本生成
mcc -e lrcxjy.m mdlMStrToNMat.m writeNMatToSmf.m mdlMidiToMStr.m ...
onset.m dur.m midi2hz.m velocity.m pitch.m UI_lrcChangeMelodies.m ...
lrcvadini_vow.m vadsohn.m estnoiseg.m estnoisem.m enframe.m rfft.m ...
lrcttsV3.m ...
-a lrcxjy_activex3 -o lrcxjywinMain
STRAIGHT --不提供-日本的合成技術-應用到文件
(lrcsingvad1.m 提取特徵值再切分的方法用到
UI_lrcChangeMelodies.m
1.)提取特徵值uiexfeature(x,fs)用到
prm.F0frameUpdateInterval=10;
prm.spectralUpdateInterval=10;
%%清音非週期
%ap=exstraightAPind(x,fs,rf0,prm);%optionalParams
%包絡envelope
sp=exstraightspec(x,rf0,fs,prm);%optionalParamsSP
2.)合成用到
prm.F0frameUpdateInterval=fvow;
prm.spectralUpdateInterval=fvow;
sy =exstraightsynth(rf0,sp(:,vowindex:end),ap(:,vowindex:end),fs,prm);
20200321
--loading 部分主要代碼片段後期在本文中新增-基本在提供資源地址中
20200429 懶癌-說一遍,資源 全在鏈接裏面了,但是由於下載需要積分啦,所以我會選擇把自認爲不錯的代碼弄到這裏<每個編程的人都會寫過自認爲不錯的代碼,直到遇到另一座山>。不定期更新吧,今天打開了就先說明一下,根據博文中的截面圖,可以直觀的看到我調用了那個音頻播放的,還有那個加載百分比的窗口,而且還加了個小圖標,調用通過api到百度請求的tts ,本機微軟的。還有告警的。目前想到的就是這些。還有那個MIDI調用的單道製作。xjytool裏面還有繪製腳本。這可能是我用到matlab的和MATLAB的知識的巔峯時代.<現在忘得差不多了>當初寫那些代碼異常考慮還有拋異常打印還是挺不錯的。
先這個可以繪製譜圖的,稍微知道一下matlab的%是註釋就可以,拿到特徵值就可以使用了,這裏面是用STRAIGHT得到的特徵值sp,如果有其他方法得到的,也可以扔進去看一下的。
function lrcplotsp(sp,choice)
%根據STRAIGHT提取的sp繪圖 lrcplotsp(sp,choice)
%輸入
% sp STRAIGHT提取的sp
% choice 選擇繪圖模式有 立方面 平面語譜 平面線
%輸出
% 圖形或沒有(sp爲空)
%使用方法
% lrcplotsp(sp);
% lrcplotsp(sp,'立體面');
% lrcplotsp(sp,'立體面平面語譜');
% lrcplotsp(sp,'平面線平面語譜');
%備註使用函數簡單範例
% image(C)默認不縮比,可以設置根據矩陣數據繪圖或縮比-矩陣(N*M或者是RGB的N*M*3)
% 浮點顏色範圍0~1,整型u8.0-255/u1.0-65535,像素佔面積[0.5 N+0.5 0.5 M+0.5]。
% imagesc(C)縮比,調用colormap('jet')、image(varargin{1},'CDataMapping','scaled');;
% 縮比使得數據【零,最高】在範圍[0,1]或[0,255]或[0,65535]內
%places the center of element C(1,1) at (1,1) in the axes,
% and the center of element (M,N) at (M,N) in the axes, and draws
% each rectilinear patch as 1 unit in width and height. As a
% result, the outer extent of the image occupies
% of the axes, and each pixel center of the image lies at integer
% coordinates ranging between 1 and M or N.
%
%code by Xu__Jiayu 20170401
plot_way='立體面 平面語譜 平面線';
if nargin>0
if(nargin>1&&~isempty(choice))
plot_way=choice;
end
i=3-isempty(strfind(plot_way,'立體面'))-...
isempty(strfind(plot_way,'平面語譜'))-...
isempty(strfind(plot_way,'平面線'));
loc=0;
if i>0
figure
end
if strfind(plot_way,'立體面')
loc=loc+1;
subplot(i,2,loc);
surf(1:size(sp,2),1:size(sp,1),sp);
colorbar
xlabel('時間/幀');
ylabel('頻率/Hz');
zlabel('幅值');
loc=loc+1;
subplot(i,2,loc);
mesh(1:size(sp,2),1:size(sp,1),sp);
colorbar
xlabel('時間/幀');
ylabel('頻率/Hz');
zlabel('幅值');
end
if strfind(plot_way,'平面語譜')
loc=loc+1;
subplot(i,2,loc);
image(sp);%根據原數據繪圖
colorbar
title('原數據繪圖');
xlabel('時間/幀');
ylabel('頻率/Hz');
loc=loc+1;
subplot(i,2,loc);
imagesc(sp);%數值最大最小分別爲像素範圍
colorbar
title('數值最大最小爲像素範圍');
xlabel('時間/幀');
ylabel('頻率/Hz');
end
if strfind(plot_way,'平面線')
loc=loc+1;
subplot(i,2,loc);
plot(sp);
xlabel('頻率/Hz');
ylabel('幅值');
loc=loc+1;
subplot(i,2,loc);
plot(sp');
xlabel('時間/幀');
ylabel('幅值');
end
else
disp('sp爲空,請重新輸入');
end
end
找了一下存檔,平面語譜圖樣例如下,我是在前期通過兩個對比給老師可是化的看得,這個圖是兩個和繪製在一起的
文語轉換的調用,先來一個聯網的版本,要長期用的自己到百度的雲平臺申請一下,替換一下其中的關鍵字,去年(2019)我還使用過是可以用的,但是代碼中的是我賬號使用的key呢,這裏面涉及的三個在前面替換即可,代碼其實很短,後面%{到%}是我在嘗試中使用修改的歷史記錄,供需要研究的參考。如果解析什麼的異常,可以聯繫或閱讀百度雲平臺,他們格式更改的話就要去修改。
function [y,fs2] = lrcttsV3(words,choice)
%lrxtts
%文語轉換,需要聯網使用,畢設中採用16000Hz,choice可使用0爲女聲,1爲男聲,3爲情感合成-度逍遙,4爲情感合成-度丫丫
%輸入
% words 字符串'待轉換字'
% support by 百度REST API
%註釋:代碼中用於獲取tok利用我在百度語音申請的api key和secret key。時間就了百度改版或我取消應用將不能使用過
%designed by Xu__Jiayu
%%
%0爲女聲,1爲男聲,3爲情感合成-度逍遙,4爲情感合成-度丫丫
%默認參數
y=[];
words2=[];
%fs2=16000;%百度目前提供的只有16000Hz和8000Hz --20170406
girl=0;%根據百度rest設置
%khz='k44';
%%
%輸入參數重置
if nargin>0
words2=words;
end
%{
if nargin>1&&~isempty(fs)&&ismember(fs,[8000 16000]);
fs2=fs;
%khz=sprintf('k%i',fix(fs/1000)); ismember(fs,[11025 12000 16000 22050 24000 32000 44100 48000]);
end
%}
if nargin>1&&~isempty(choice)&&ismember(choice,[1,3,4]);
girl=choice;
end
%%
[tokt,stat]=gettok;
if 1==stat
tok=tokt;
else
tok='24.a702efee9c534e4cad0723332a6d76ed.2592000.1493996778.282335-9481503';
end
%http://tsn.baidu.com/text2audio?tok=24.a702efee9c534e4cad0723332a6d76ed.2592000.1493996778.282335-9481503&tex=清&lan=zh&cuid=AC-16-2D-52-3A-27&ctp=1&
[filepath,status]=getfile(words2,girl,tok);
if status
[y,fs2]=lrcreadwav(filepath);
end
%{
[vadgate,~]=vadsohn(y3,fs2);
index=find(vadgate);%有生部分
x= y3(index(1):index(end),1); % Make sure it is a comum vector.取單聲道
%}
%sound(x,fs2); % Playback sound播放
%%
%out
end
function [filepath,status]=getfile(words2,girl,tok)
URL='http://tsn.baidu.com/text2audio';
Name='get';
Value={
'tex',char(java.net.URLEncoder.encode(words2,'UTF-8')),...
'lan','zh',...
'cuid','AC-16-2D-52-3A-27',...
'ctp','1',...
'tok',tok,...
'spd','5',...%語速0-9
'pit','7',...%音調0-9
'vol','9',...%音量0-9
'per',num2str(girl)};%角色0,1,3,4
[filepath,status] = urlwrite(URL,'UI.mp3',Name,Value);
if(isempty(filepath)||0==status)
disp('請求音頻失敗');
err= MException('MATLAB:rmpath:DirNotFound','%s沒聯網','lrcttsV3.m');
throw(err);
else
status=1;
disp('請求成功');
end
end
function [tok,stat]=gettok
%get tok
%聯繫百度帳號 xujiayuxjy
%App ID: 9481503
%API Key: OWhu33XDY3iBKhPrwBiq8sro
%Secret Key: fe8c59147f5a1fde9a8067b6fde07db7
%利用post請求方式,獲取百度自己內置的access_token。
%這個一段時間access_token百度內部數據庫就會更新。因此採用隨用隨獲取。如果要更細緻減少使用許另外設置參數判斷是否更新
%via by Xu__Jiayu
tok=[];
stat=0;
URL='https://openapi.baidu.com/oauth/2.0/token';
Name='post';%請求數據不在url出的post請求方法
requestHead={'grant_type','client_credentials',...
'client_id','OWhu33XDY3iBKhPrwBiq8sro',...
'client_secret','fe8c59147f5a1fde9a8067b6fde07db7'};
[tok,status]= urlread(URL,Name,requestHead);
if(1==status)
if isempty(strfind(tok,'access_token'))
disp('請求成功,但是沒有獲取到tok');
else
stat=1;
index=strfind(tok,'"');
if length(index)>3
tok=tok(index(3)+1:index(4)-1);%根據當前百度設置的json格式,簡單獲取需要的tok
end
end
else
disp('請求失敗');
end
end
%%
%編寫試驗代碼中使用過的函數
%[status,cmdout] = dos('getmac');
%currentCharacterEncoding = slCharacterEncoding()
%[str,status]= urlread(URL,Name,Value);
%[f,status] = urlwrite(url,filename,varargin)
%bytes=unicode2native(words2, 'UTF-8');%由獲得utf-8的字節編碼
%words=dec2hex(bytes);
%words=native2unicode(bytes, 'UTF-8');
%urlencode(urlIn)
%d = hex2dec()
%fid=fopen('p.mp3','wb');
%fprintf(fid,'%c',str-0);
%fclose(fid);
%bytes=unicode2native(str,'UTF-8');%由獲得utf-8的字節編碼
%{
Value={
'tex',urlencode(words2),...
'lan','zh',...
'cuid','AC-16-2D-52-3A-27',...
'ctp','1',...
'tok',tok,...
'spd','4',...%語速0-9
'pit','5',...%音調0-9
'vol','9',...%音量0-9
'per',num2str(girl)};%角色0,1,3,4
edit urlencode
java.net.URLEncoder.encode('好','UTF-8')
ans =
%E5%A5%BD
get(ans)
Bytes: [9x1 int8]
Class: [1x1 java.lang.Class]
Empty: 0
get(ans,'Bytes')
%}
我們用window電腦,基本也是有內置文語轉換的,強大的電腦,大家也就沖沖浪,浪費很多,我也是搜索之類的還是隨便使用matlab幫助找到的,3年之久有點忘記了。
function [y,fs2] = lrctts(words,fs)
%lrxtts 文語轉換
%輸入
% words 字符串'待轉換字'
% fs 採樣頻率,默認44100Hz
%%
%默認參數
y=[];
words2=[];
fs2=44100;
%khz='k44';
%%
%輸入參數重置
if nargin>0
words2=words;
end
if nargin>1&&ismember(fs,[11025 12000 16000 22050 24000 32000 44100 48000]);
fs2=fs;
%khz=sprintf('k%i',fix(fs/1000));
end
x=sapisynth(words2,'k16');
%{
t=1:length(x);
t3=1:16000/fs2:length(x);
y3=interp1(t,x,t3)';%分段線性插值,重新採樣
%}
%sound(x,fs2); % Playback sound播放
%%
%out
y=x;
end
記得當初一開始還想着自己錄製聲音製作,然後就搜了一下,還使用了按鍵之類的控制,就是太嘈雜了。
function [y,fs2] = lrcrecorder(secs,fs,nbits,channel)
%lrcrecorder 根據採樣頻率fs和通道數channel錄音
%%
%默認參數設置
fs2=44100;
ch=1;
nb=8;
t_s=1;
y=[];
%%
%輸入參數設置
if(nargin>0&&~isempty(secs)&&isnumeric(secs)&&secs(1,1)>0)
t_s=secs(1,1);
if t_s>300
t_s=300;%我這裏限制最多錄製5分鐘
end
end
if(nargin>1&&~isempty(fs)&&ismember(fs,[8000,11025,16000,22050,44100,48000,96000]))
fs2=fs;
end
if(nargin>2&&~isempty(nbits)&&ismember(nbits,[8,16,24]))
nb=nbits;
end
if(nargin>3&&~isempty(channel)&&ismember(channel,[1,2]))
ch=channel;
end
%%
%程序主要處理階段
rhandle=audiorecorder(fs2,nb,ch);%對象創建
%record(rhandle);%開始錄音
%pause(rhandle);%暫停
%isrecording(rhandle);%判斷有沒有在錄音並行纔有用啊這個
%%
input('正要錄一段環境音用於去噪,按一下轉折');
recordblocking(rhandle,2);%根據設置錄製時間
y=getaudiodata(rhandle);%獲得錄製的波形數據
y=y(:,1);%取單聲道
seg=snrseg(y,zeros(length(y),1),fs2,'wz');
option.asnr=seg;
option.ne=0;
%%
input('要開始錄製了,按一下轉折鍵');
recordblocking(rhandle,t_s);%根據設置錄製時間
%record(rhandle);%
%resume(rhandle);%繼續錄
%stop(rhandle);%停止錄製
y=getaudiodata(rhandle);%獲得錄製的波形數據
y=y(:,1);%取單聲道
y=ssubmmse(y,fs2,option);
if(isempty(y(y>0)))
disp('麥克風沒有設置爲默認設備或其他問題');
y=[];
end
%play(rhandle);%試聽
end
彈出告警的窗口
function lrcwarning(strwarn,s,pf)
%告警窗口,提示窗口lrcwarning('提示文字','窗口名','圖片地址')
winname='告警窗口';
pngfie='lrcico\icot1.png';
if nargin>1&&~isempty(s)
winname=s;
end
if nargin>2&&~isempty(pf)&&~isempty(dir(pf))
pngfie=pf;
end
if nargin>0&&~isempty(strwarn)
[u8,rbg256]=imread(pngfie);
h=msgbox(strwarn,winname,'custom',u8,rbg256);
%h:figure)-c1:axes(image))-c2:axes(text))-c3:uicontrol
%%
c3=findall(get(h,'children'),'type','uicontrol');
%set(c3,'BackgroundColor',[0.4,0.4,0.4]);%確定按鈕
set(c3,'Visible','off');
%%
objcell=get(get(h,'children'),'children');
%objcell{1}-image;objcell{2}-text;objcell{1}-[]
set(objcell{2},'Color',[1 ,0,0]);
%set(objcell{2},'Position',[100 30 10]);
%set(objcell{2},'FontSize',25);
%set(objcell{2},'String','處理中..');
% pause(1);
% close(h);
end
end
文本或者二進制保存
function lrcsavedata(filename,variables,fmt)
%保存文件
%輸入:
% filename 地址+文件名
% variables 存儲數據變量
% fmt 默認二進制'-mat','-ascii'十進制存儲
% 主要使用了save函數
%輸出:
% 一個文件
%Designed by Xu__Jiayu
ifmt='-mat';
p=variables;
if(nargin>1)
if(~ischar(filename))
return
end
indexs=strfind(filename,'\');
if(~isempty(indexs))
exdir=filename(1:indexs(end)-1);
if isempty(dir(exdir))
disp('目錄不存在,創建目錄');
%mkdir('parentFolder','folderName')
mkdir(pwd,exdir);
end
end
if(nargin>2&&(strcmp(fmt,'-mat')||strcmp(fmt,'-ascii')))
ifmt=fmt;
end
save(filename,'p',ifmt);
end
end
下面是通過miditool第三方庫製作簡答的單軌道的MIDI文件,哦這裏音符文件涉及到我自己設計的音符表示格式,這個比較不好使用呢。簡單的說就是一個音符獨佔三行,第一行表示的'.'升八度和'..'十六度,第二行音符用1,2,3,4,5,6,7對應代替可加‘-’拉長音,第三行是表示降八度等
function [nmats] = lrcmademidicomplex(melodicfile,basein,basedur)
%lrcmademidicomplex 單通道主旋律製作(複雜版本)
%melodicfile 按行輸入旋律的文件名,後綴.mat
%basein 基調調整
%basedur 四分音符時長設置,單位秒sec
%modify by Xu__Jiayu 2017-03-06
%根據文件1 2 3 4 5 6 7 =Do Re Mi Fa So La Si
%..升八度或升16度
%符..-- 一點:原+一半,兩點:原+一半+半半,-:原+原,
%..降八度或降16度---變爲1/8 1/16 1/32
%休止符0設置時間起始間隔,也用三行,雖然無升降調
%%
% 默認參數設置
global baseNOTE;
baseNOTE=65;
t2=[1 ,2 ,4];%四分音符,二分音符 -,全音符---
to2=[1,1+1/2,1+1/2+1/4];%四分音符 . ..
t3=[1,1/2 ,1/4 ,1/8];%四分音符,八分音符 - ,16分音符 --, 三十二分音符---,
keydu=[0,12,24];%升+. 升+.. 降-. 降-..
dur=0.25;%sec
mypitch=[];
nmats=[];
%%
%音符文件讀入或者命令窗口讀入
if nargin==2&&~isempty(basein)&&isnumeric(basein)
baseNOTE=baseNOTE+basein(1);%中調調正
end
if nargin==3&&~isempty(basedur)&&isnumeric(basedur)
dur=basedur(1);%中調調正
end
C4mel=[0 2 4 5 7 9 11 12] + baseNOTE;
if nargin>0&&~isempty(melodicfile)&&ischar(melodicfile)
%mel=load(melodicfile,'-ascii');%矩陣load
fid=fopen(melodicfile,'r');%打開獲取文件標識符-連接
tmel=fgets(fid);
mel=[];
ts=0;
tttt=0;
while ischar(tmel)
%%%%%%..
up_down=keydu(1+mod(length(strfind(tmel,'.')),length(keydu)));%升降調#
%%%%%%符..---
tmel=fgets(fid);
if ~ischar(tmel)
disp('複雜版簡譜文件輸入錯誤2');
return;
end
ind=regexp(tmel,'[01234567]');%正則表達式過濾
mel=tmel(ind)-'0';%符mel(1);
tt2=t2(1+mod(length(strfind(tmel,'-')),length(t2)));%延長;
tto2=to2(1+mod(length(strfind(tmel,'.')),length(to2)));%原+半;
%..---
tmel=fgets(fid);
if ~ischar(tmel)
disp('複雜版簡譜文件輸入錯誤3');
return;
end
up_down=up_down-keydu(1+fix(length(strfind(tmel,'.'))/length(keydu)));%降調b
tt3=t3(1+mod(length(strfind(tmel,'-')),length(t3)));%縮短;
%%%%%
mydur=dur*tt2*tto2*tt3;%
tttt=tttt+1;
if(isempty(mel))
str=['第',num2str(tttt),'個複雜簡譜音符出現錯誤.程序結束'];
disp(str);
return
end
if(0~=mel(1))%非休止符,假如一行anmat
mypitch= C4mel(mel(1))+up_down;%升降調操作
%%
%音符形成nmat,默認開始時間ts,時間間隔mydur
rowNum=size(mypitch,1);%當前爲1,不循環
for ind=1:rowNum;
aNmat=createOneNmat(mypitch(ind,:),ts,mydur);
nmats=[nmats;aNmat];%沒有進行內存空間申請,
ts=aNmat(end,6)+aNmat(end,7);%新的起始時間;
end
%%%%%%%%%%%%%%%%%%%%%%%單個音符操作
else%休止符
ts=ts+mydur;%有休止符,起始時間改變
end
tmel=fgets(fid);
end
fclose(fid);%關閉標識符
%{
else
%屏幕輸入
input('按照1 2 3 4 5 6 7 =Do Re Mi Fa So La Si輸入旋律(空格隔開或無),其他鍵結束輸入\n');
while true;
s=input(' ','s');
s=s(strfind(s,' '));%去除空格
mel=[];
for i=1:length(s);
mel=[mel,s(i)-'0'];%單個字符成數據
end
if true(ismember(mel,[1,2,3,4,5,6,7]));%判斷在範圍內?
mypitch=[mypitch,mel];
else
break;%音符讀取結束
end
end
%}
end
%%
%保存製作的midi文件
%s=input('請輸入要保存的文件名\n','s');
%if isempty(strfind(s,'.mid'));
% s=strcat(s,'.mid');
%end
%nmats
ind=strfind(melodicfile,'\');
if ~isempty(ind)
melodicfile=melodicfile(ind(end)+1:end);
end
s=melodicfile(1:strfind(melodicfile,'.txt')-1);
s=['lrcC_midi\',s,'.mid'];%文件夾需要創建好了,不然報錯
%writemidi(nmats, s,60/dur,120/dur);
writemidi(nmats, s);
end
%%
%nmat--bmponset ,bmpdur,ch,pitch,vel,seconset,secdur
function aNmat=createOneNmat(notes,time_star,dur,vel,ch)
% Create isochronous notematrix
% nmat = createnmat(notes,<time_star><dur>,<vel>,<ch>);
% Function creates a notematrix of isochronous pitches based on the NOTES vector.
% This is useful for demonstration purposes and for creating stimuli with certain properties.
%
% 輸入:
% NOTES =pitch音高dB (e.g. [ 60 64 67] for C major chord)
% 可選輸入
% time_star=起始時間(默認0)
% DUR (optional) = 間隔時間 (默認 0.25秒)
% VEL (optional) = note velocities音符速率? (0-127, 默認 100)其意這個速率我不解
% CH (optional) = note channel 通道(默認通道 1)
%
% Output:
% NMAT = notematrix
%
% Remarks: only the NOTES vector is required for the input, other input arguments are
% optional and will be replaced by default values if omitted.
%
% Example: Create major scale going up
% major = [0 2 4 5 7 9 11 12] + 60;
% nmat = create_nmat(major,0.2,127,1);
%
% Authors:
% Date Time Prog Note
% 26.1.2003 18:44 TE Created under MATLAB 5.3 (PC)
%?Part of the MIDI Toolbox, Copyright ?2004, University of Jyvaskyla, Finland
% See License.txt last modify by Xu__Jiayu
%鋼琴鍵下面52個白件,黑鍵在CD間DE間FG間GA間AB間共36個黑鍵
%A0 B0
%C1 D1 E1 F1 G1 A1 B1
%C D E F G A B
%c d e f g a b
%c^1 d^1 e^1 f^1 g^1 a^1 b^1
%c^2 d^2 e^2 f^2 g^2 a^2 b^2
%c^3 d^3 e^3 f^3 g^3 a^3 b^3
%c^4 d^4 e^4 f^4 g^4 a^4 b^4
%c^5
%%
%默認參數設置
notes2=[0 2 4 5 7 9 11 12] + 60;
time_star2=0;
dur2=0.25;
vel2=100;
ch2=1;
%%
%輸入參數重置
if nargin>0&&~isempty(notes)&&(1==size(notes,1))
notes2=notes;
end
if nargin>1&&~isempty(time_star)&&isequal([1,1],size(time_star))
time_star2=time_star;
end
if nargin>2&&~isempty(dur)&&isequal([1,1],size(dur))
dur2=dur;
end
if nargin>3&&~isempty(vel)&&isequal([1,1],size(vel))
vel2=vel;
end
if nargin>4&&~isempty(ch)&&isequal([1,1],size(ch))
ch2=ch;
end
%%
%處理程序
% Pitches
notecnt= size(notes2,2);
oneVector=ones(notecnt,1);
% Durations時間間隔
dur2=oneVector*dur2;
% Velocities速率
vel2=oneVector*vel2;
% Channel通道
ch2 =oneVector*ch2;
%起始時間
onset=oneVector*time_star2;
for i = 2:notecnt
onset(i) = onset(i-1)+dur2(i-1);
end
dur_tb =dur2*1.666666;
onsetb = onset * 1.666666;
notes2=notes2';
aNmat=[onsetb,dur_tb,ch2,notes2,vel2,onset,dur2];
end
關於調用播放器的那個,由於涉及到界面的這個也是不好說,我就留下一點備份信息吧,在資源的lrcxjy.m裏面
% --- Executes on button press in UI_songlis_syn.
function UI_songlis_syn_Callback(hObject, eventdata, handles)
% hObject handle to UI_songlis_syn (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
exdir='runtemp\';
if(~isempty([exdir,'UIsyn.wav']))
set(handles.activex3,'URL',[exdir,'UIsyn.wav']);
else
lrcwarning('合成歌曲文件不存在','提示窗口');
disp('合成歌曲文件不存在');
end
% --- Executes on button press in UI_vibrato_on.
function UI_vibrato_on_Callback(hObject, eventdata, handles)
% hObject handle to UI_vibrato_on (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of UI_vibrato_on
%get(hObject,'Value') 1 on ;0 off;
% --- Executes during object creation, after setting all properties.
function UI_vibrato_on_CreateFcn(hObject, eventdata, handles)
% hObject handle to UI_vibrato_on (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% --------------------------------------------------------------------
function activex3_PlayStateChange(hObject, eventdata, handles)
% hObject handle to activex3 (see GCBO)
% eventdata structure with parameters passed to COM event listener
% handles structure with handles and user data (see GUIDATA)
%set(hObject.Peer,'Visible','on');
disp('window player PlayStateChange --mark by Xu__Jiayu');
%{
switch get(hObject,'playState')
case 'wmppsTransitioning'%緩衝--連接媒體/改變媒體
case 'wmppsReady'%準備就緒
case 'wmppsStopped'%播放結束
case 'wmppsMediaEnded'%已完成?加載完成?
case 'wmppsPlaying'%正在播放
otherwise
end
c=get(hObject,'controls');
c=get(c,'currentItem');
get(c)
disp('-------------');
s=get(hObject,'settings');
get(s)
%}
disp(get(hObject,'playState'));
disp(get(hObject,'status'));
進度條和拋異常的代碼片段截取
try
wbh=waitbar(0,'開始旋律調整');
set(wbh,'Name','調整旋律進度條');
%attr=get(wbh);%獲取句柄屬性對象
figureOBJ=get(wbh,'children');%查找句柄的children屬性/對象
axesOBJs=get(figureOBJ,'children');%查找句柄的children屬性/對象
patchOBJ=findall(axesOBJs,'type','patch');%多個句柄找出類型爲TYPE=patch的句柄
set(patchOBJ,'Edgecolor','g','FaceColor','b');%設置邊緣顏色和片顏色
pause(1);
for ind=1:length(lrc);%一個歌詞lrc對應一個lrcN音符個數
nmatend=nmatbegin+lrcN(ind)-1;
[yt,fs]=UI_lrcChangeMelodies(lrc(ind),mel(nmatbegin:nmatend,:),role,cutmethod,initialk,vibrato_on);
if(1~=ind)%休止時間處理
y=[y;zeros(ceil(fs*(mel(nmatbegin,6)-mel(nmatbegin-1,6)-mel(nmatbegin-1,7))),1)];%間隔無聲時間
end
y=[y;yt];
nmatbegin=nmatend+1;
waitbar(ind/length(lrc),wbh,['已經調整',num2str(ind),'個']);
disp(['已經調整',num2str(ind),'個']);
end
close(wbh);
catch err
close(wbh);
str=[];
for erri=1:length(err.stack);
str=[str,err.stack(erri).name];
if 1==strcmp('lrcttsV3',err.stack(erri).name)
lrcwarning('聯網錯誤,請用離線角色','提示窗口');
return;
end
end
lrcwarning(['合成出錯',str],'提示窗口');
end%plot(y);