MATLAB 編寫簡易電子琴(二)

2021-10-19 08:33:30 字數 4142 閱讀 4666

matlab 編寫簡易電子琴

這個電子琴輸入用的input函式,每按乙個字元要敲回車,現在用另一種方法解決了這個問題:

使用 set(gcf,『keypressfcn』,@key_press) 輸入字元,其中f=key_press(~,event) 為自定義函式,例如,以下**實時輸出按下的鍵:

set(gcf,'keypressfcn',@key_press)

function f=key_press(~,event)

f=event.key

end

電子琴完整**如下:

主程式

%讀入頻譜、音階-頻率表

amp_p=xlsread('amp_p.xlsx');

amp_p=1/max(amp_p)*amp_p;

global amp

amp=amp_p;

global or

or=1;

global f_key

f_key=xlsread('frequency.xlsx','sheet3','b1:c21');

%繪出鋼琴圖

global dw lw db lb

dw=32;

lw=200;

db=16;

lb=120;

global a;

a=key_image();

%figure(1)

figure('color',[0 0 0])

imshow(a)

title('electronic organ 1.0')

hold on

%鍵盤控制

set(gcf,'keypressfcn',@key_press)

function f=key_press(~,event)

global or amp f_key

c=event.key;

switch c

case 'z'

amp=amp_p;

case 's'

or=1;

case 'a'

or=0;

case 'd'

or=2;

case '1'

piano(f_key(or*7+1,1));

dot_plot(1,1);

case '2'

piano(f_key(or*7+2,1));

dot_plot(2,1);

case '3'

piano(f_key(or*7+3,1));

dot_plot(3,1);

case '4'

piano(f_key(or*7+4,1));

dot_plot(4,1);

case '5'

piano(f_key(or*7+5,1));

dot_plot(5,1);

case '6'

piano(f_key(or*7+6,1));

dot_plot(6,1);

case '7'

piano(f_key(or*7+7,1));

dot_plot(7,1);

case 'q'

piano(f_key(or*7+1,2));

dot_plot(1,2);

case 'w'

piano(f_key(or*7+2,2));

dot_plot(2,2);

case 'r'

piano(f_key(or*7+4,2));

dot_plot(4,2);

case 't'

piano(f_key(or*7+5,2));

dot_plot(5,2);

case 'y'

piano(f_key(or*7+6,2));

dot_plot(6,2);

otherwise

disp('again');

endf=1;

end%發出特定音高和音色的聲音

function p=piano(f)

global amp

fs=32000;

t=0:1/fs:1;

x=0*t;

n=length(amp);

for i=1:n

x=x+amp(i)*sin(2*pi*f*i*t);

endx=x.*exp(-1/(2*0.2^2)*t.^2);

x=sqrt(400/f)*x; %這一行是想把低音變強一些,可以去掉

sound(x,fs)

p=1;

endfunction plt=dot_plot(para_1,para_2)

global dw lw db lb or

l=1/2*db;

global a

a2=a;

if para_2==1

i_cen=3/4*lw;

j_cen=(or*7+para_1)*dw-1/2*dw;

a2(i_cen-l/2:i_cen+l/2,j_cen-l/2:j_cen+l/2,1)=ones(l+1,l+1,1);

a2(i_cen-l/2:i_cen+l/2,j_cen-l/2:j_cen+l/2,2:3)=0*ones(l+1,l+1,2);

else

i_cen=3/4*lb;

j_cen=(or*7+para_1)*dw;

a2(i_cen-l/2:i_cen+l/2,j_cen-l/2:j_cen+l/2,1)=ones(l+1,l+1,1);

a2(i_cen-l/2:i_cen+l/2,j_cen-l/2:j_cen+l/2,2:3)=zeros(l+1,l+1,2);

endimshow(a2)

plt=1;

end

呼叫的自定義函式 key_image() 用於生成琴鍵的影象:

function f=key_image()

dw=32;

lw=200;

db=16;

lb=120;

a=ones(lw,dw*21,3);

for i=1:20

a(:,i*dw-1:i*dw,:)=1/2*a(:,i*dw-1:i*dw,:);

endbkey_n=[1 2 4 5 6];

for i=1:3

for j=1:5

a(1:lb,((i-1)*7+bkey_n(j))*dw-db/2:((i-1)*7+bkey_n(j))*dw+db/2,:)=0*a(1:lb,((i-1)*7+bkey_n(j))*dw-db/2:((i-1)*7+bkey_n(j))*dw+db/2,:);

endendf=a;

end

執行結果如下,在鍵盤上按下各按鍵後,會發出對應的琴聲,並在對應的琴鍵上標出紅框。

%第二列是全音頻率,第三列是公升半音,不存在的半音用0填上

c4 261.63 277.18

d4 293.66 311.13

e4 329.63 0

f4 349.23 369.99

g4 392 415.3

a4 440 466.16

b4 493.88 0

c5 523.25 554.37

d5 587.33 622.25

e5 659.25 0

f5 698.46 739.99

g5 783.99 830.61

a5 880 932.33

b5 987.77 0

c6 1046.5 1108.73

d6 1174.66 1244.51

e6 1318.51 0

f6 1396.91 1479.98

g6 1567.98 1661.22

a6 1760 1864.66

b6 1975.53 0

amp_p.xlsx

%通過對某鋼琴琴音做fft得到的前八個倍頻的相對振幅

645.4

183.7

3020

2020

2056

c版電子琴

這是老師布置的期末大作業 不想自己辛苦的果實被自己刪除 所以選擇寫下來 可以給但是我一樣的朋友乙個借鑑吧 在此宣告我的東西挺菜的 只是給個提示而已 執行環境是win tc 有很多有待完善的地方 1.2.錄曲功能 3.1.通過對8255 並行介面,8253 定時器的設定實現了揚聲器的發聲 利用對sou...

介面程式設計 使用Proteus設計簡易電子琴

proteus版本 8.0 使用晶元 8086 並行介面晶元8255a 可程式設計定時 計數器8253 鎖存器74hc373 解碼器74hc138 1 設計乙個簡易的電子琴有21個音階,故採用3 7個按鈕來模擬。2 通過pb輸出的資料以及從pc口讀入的資料來判斷按下的是哪個鍵,然後通過c語言程式設計...

51微控制器電子琴 雷射電子琴

hi,有想到今天的專案嗎?理工男也有文藝細菌 今天給大家帶來的是雷射電子琴。第一步,首先先來介紹一下專案實現的功能 本次設計的核心是以stc89c52為主控微控制器,檢測紅外對管的狀態來識別當前已經被按下的琴鍵,然後通過定時器來控制引腳高低電頻的輸出頻率,達到控制無源蜂鳴器輸出不同音調的目的。核心內...