-
Notifications
You must be signed in to change notification settings - Fork 1
/
멜로디.html
179 lines (151 loc) · 6.47 KB
/
멜로디.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>안녕</title>
<link type="font" href="D2Coding.ttf">
<style>
*{
font-family: D2Coding;
}
.글자창{
height: 500px;
width: 32%;
}
</style>
</head>
<body>
<div id="파형">
<span onclick="오디오.파형='sine'">sine</span>
<span onclick="오디오.파형='square'">square</span>
<span onclick="오디오.파형='sawtooth'">sawtooth</span>
<span onclick="오디오.파형='triangle'">triangle</span>
<input id="i" type="range" min="50" max="600" value="300">
</div>
<div id="옥타는">옥타브: <span id='옥타브'>3</span></div>
<div id="비트는">비트: <span id='비트'>300</span></div>
<button onclick="" id='재생버튼'>재생</button>
<div>
<textarea id='재생' class="글자창"></textarea>
<textarea id='재생_반주' class="글자창"></textarea>
<textarea id="입력내역" class="글자창"></textarea>
</div>
<script>
document.getElementById('i').addEventListener('change',(e)=>{
console.log(e.target.value)
document.getElementById('비트').innerHTML=재생.비트=e.target.value
})
document.getElementById('재생버튼').addEventListener('click',(e)=>{
var 값 = document.getElementById('재생').value.replaceAll('\n',' ').replace(/(\s\s*)/g, " ") .trim().split(" ")
var 값_반주 = document.getElementById('재생_반주').value.replaceAll('\n',' ').replace(/(\s\s*)/g, " ") .trim().split(" ")
재생.시작(값);
재생.시작(값_반주);
})
</script>
<!-- 단순재생-->
<script>
var 단계 = 2**(1/12);
document.getElementById('입력내역').value=''
document.body.addEventListener('keydown',(e)=>{
console.log('누름',e.key, e.target.tagName)
if (e.target.tagName!='BODY') return;
if (e.key=='Backspace'){
e.returnValue=false;
var a = document.getElementById('입력내역').value
document.getElementById('입력내역').value=a.substr(0,a.length-4)
}
else if(e.key==' '){
document.getElementById('입력내역').value += ' _'
}
else if("_-".includes(e.key)){
document.getElementById('입력내역').value += ' '+e.key
}
else if(e.key=='Enter'){
document.getElementById('입력내역').value += '\n'
}
else if ("1234567890".includes(e.key)){
오디오.옥타브 = Number(e.key)
document.getElementById('옥타브').innerHTML=오디오.옥타브
}
else if (오디오.음계(e.key)) {
if (오디오.목록[e.key]) return;
//입력내역추가
var a="asedrfgyhujiklp;['"
var 내보낼옥타브 = 오디오.옥타브
if ("a".includes(e.key)) 내보낼옥타브-=1
else if ("lp;['".includes(e.key)) 내보낼옥타브+=1
var 코드 = 내보낼옥타브.toString()+"b c cs d ds e f fs g gs a as b c cs d ds e".split(" ")[a.indexOf(e.key)]
document.getElementById('입력내역').value+=(코드.length==2?" ":" ")+코드
오디오.작성(오디오.음계(e.key),e.key)
}
})
document.body.addEventListener('keyup',(e)=>{
//console.log('올림',e.key)
if (오디오.음계(e.key)) 오디오.해제(e.key)
})
var 오디오 ={
'파형':'sine',
'작성':(f,s)=>{
if (오디오.목록[s]) return;
//console.log('작성',f,s);
var AuCon = new AudioContext()
var ocil = AuCon.createOscillator()
ocil.type=오디오.파형
//square, triangle, sine
ocil.frequency.setValueAtTime(f, AuCon.currentTime);
ocil.connect(AuCon.destination)
// console.log('받음',ocil,AuCon)
ocil.start()
오디오.목록[s] = ocil;
},
'해제':(s)=>{
// console.log('해제',s);
if (!오디오.목록[s]) return;
오디오.목록[s].stop()
오디오.목록[s]=null;
},
'옥타브':3,
'음계':(s)=>{
var a="asedrfgyhujiklp;["
if (!a.includes(s)) return false;
// console.log(s,440/(2**((9-a.indexOf(s))/12)))
return 440/(2**((10-a.indexOf(s))/12))*(2**(오디오.옥타브-3));
},
'목록':{},
}
</script>
<!-- 재생-->
<script>
var 재생={
'시작':(값)=>{
console.log(값)
var i=0;
var 이름="c_d_ef_g_a_b"
var 이전f = 0
var a = setInterval(()=>{
//console.log(a,i,값.length)
if (i>=값.length || !값[i]) {
console.log("끋")
clearInterval(a);
오디오.해제(이전f )
i=0;
return;
}
if (값[i]!='-') 오디오.해제(이전f)
if (!"_-".includes(값[i])){
var 옥타브 = Number(값[i][0]) + (오디오.옥타브-3);
var 음계 = 이름.indexOf(값[i][1]) + (값[i].length<3 ? 0 : 값[i][2]=='s'? 1: -1)
var 주파수 = (440/(2**((9-음계)/12)))*(2**(옥타브-3))
//console.log(옥타브, 음계);
console.log(음계,주파수)
setTimeout(()=>{오디오.작성( 주파수, 주파수)},이전f!=주파수?0:40)
이전f = 주파수
}
i+=1;
},60*1000/재생.비트)
},
비트:300,
}
</script>
</body>
</html>