pyACA: Documentation 0.3.1
Source Code for Audio Content Analysis
Loading...
Searching...
No Matches
computeNoveltyFunction.py
Go to the documentation of this file.
1# -*- coding: utf-8 -*-
2
3import math
4import numpy as np
5import matplotlib.pyplot as plt
6from scipy.signal import filtfilt
7from scipy.signal import find_peaks
8
9import pyACA
10from pyACA.computeSpectrogram import computeSpectrogram
11from pyACA.ToolPreprocAudio import ToolPreprocAudio
12from pyACA.ToolComputeHann import ToolComputeHann
13from pyACA.ToolReadAudio import ToolReadAudio
14
15
16
32def computeNoveltyFunction(cNoveltyName, x, f_s, afWindow=None, iBlockLength=4096, iHopLength=512):
33
34 # compute window function for FFT
35 if afWindow is None:
36 afWindow = ToolComputeHann(iBlockLength)
37
38 assert(afWindow.shape[0] == iBlockLength), "parameter error: invalid window dimension"
39
40 hNoveltyFunc = getattr(pyACA, "Novelty" + cNoveltyName)
41
42 # lp initialization
43 fLenSmoothLpInS = 0.07
44 fLenThreshLpInS = 0.14
45 iLenSmoothLp = np.max([2, math.ceil(fLenSmoothLpInS * f_s / iHopLength)])
46 iLenThreshLp = np.max([2, math.ceil(fLenThreshLpInS * f_s / iHopLength)])
47
48 # pre-processing
49 x = ToolPreprocAudio(x)
50
51 # in the real world, we would do this block by block...
52 [X, f, t] = computeSpectrogram(x, f_s, None, iBlockLength, iHopLength)
53
54 # novelty function
55 d = hNoveltyFunc(X, f_s)
56
57 # smooth novelty function
58 b = np.ones(iLenSmoothLp) / iLenSmoothLp
59 d = filtfilt(b, 1, d)
60 d[d < 0] = 0
61
62 # compute threshold
63 iLenThreshLp = min(iLenThreshLp, np.floor(len(d)/3))
64 b = np.ones(iLenThreshLp) / iLenThreshLp
65 G_T = .4 * np.mean(d[np.arange(1, d.shape[0])]) + filtfilt(b, 1, d)
66
67 # find local maxima above the threshold
68 iPeaks = find_peaks(d - G_T, height=0)
69
70 return d, t, iPeaks[0]
71
72
73
75def computeNoveltyFunctionCl(cPath, cNoveltyName):
76
77 [f_s, x] = ToolReadAudio(cPath)
78 # afAudioData = np.sin(2*np.pi * np.arange(f_s*1)*440./f_s)
79 [d, t, iPeaks] = computeNoveltyFunction(cNoveltyName, x, f_s)
80
81 # plot feature output
82 if bPlotOutput:
83 plt.plot(t, d)
84 return d, t, iPeaks
85
86
87if __name__ == "__main__":
88 import argparse
89
90 parser = argparse.ArgumentParser(description='Compute key of wav file')
91 parser.add_argument('--infile', metavar='path', required=False,
92 help='path to input audio file')
93 parser.add_argument('--noveltyname', metavar='string', required=False,
94 help='novelty measure name in the format NoveltyFlux')
95 parser.add_argument('--plotoutput', metavar='bool', required=False,
96 help='option to plot the output')
97
98 # retrieve command line args
99 args = parser.parse_args()
100 cInPath = args.infile
101 cNoveltyName = args.noveltyname
102 bPlotOutput = args.plotoutput
103
104 # only for debugging
105 if __debug__:
106 if not cInPath:
107 cInPath = "../../ACA-Plots/audio/sax_example.wav"
108 if not cNoveltyName:
109 cNoveltyName = "Flux"
110 if not bPlotOutput:
111 bPlotOutput = True
112
113 # call the function
114 computeNoveltyFunctionCl(cInPath, cNoveltyName)
computeNoveltyFunctionCl(cPath, cNoveltyName)
main