matlab2013b,quartusii12.1
2.1频率选择
音乐的合成主要有几种频率,这里设置如下几组频率,在实际情况下,可以进行扩充。
Fc = 261.63; %C
Fd = 293.66; %D
Fe = 329.63; %E
Ff = 349.23; %F
Fg = 392; %G
Fa = 440; %A
Fb = 493.88; %B
在FPGA中,取整数,进行四舍五入的选择。
module sin_tops(
clk,
rst,
Fre,
sine
);
input clk;
input rst;
input[9:0] Fre;
output[9:0]sine;
reg[15:0]fres;
always @(posedge clk or posedge rst)
begin
if(rst)
begin
fres <= 16'd0;
end
else begin
case(Fre)
10'd262 : fres <= 16'd1715;
10'd294 : fres <= 16'd1925;
10'd330 : fres <= 16'd2160;
10'd349 : fres <= 16'd2289;
10'd392 : fres <= 16'd2569;
10'd440 : fres <= 16'd2884;
10'd494 : fres <= 16'd3237;
default: fres <= 16'd1715;
endcase
end
end
//parameter Fc = 10'd262;//261.63;//0.1M,32'd11236923
//parameter Fd = 10'd294;//293.66;//0.1M,32'd12612601
//parameter Fe = 10'd330;//329.63;//0.1M,32'd14157501
//parameter Ff = 10'd349;//349.23;//0.1M,32'd14999314
//parameter Fg = 10'd392;//392; //0.1M,32'd16836272
//parameter Fa = 10'd440;//440; //0.1M,32'd18897856
//parameter Fb = 10'd494;//494; //0.1M,32'212171384
nco_ips nco_ips_u(
.phi_inc_i (fres),
.clk (clk),
.reset_n (~rst),
.clken (1'b1),
.fsin_o (sine),
.fcos_o (),
.out_valid ()
);
// input [31:0] phi_inc_i;
// input clk;
// input reset_n;
// input clken;
// output [15:0] fsin_o;
// output [15:0] fcos_o;
// output out_valid;
endmodule
这个模块的仿真效果如下所示:
2.2正弦信号的模块设计
第二,正弦信号的模块设计,这个是核心模块,产生不同频率的正弦模块。
这个模块的主要功能就是产生正弦信号波。
2.3衰减模块
第三,衰减模块,即对每个音符发生的时候出现衰减,相当于论文中的公式:
公式中的exp部分。
2.4音乐合成顶层模块
module tops(
i_clock,
i_rst,
o_fre,
o_sin,
o_lapse,
o_final
);
input i_clock;
input i_rst;
output[9:0] o_fre;
output[9:0] o_sin;
output[11:0]o_lapse;
output[21:0]o_final;
//timing Controller
reg Reset;
reg Enable;
reg[15:0]Count;
reg[3:0] Cnt;
always @(posedge i_clock or posedge i_rst)
begin
if(i_rst)
begin
Count <= 16'd0;
Cnt <= 4'd0;
Reset <= 1'b0;
Enable<= 1'b0;
end
else begin
//every pitch continue 1s
if(Count == 8000)
Count <= 1;
else
Count <= Count + 1;
if(Count == 1)
begin
Reset <= 1'b1;
Enable<= 1'b1;
if(Cnt == 4'd6)
Cnt <= 4'd0;
else
Cnt <= Cnt + 4'd1;
end
else
begin
Reset <= 1'b0;
Enable<= 1'b0;
end
end
end
//C D E F G A B ~~~~~
sub_pitch sub_pitch_u(
.i_clock (i_clock),
.i_reset (Reset),
.i_enable (Enable),
.i_a (4'd1),
.i_sel (Cnt),//C D E F G A B ~~~~~
.o_fre (o_fre),
.o_sin (o_sin),
.o_lapse (o_lapse),
.o_final (o_final)
);
endmodule
进行音乐的合成:
仿真效果如下所示:
上述就是加入衰减效果的音符。
下面就通过连续的音符,产生一个音乐。
最后,根据合成的音符,组成连续的音乐。连续播放CDEFGAB。
首先进行仿真,得到如下的仿真结果,即运行我们代码中的top.vwf文件,仿真运行,结果如下:
然后,我们将对应的数据o_final和i_clock复制到新的一个波形文件中,如下所示:
就是新建一个波形文件,然后将o_final和i_clock复制到里面,如下
然后做一个设置,选中i_clock,然后点击如下的按键:
将时钟频率设置为原来的一半,得到如下的效果:
然后进行保存,右击另存为tbl文件
得到一个tbl波形文件组。
然后,将tbl中的英文说明删除。变成单独的数据(前面几行英文和最后一行X)
然后运行我们提供的MATLAB数据获取代码
clc;
clear;
close all;
%从tbl中数据进行提取
y = tbls('DAT.tbl');
%将读取的十六进制数据转换为有符号十进制数据
y_dec = func_get_real_dat(y);
%将FPGA中的数据进行归一
y_dec = y_dec/max(y_dec);
figure;
plot(y_dec);
sound(y_dec,8000);
运行后得到如下的效果:
然后可以听到合成的音乐,CDEFGAB~~~1,2,3,4,5,6,7
A03-13