파이썬을 사용하여 템포 해석을 시도했습니다.
19571 단어 템포 분석librosa파이썬matplotlib분석
처음에
이번에는 Python을 사용하여 템포 해석을 실시했습니다.
본 기사는 작성한 프로그램의 소개와 결과에 대해 전할 수 있으면 좋겠습니다.
앞으로 몇 번이나 갱신하겠습니다.
※정밀도가 굉장히 나쁘습니다…
※프로그래밍을 할 수 있는 쪽은 개선해 코멘트를 부탁합니다<(_ _)>
사용환경
파이썬 3.9.1
Windows 10 Home Edition
Anaconda Powershell Prompt
템포 분석에 대해 자세히 알아보기
분석 순서
파이썬 3.9.1
Windows 10 Home Edition
Anaconda Powershell Prompt
템포 분석에 대해 자세히 알아보기
분석 순서
1. wav 파일을 N초마다 분할
wav 파일을 분할 → def cut_wav():
output 파일을 자동 생성하고 거기에,
0.wav -> 1.wav ...로 저장합니다.
2.Librosa를 사용하여 전체 템포를 분석
Librosa에서 템포 해석을 해 나갑니다.
전체 곡을 통과하면 전체 템포가 출력됩니다.
※어떻게 템포를 내고 있는지는, 웹사이트를 봐 주세요.
Librosa
3. 분할한 wav 파일마다 템포를 해석
"2.Librosa를 사용하여 전체 템포를 분석"과 마찬가지로,
분할한 파일마다 템포를 추정해 갑니다.
상당한 이상치가 나오므로 주의가 필요합니다.
※향후 개선 예정
4. 템포의 추이를 matplotlib로 표시
추정된 템포를 그래프로 표시합니다. 항상 일정한 템포라면 직선이 표시되어야 합니다.
실제 프로그램
import numpy as np
import librosa
import wave
import struct
import math
import os
from scipy import fromstring, int16
import matplotlib.pyplot as plt
#----------------------------------------
# wavファイルの分割
#---------------------------------------
def cut_wav(filename, time):
#ファイル読み出し
wavf = filename + '.wav'
wr = wave.open(wavf, 'r')
#waveファイルが持つ性質を取得
ch = wr.getnchannels()
width = wr.getsampwidth()
fr = wr.getframerate()
fn = wr.getnframes()
total_time = 1.0 * fn / fr
integer = math.floor(total_time)
t = int(time)
frames = int(ch * fr * t)
num_cut = int(integer//t)
# 確認用
print("total time(s) : ", total_time)
print("total time(integer) : ", integer)
print("time : ", t)
print("number of cut : ", num_cut)
# waveの実データを取得し数値化
data = wr.readframes(wr.getnframes())
wr.close()
X = np.frombuffer(data, dtype=int16)
print()
for i in range(num_cut):
print(str(i) + ".wav --> OK!")
#出力データを生成
outf = 'output/' + str(i) + '.wav'
start_cut = i*frames
end_cut = i*frames + frames
Y = X[start_cut:end_cut]
outd = struct.pack("h" * len(Y), *Y)
# 書き出し
ww = wave.open(outf, 'w')
ww.setnchannels(ch)
ww.setsampwidth(width)
ww.setframerate(fr)
ww.writeframes(outd)
ww.close()
return num_cut
#----------------------------------------
# 全体のテンポを求める
#---------------------------------------
def totaltempo(filename):
#検索するファイル名の作成 => output/ i .wav
name = filename + ".wav"
#wavファイルの読み込み
y, sr = librosa.load(name)
#テンポとビートの抽出
tempo , beat_frames = librosa.beat.beat_track(y=y, sr=sr)
#全体のテンポを表示
print()
print("total tempo : ", int(tempo))
print()
#----------------------------------------
# 分割テンポを求める
#---------------------------------------
def temposearch(num, time):
#return用変数の宣言
l = []
t = []
t_time = 0
before_tempo = 0
print("division tempo")
#音楽の読み込み
for i in range(0,num,1):
#検索するファイル名の作成 => output/ i .wav
name = "output/" + str(i) + ".wav"
#wavファイルの読み込み
y, sr = librosa.load(name)
#テンポとビートの抽出
tempo , beat_frames = librosa.beat.beat_track(y=y, sr=sr)
int_tempo = int(tempo)
#テンポの表示
print(str(i+1) + ":" + str(int_tempo))
#return用変数へ代入
l.append(int_tempo)
t_time = t_time + int(time)
t.append(t_time)
return l, t
#---------------------------------
# メイン関数
#---------------------------------
if __name__ == '__main__':
# すでに同じ名前のディレクトリが無いか確認
file = os.path.exists("output")
print(file)
if file == False:
#保存先ディレクトリの作成
os.mkdir("output")
#ファイル名とカット時間を入力しwavファイルを分割
f_name = input('input filename -> ')
cut_time = input('input cut time -> ')
n = int(cut_wav(f_name,cut_time))
#テンポ解析
totaltempo(f_name)
tempo, time = temposearch(n, cut_time)
print()
#タイトル用
name = "テンポ解析 " + cut_time + "秒で分割"
#グラフ描写
plt.title(name, fontname="MS Gothic")
plt.xlabel("時間(s)", fontname="MS Gothic")
plt.ylabel("テンポ(bpm)", fontname="MS Gothic")
plt.ylim(60, 180)
plt.plot(time, tempo)
plt.show()
실행 결과
이번에는 「위풍 당당」이라는 곡을 해석해 갑니다.
분석 된 노래는 여기에서 → 무료 Wave,MP3
(base) PS C:\Users\Name\tempo> python tempo_main.py
True
input filename -> ifudoudou
input cut time -> 10
total time(s) : 204.56489795918367
total time(integer) : 204
time : 10
number of cut : 20
0.wav --> OK!
1.wav --> OK!
2.wav --> OK!
3.wav --> OK!
4.wav --> OK!
5.wav --> OK!
6.wav --> OK!
7.wav --> OK!
8.wav --> OK!
9.wav --> OK!
10.wav --> OK!
11.wav --> OK!
12.wav --> OK!
13.wav --> OK!
14.wav --> OK!
15.wav --> OK!
16.wav --> OK!
17.wav --> OK!
18.wav --> OK!
19.wav --> OK!
total tempo : 117
division tempo
1:123
2:117
3:117
4:117
5:123
6:123
7:123
8:123
9:99
10:99
11:99
12:99
13:117
14:117
15:123
16:117
17:99
18:99
19:99
20:117
(base) PS C:\Users\Name\tempo>
표시할 그래프↓
결과 정보
상당히, 정밀도가 나쁜 것을 알 수 있습니까? ?
템포가 일정한 곳도 수치에 편차가 보이네요.
감상
단순히 곡수가 부족하기 때문에, 정밀도를 잘 모릅니다.
많이 해석을 해 이 프로그램의 특징을 보고 싶습니다.
개선점이나 이런 곡을 분석해 주었으면 한다! 라는 의견이 있으면 점점 코멘트 부탁드립니다!
Reference
이 문제에 관하여(파이썬을 사용하여 템포 해석을 시도했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/OkomeChike/items/b4ab7f5ed6ffa1653b94
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import numpy as np
import librosa
import wave
import struct
import math
import os
from scipy import fromstring, int16
import matplotlib.pyplot as plt
#----------------------------------------
# wavファイルの分割
#---------------------------------------
def cut_wav(filename, time):
#ファイル読み出し
wavf = filename + '.wav'
wr = wave.open(wavf, 'r')
#waveファイルが持つ性質を取得
ch = wr.getnchannels()
width = wr.getsampwidth()
fr = wr.getframerate()
fn = wr.getnframes()
total_time = 1.0 * fn / fr
integer = math.floor(total_time)
t = int(time)
frames = int(ch * fr * t)
num_cut = int(integer//t)
# 確認用
print("total time(s) : ", total_time)
print("total time(integer) : ", integer)
print("time : ", t)
print("number of cut : ", num_cut)
# waveの実データを取得し数値化
data = wr.readframes(wr.getnframes())
wr.close()
X = np.frombuffer(data, dtype=int16)
print()
for i in range(num_cut):
print(str(i) + ".wav --> OK!")
#出力データを生成
outf = 'output/' + str(i) + '.wav'
start_cut = i*frames
end_cut = i*frames + frames
Y = X[start_cut:end_cut]
outd = struct.pack("h" * len(Y), *Y)
# 書き出し
ww = wave.open(outf, 'w')
ww.setnchannels(ch)
ww.setsampwidth(width)
ww.setframerate(fr)
ww.writeframes(outd)
ww.close()
return num_cut
#----------------------------------------
# 全体のテンポを求める
#---------------------------------------
def totaltempo(filename):
#検索するファイル名の作成 => output/ i .wav
name = filename + ".wav"
#wavファイルの読み込み
y, sr = librosa.load(name)
#テンポとビートの抽出
tempo , beat_frames = librosa.beat.beat_track(y=y, sr=sr)
#全体のテンポを表示
print()
print("total tempo : ", int(tempo))
print()
#----------------------------------------
# 分割テンポを求める
#---------------------------------------
def temposearch(num, time):
#return用変数の宣言
l = []
t = []
t_time = 0
before_tempo = 0
print("division tempo")
#音楽の読み込み
for i in range(0,num,1):
#検索するファイル名の作成 => output/ i .wav
name = "output/" + str(i) + ".wav"
#wavファイルの読み込み
y, sr = librosa.load(name)
#テンポとビートの抽出
tempo , beat_frames = librosa.beat.beat_track(y=y, sr=sr)
int_tempo = int(tempo)
#テンポの表示
print(str(i+1) + ":" + str(int_tempo))
#return用変数へ代入
l.append(int_tempo)
t_time = t_time + int(time)
t.append(t_time)
return l, t
#---------------------------------
# メイン関数
#---------------------------------
if __name__ == '__main__':
# すでに同じ名前のディレクトリが無いか確認
file = os.path.exists("output")
print(file)
if file == False:
#保存先ディレクトリの作成
os.mkdir("output")
#ファイル名とカット時間を入力しwavファイルを分割
f_name = input('input filename -> ')
cut_time = input('input cut time -> ')
n = int(cut_wav(f_name,cut_time))
#テンポ解析
totaltempo(f_name)
tempo, time = temposearch(n, cut_time)
print()
#タイトル用
name = "テンポ解析 " + cut_time + "秒で分割"
#グラフ描写
plt.title(name, fontname="MS Gothic")
plt.xlabel("時間(s)", fontname="MS Gothic")
plt.ylabel("テンポ(bpm)", fontname="MS Gothic")
plt.ylim(60, 180)
plt.plot(time, tempo)
plt.show()
이번에는 「위풍 당당」이라는 곡을 해석해 갑니다.
분석 된 노래는 여기에서 → 무료 Wave,MP3
(base) PS C:\Users\Name\tempo> python tempo_main.py
True
input filename -> ifudoudou
input cut time -> 10
total time(s) : 204.56489795918367
total time(integer) : 204
time : 10
number of cut : 20
0.wav --> OK!
1.wav --> OK!
2.wav --> OK!
3.wav --> OK!
4.wav --> OK!
5.wav --> OK!
6.wav --> OK!
7.wav --> OK!
8.wav --> OK!
9.wav --> OK!
10.wav --> OK!
11.wav --> OK!
12.wav --> OK!
13.wav --> OK!
14.wav --> OK!
15.wav --> OK!
16.wav --> OK!
17.wav --> OK!
18.wav --> OK!
19.wav --> OK!
total tempo : 117
division tempo
1:123
2:117
3:117
4:117
5:123
6:123
7:123
8:123
9:99
10:99
11:99
12:99
13:117
14:117
15:123
16:117
17:99
18:99
19:99
20:117
(base) PS C:\Users\Name\tempo>
표시할 그래프↓
결과 정보
상당히, 정밀도가 나쁜 것을 알 수 있습니까? ?
템포가 일정한 곳도 수치에 편차가 보이네요.
감상
단순히 곡수가 부족하기 때문에, 정밀도를 잘 모릅니다.
많이 해석을 해 이 프로그램의 특징을 보고 싶습니다.
개선점이나 이런 곡을 분석해 주었으면 한다! 라는 의견이 있으면 점점 코멘트 부탁드립니다!
Reference
이 문제에 관하여(파이썬을 사용하여 템포 해석을 시도했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/OkomeChike/items/b4ab7f5ed6ffa1653b94
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(파이썬을 사용하여 템포 해석을 시도했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/OkomeChike/items/b4ab7f5ed6ffa1653b94텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)