야, 너도 드럼 칠 수 있어 : 1. 드럼 비트 샘플 파일 입력

드럼 악보 채보 프로젝트

  • 본 글은 제 대학교 3학년 여름 방학이었던 2019년 6월부터 3개월 간 진행했던, “야, 너도 드럼 칠 수 있어” 프로젝트에 관련된 설명 글입니다.
  • 편의상 설명 과정은 ‘~했다.’ 로 작성하였습니다.
  • 소스 코드 는 다음과 같습니다. (Source)

채보의 사전적 정의 : 음악을 듣고 악보로 옮겨 적는 것



이전 글 “(야, 너도 드럼 칠 수 있어 : 0. 개요)” 에서 이어지는 글입니다.


0. 사용 라이브러리


  • 먼저, import 항목들은 다음과 같다.
1
2
3
4
5
6
7
8
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as wav
import wave
import glob
import os.path
import cv2
import sounddevice as sd
cs


  • 주요 라이브러리와 사용된 이유는 아래와 같다.

1. numpy

  • 배열을 생성, 편집할 수 있는 라이브러리. FFT 메소드가 내장되어 있어 이를 활용하기 위해 사용.

2. matplotlib

  • 그래프를 plot하기 위한 라이브러리. 개발 과정 중 여러 실험들을 진행하며, 직접 결과를 확인하기 위해 사용.

3. scipy, wave

  • scipy는 여러 과학적 계산과정이 포함된 라이브러리이며, wave와 함께 .wav 파일을 분석하기 위해 사용.

4. glob, os.path, cv2

  • 모두 파일 입,출력을 구현하기 위해 사용.

5. sounddevice

  • 결과 시연 과정에서 파일을 재생하는 과정에 사용.


1. 파일 입력과 경우의 수 분류


  • 먼저, “.wav”파일을 불러오기 위해 다음과 같이 추가했다.
1
2
myPath = 'PATH'
myExt = '*.wav'
cs

PATH에 주소를 지정하고, “.wav”확장자를 불러온다.

  • 이후, (후에 사용될) 이미지 파일을 불러왔다.
1
default = cv2.imread("C:/drum/default.png",cv2.IMREAD_REDUCED_COLOR_4)
cs

드럼을 총 여섯 가지의 구성 요소로,
Kick, Snare, Tom, Ride, Crash, Hi-Hat 으로 분류했다.
(low/mid/high Tom, closed/open Hi-Hat은 따로 분류하지 않았다.)

드럼을 연주할 때, 한 번에 최대로 연주될 수 있는 요소는 셋 이라고 판단했다.
(양손에 채 하나, 킥 드럼 하나)

따라서 다음과 같이 각 경우의 수를 상세하게 생각했다.

1. 동시에 한 가지의 악기 연주

# 연주 방법 연주하는 악기
1 한 손 Crash
2 한 손 Ride
3 한 손 Hi-Hat
4 한 손 Tom
5 한 손 Snare
6 Kick


Kick만 로 연주하는 것을 알 수 있다. (손으로 Kick을 연주하는 사람은 제외)

2. 동시에 두 가지의 악기 연주

# 연주 방법 연주하는 악기
1 두 손 Crash, Ride
2 두 손 Hi-Hat, Crash
3 두 손 Hi-Hat, Ride
4 발, 한 손 Kick, Crash
5 발, 한 손 Kick, Hi-Hat
6 발, 한 손 Kick, Ride
7 양 손 Snare, Crash
8 양 손 Snare, Hi-Hat
9 한 손, 발 Snare, Kick
10 양 손 Snare, Ride
11 양 손 Snare, Tom
12 양 손 Tom, Crash
13 양 손 Tom, Hi-Hat
14 한 손, 발 Tom, Kick
15 양 손 Tom, Ride


Kick이 포함된 5가지 경우의 수와, 다른 5가지 악기의 경우의 수이다.

3. 동시에 세 가지의 악기 연주

# 연주 방법 연주하는 악기
1 발, 양 손 Kick, Crash, Ride
2 발, 양 손 Kick, Hi-Hat, Crash
3 발, 양 손 Kick, Hi-Hat, Ride
4 발, 양 손 Kick, Snare, Crash
5 발, 양 손 Kick, Snare, Hi-Hat
6 발, 양 손 Kick, Snare, Ride
7 발, 양 손 Kick, Snare, Tom
8 발, 양 손 Kick, Tom, Crash
9 발, 양 손 Kick, Tom, Hi-Hat
10 발, 양 손 Kick, Tom, Ride


Kick이 무조건 포함되므로, 경우의 수는 10가지이다.
마지막으로, 아무것도 연주하지 않은 초기 상태를 default로 두었다.

그렇게 총 32 개의 이미지를 준비했다.

2. 샘플링레이트와 진폭 계산

  • 이후, 입력된 파일들을 분석했다.
1
2
3
4
5
6
7
8
9
10
for filename in glob.glob(os.path.join(myPath, myExt)):
    rate, data0 = wav.read(filename)
    data1 = np.full(np.alen(data0), 0)
    data2 = np.full(np.alen(data0), 0)
    data1 = np.array(data0)
    times = np.arange(len(data0)) / float(rate)
    original = wave.open(filename, 'rb')
    nChannel = original.getnchannels()
    length = original.getnframes()
    original.close()
cs
  1. glob과 os.path를 활용해 입력, 출력 부분을 설정했다.
  2. data* 이름으로 변수를 설정했다.
  3. 총 프레임을 시간으로 나누어 Sampling-rate를 구했다.
  4. wave를 활용해 파일의 채널과 총 길이를 구했다.

만약 입력이 Stereo일 경우

  • Stereo 일 경우 wave 라이브러리로 처리하기 어려워, 간단히 Left 채널 만을 사용했다.
1
2
3
    if nChannel == 2:
        data2 = data0[:, 0]
        data1 = data2
cs

nChannel = 2일 경우 data0[:, 0] 를 대입해 Left 채널만 활용했다.

이같은 과정을 통해 샘플 파일을 입력했고, 기초적인 값들의 계산과 변수 선언을 마쳤다.
이제 FFT 등 실질적으로 신호를 처리하는 메소드를 구현할 차례이다.

다음 글 “(야, 너도 드럼 칠 수 있어 : 2. 처리 과정 구현)” 에서 이어집니다.

댓글남기기