특정 주파수의 음을 사인파(Sine Wave)로 재생하고 싶다면, javax.sound.sampled.*
라이브러리를 사용합니다. javax 시리즈는 자바에서 기본 제공됩니다.
1) new AudioFormat
으로 새로운 오디오 형식 생성
public AudioFormat(float sampleRate:샘플수, int sampleSizeInBits:비트당샘플사이즈, int channels:채널수, boolean signed:부호여부, boolean bigEndian:빅엔디안여부)
2) 생성한 AudioFormat
에서 소스 데이터 라인(Source Data Line)을 추출 후 SourceDataLine
자료형 변수에 저장
AudioFormat af = new AudioFormat(SAMPLE_RATE, BITS, CHANNELS, IS_BIG_ENDIAN); SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
3) sdl 오픈(open
) 및 시작(start
)
sdl.open(af); sdl.start();
4) 재생 정보에 대한 byte
형 배열 생성 후 해당 배열을 sld.write()
를 이용하여 기록
// Speicify playback time from SAMPLE_RATE int sizePerMs = (int)(SAMPLE_RATE / 1000); for(int i = 0; i < ms * sizePerMs; i++) { double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; buf[0] = (byte) (Math.sin(angle) * 127.0 * vol); sdl.write(buf, 0, 1); }
배열에는 특정 주파수에 대한 사인파 정보를 재생시간(ms) * ms당 사이즈
만큼 기록합니다. i
가 1이고, 샘플수가 44000, 주파수는 440인 경우 angle
은 0.0628이며, 이것에 대한 사인(sine)각도을 구하면 약 13.92입니다. 구해진 사인각은 그래프에서 y축의 높이 정보에 활용됩니다(자세한 사항은 푸리에 변환 참조). 여기에 127
을 곱하는 이유는 바이트형 배열의 범위가 -128
~127
(참고사이트)이기 때문입니다. vol
(볼륨)의 기본값은 1.0입니다. 재생시간이 1초(1000ms)인 경우, 44000 / 1000 * 1000 으로 i
는 43999까지 진행합니다.
5) sd의 버퍼를 비우고(drain
) 정지(stop
), 닫기(close
) 실행
sdl.drain(); sdl.stop(); sdl.close();
drain()
을 하지 않으면 소리가 재생되지 않습니다.
추가 예제: 제이콥 콜리어(Jaco Collier)의 미분음 게임 (Microtonal Game)
위 영상의 과정을 프로그래밍으로 나타내 봤습니다. 미 ~ 솔을 일정 수로 2등분부터 8등분까지 나눠서 노래를 부르고 있는데 이 사람은 외계인이라 가능한거고 다른 사람들은 절대 이런 식으로 할 수 없습니다. 원래는 평균율 기준으로 미
– 파
– 파#
– 솔
로 3등분입니다.
1개의 댓글
자바스크립트 예제: 특정 주파수의 소리 재생 + 음악 평균율 주파수 테이블 - BGSMM · 2019년 11월 4일 12:35 오전
[…] 주파수를 재생하는 글 자바 예제: 특정 주파수의 소리 재생 을 자바스크립트로 바꾼 예제입니다. 외부 온라인 소스나 라이브러리 […]