🔓알고리즘/수학

C++ 피아노 연주

Mawile 2020. 9. 26.
728x90

안녕하세요!!

이번에는 백도어만들기 뒤풀이로

간단하게 피아노연주 함수를 만들어봤습니다

 

혹시 Beep() 이런함수 들어보셨나요?

소리를 출력해주는 함수입니다.

 

이함수는

#include <windows.h>

헤더파일을 추가하면 정상적으로 작동합니다

사용방법은

Beep(주파수,연주시간)
Beep(float,float)

입니다.

 

하지만 그냥 이렇게사용하면 피아노를 연주하기 힘듭니다

 

왜냐면 피아노는 옥타브마다 주파수가 다 다르기때문입니다

 

그래서 사용자가 사용하기 편하게만들어줬답니다.

 

피아노 자리별 주파수크기

위에 표는 보시다시피 피아노의 주파수크기를

알려주는 표입니다.

저는 이표에서 특정한 규칙성을 찾았습니다.

바로 n옥타브의 주파수의 음이 (n * 2^n-1)로 규칙적으로

증가하더라구요

이를 바탕으로 옥타브구현 알고리즘을 만들어보았습니다

 

{{{   소스코드   }}}

 

 

#include <windows.h> //beep()
#include <cmath> //pow()

void play(string str,int octa,float seconds){
	float ret;
	const float DO = 32.7032,DO_SH = 34.6478,RE = 36.7081
	,RE_SH = 38.8909,MI = 41.2034,FA = 43.6535
	,FA_SH = 46.2493,SOL = 48.9991,SOL_SH = 51.9130
	,LA = 55.0000,LA_SH = 58.2705,SI = 61.7354;
	if(str=="do") ret=DO * pow(2,octa-1);
	else if(str=="doS") ret=DO_SH * pow(2,octa-1);
	else if(str=="re") ret=RE * pow(2,octa-1);
	else if(str=="reS") ret=RE_SH * pow(2,octa-1);
	else if(str=="mi") ret=MI * pow(2,octa-1);
	else if(str=="fa") ret=FA * pow(2,octa-1);
	else if(str=="faS") ret=FA_SH * pow(2,octa-1);
	else if(str=="sol") ret=SOL * pow(2,octa-1);
	else if(str=="solS") ret=SOL_SH * pow(2,octa-1);
	else if(str=="la") ret=LA * pow(2,octa-1);
	else if(str=="laS") ret=LA_SH * pow(2,octa-1);
	else if(str=="si") ret=SI * pow(2,octa-1);
	else cout <<"잘못된 값";
	Beep(ret,seconds*1000);
	return;
}

[[[   알고리즘 원리   ]]]

void play(string str,int octa,float seconds){ //자리정보,옥타브수,연주시간 (0.5 반박자기준)
	float ret; //결과값
	const float DO = 32.7032,DO_SH = 34.6478,RE = 36.7081
	,RE_SH = 38.8909,MI = 41.2034,FA = 43.6535
	,FA_SH = 46.2493,SOL = 48.9991,SOL_SH = 51.9130
	,LA = 55.0000,LA_SH = 58.2705,SI = 61.7354;
    
    //1옥타브 자리별 주파수 const로 저장
if(str=="do") ret=DO * pow(2,octa-1);
//str가 "do" 일시 결과값은 1옥타브자리 도에서 2의 입력한옥타브-1제곱의 값과같다
	else if(str=="doS") ret=DO_SH * pow(2,octa-1);
    //str가 "doS" 일시 결과값은 1옥타브자리 도샾에서 2의 입력한옥타브-1제곱의 값과같다
else cout <<"잘못된 값"; //str의값이 이상할때 출력
	Beep(ret,seconds*1000);
    //결과값만큼의 주파수와 Beep함수는 1000 이 1초이기때문에 편하게 1로하도록바꿔주기

 


[[[   play() 함수사용방법   ]]]

play(str,oct,sec);



밑에저가 github에올려놓은함수는 piano.play() 로사용할거예요

예를들어

 

play("do",4,1); //피아노가운데도를 1초간연주

피아노의옥타브는 대게

1~8인데

그중 제일 대중적으로많이쓰는자리 

가운데자리는 4옥타브입니다!

(피아노배우는사람의여유..후후..<--ㅈㅅㅋㅋㅋ)

 

하지만 동시연주는 thread를 사용해야합니다!

이번달안으로 이 함수에대해 글을쓰게된다면

멀티쓰레딩을 이용한 피아노동시연주 심화과정에 대해 써볼게요!

시연영상은 하단에있으며,

파일은 깃허브에 올려놨습니다 감사합니다!


[[[   시연영상   ]]]

 

 

다운로드

 

DRAGONPROCESS/playpiano

Contribute to DRAGONPROCESS/playpiano development by creating an account on GitHub.

github.com

 

728x90

댓글