## Sc final
## input
index_vocal.json [frame, putch]
index_feature.json ????
index_link.txt
index_groundtruth.txt => ans
## output
onset(sec) offset(sec) pitch
## grading
A = 實際正確的音個數
B = 做出來正確的音個數
C = 滿足條件的音個數
=====> (2*C) / (A+B)
## DP
```matlab=
int arrayA[][max_column]
for j = 1~n
for i = 1~m
A(j, i) = abs(noteVec(1,j)-pv(1,i));
int arrayB[][max_column];
B(1,1) = A(1,1);
for i = 2:m
B(1,i) = B(1,i-1)+A(1,i);
for j = 2:n
for k = 1:j-1
B(j,k) = 10000000;
for j = 2:n
for i = 2:m
if B(j, i-1) < B(j-1, i-1)
B(j, i) = A(j, i) + B(j, i-1);
else
B(j, i) = A(j, i) + B(j-1, i-1);
minDist = B(1,m);
for j = 2:n
if B(j,m) < minDist
minDist = B(j,m);
output = minDist;
```
## DP in C
```C=
## DP
int A[][max_column]
for(int i = 0 ; i < n ; i++)
for(int j = 0 ; j < m ; j++)
A[i][j] = abs(noteVec[i]-pv[j]);
int B[][max_column];
B[0][0] = A[0][0];
for(int j = 1 ; j < m ; j++)
B[0][j] = B[0][j-1]+A[0][j];
for(int i = 1 ; i < n ; i++)
for(int k = 0 ; k < i ; k++)
B[i][k] = 10000000;
for(int i = 1 ; i < n ; i++)
for(int j = 1 ; j < m ; j++)
if B[i][j-1] < B[i-1][j-1]
B[i][j] = A[i][j] + B[i][j-1];
else
B[i][j] = A[i][j] + B[i-1][j-1];
int minDist = B[0][m];
for(int i = 1 ; i < n ; i++)
if B[i][m] < minDist
minDist = B[i][m];
//output = minDist;
```
## main
```python=
import numpy as np
import math
import json
frame = 0.032
p = 2 # pitch 正負可能的值
k = 1.5 #高或低於平均視為分段
t = 0 #時間
z = 0.1
output_list = []
def READ():
index = input()
vocal_file = index + "_vocal.json"
feature_file = index + "_feature.json"
with open(vocal_file, 'r') as read_file:
vocal_data = json.load(read_file)
with open(feature_file, 'r') as read_file:
feature_data = json.load(read_file)
return vocal_data, feature_data
def CAL_AVE(data_list):
total = 0
n = 0
for data in data_list:
total += data[1]
n += 1
return (total / n)
def DP(data_list, average_pitch):
p1 = math.floor(average_pitch - p) #無條件捨去
p2 = math.ceil(average_pitch + p) #無條件進位
p_list = list(range(p1, p2+1))
n = len(p_list) #y軸個數
m = len(data_list) #x軸個數
table = np.zeros((n, m)) #A
dp_table = np.zeros((n, m)) #B
for i in range(n):
for j in range(m):
table[i][j] = abs(p_list[i] - data_list[j][1])
dp_table[0][0] = table[0][0]
for j in range(1, m):
dp_table[0][j] = dp_table[0][j-1] + table[0][j]
for i in range(1, n):
for j in range(0, i):
if j == m:
break
dp_table[i][j] = float("inf")
for i in range(1, n):
for j in range(1, m):
if dp_table[i][j-1] < dp_table[i-1][j-1]:
dp_table[i][j] = table[i][j] + dp_table[i][j-1];
else:
dp_table[i][j] = table[i][j] + dp_table[i-1][j-1];
best_pitch = average_pitch
mindis = dp_table[0][m-1];
for i in range(1, n):
if dp_table[i][m-1] < mindis:
mindis = dp_table[i][m-1]
best_pitch = p_list[i]
start_time = data_list[0][0]
end_time = data_list[m-1][0]
output_list.append([start_time, end_time, best_pitch])
return
vocal_data, feature_data = READ()
#print(feature_data['zcr'])
data_list = []
average_pitch = 0
for now_data in vocal_data:
sec = now_data[0]
pitch = now_data[1]
if pitch == 0:
if (len(data_list) != 0):
DP(data_list, average_pitch)
data_list.clear()
average_pitch = 0
continue
if average_pitch != 0 and abs(pitch - average_pitch) > k: #分段
DP(data_list, average_pitch)
data_list.clear()
average_pitch = 0
data_list.append(now_data)
average_pitch = CAL_AVE(data_list)
#print("(", now_data[0], ", ", now_data[1], ")")
if (len(data_list) != 0):
DP(data_list, average_pitch)
for output in output_list:
print(output[0], " ", output[1], " ", output[2])
```