前要
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);