2020-10-26 18:57:43 +00:00
|
|
|
##| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
|
|
|
|
##| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
|
2020-02-29 05:01:58 +00:00
|
|
|
|
|
|
|
import sys,os
|
|
|
|
import numpy as np
|
|
|
|
import common
|
|
|
|
import rms_analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fit_points_to_reference( usL, dbL, usRefL, dbRefL ):
|
|
|
|
|
|
|
|
dbV = None
|
|
|
|
|
|
|
|
yyL = [ (db,dbRefL[ usRefL.index(us)]) for i,(us,db) in enumerate(zip(usL,dbL)) if us in usRefL ]
|
|
|
|
|
|
|
|
if len(yyL) < 10:
|
|
|
|
print("NO FIT")
|
|
|
|
else:
|
|
|
|
|
|
|
|
y0L,yrL = zip(*yyL)
|
|
|
|
yN = len(y0L)
|
|
|
|
|
|
|
|
A = np.vstack([np.ones(yN),y0L]).T
|
|
|
|
c,m = np.linalg.lstsq(A,yrL,rcond=None)[0]
|
|
|
|
|
|
|
|
dbV = (np.array(dbL) * m) + c
|
|
|
|
|
|
|
|
|
|
|
|
return dbV
|
|
|
|
|
|
|
|
def find_elbow( usL, dbL, pointsPerLine=10 ):
|
|
|
|
|
|
|
|
ppl_2 = int(pointsPerLine/2)
|
|
|
|
dL = []
|
|
|
|
|
|
|
|
|
|
|
|
i = pointsPerLine
|
|
|
|
|
|
|
|
# for each consecutive set of 'pointsPerLine' points in usL and dbL
|
|
|
|
while i < len(usL):
|
|
|
|
|
|
|
|
# find the x,y coordinates of the first 'ppl_2' coordinates
|
|
|
|
x0L = np.array([ (us,1.0) for us in usL[i-pointsPerLine:i-ppl_2] ])
|
|
|
|
y0L = np.array(usL[i-pointsPerLine:i-ppl_2])
|
|
|
|
|
|
|
|
# find the x,y coordinates of the second 'ppl_2' coordinates
|
|
|
|
x1L = np.array([ (us,1.0) for us in usL[i-ppl_2:i]])
|
|
|
|
y1L = np.array(dbL[i-ppl_2:i])
|
|
|
|
|
|
|
|
|
|
|
|
m0,c0 = np.linalg.lstsq(x0L,y0L,rcond=None)[0] # fit a line through the first set of points
|
|
|
|
m1,c1 = np.linalg.lstsq(x1L,y1L,rcond=None)[0] # fit a line through the second set of points
|
|
|
|
|
|
|
|
# store the angle between the two lines
|
|
|
|
dL.append(m1-m0)
|
|
|
|
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
# find the max angle
|
|
|
|
i = np.argmax( dL )
|
|
|
|
|
|
|
|
# return the x,y coordinate of the first data point of the second line
|
|
|
|
return (usL[i+ppl_2],dbL[i+ppl_2])
|
|
|
|
|
|
|
|
def find_elbow_main( cfg, inDir, midi_pitch, takeId ):
|
|
|
|
|
|
|
|
inDir = os.path.join(inDir,str(pitch),str(takeId))
|
|
|
|
analysisArgsD = cfg.analysisArgs['rmsAnalysArgs']
|
|
|
|
|
|
|
|
r = rms_analysis_main( inDir, int(midi_pitch), **analysisD )
|
|
|
|
|
|
|
|
usL = r.pkUsL
|
|
|
|
dbL = r.pkDbL
|
|
|
|
|
|
|
|
return find_elbow(r.pkUsL,r.pkDbL)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
inDir = sys.argv[1]
|
|
|
|
cfgFn = sys.argv[2]
|
|
|
|
pitch = sys.argv[3]
|
|
|
|
|
|
|
|
cfg = common.parse_yaml_cfg(cfgFn)
|
|
|
|
|
|
|
|
find_elbow( cfg, inDir, pitch, 0 )
|