pyACA: Documentation 0.3.1
Source Code for Audio Content Analysis
Loading...
Searching...
No Matches
computeFingerprint.py
Go to the documentation of this file.
1# -*- coding: utf-8 -*-
2
3import numpy as np
4
5from pyACA.computeSpectrogram import computeSpectrogram
6from pyACA.ToolComputeHann import ToolComputeHann
7from pyACA.ToolFreq2Bin import ToolFreq2Bin
8from pyACA.ToolPreprocAudio import ToolPreprocAudio
9from pyACA.ToolResample import ToolResample
10
11
12
19def computeFingerprint(x, f_s):
20
21 # set default parameters
22 fs_target = 5000
23 iBlockLength = 2048
24 iHopLength = 64
25
26 # pre-processing: down-mixing and normalization
27 x = ToolPreprocAudio(x)
28
29 # pre-processing: downsampling to target sample rate
30 if f_s != fs_target:
31 x, t_x = ToolResample(x, fs_target, f_s)
32
33 # initialization: generate transformation matrix for 33 frequency bands
34 H = generateBands_I(iBlockLength, fs_target)
35
36 # initialization: generate FFT window
37 afWindow = ToolComputeHann(iBlockLength)
38
39 # in the real world, we would do this block by block...
40 [X, f, tf] = computeSpectrogram(x, f_s, afWindow, iBlockLength, iHopLength)
41
42 # power spectrum
43 X = np.abs(X)**2
44
45 # group spectral bins in bands
46 E = np.matmul(H, X)
47
48 # extract fingerprint through diff (both time and freq)
49 SubFingerprint = np.diff(np.diff(E, 1, axis=0), 1, axis=1)
50 tf = tf[:-1] + iHopLength / (2 * fs_target)
51
52 # quantize fingerprint
53 SubFingerprint[SubFingerprint < 0] = 0
54 SubFingerprint[SubFingerprint > 0] = 1
55
56 return SubFingerprint, tf
57
58
59def generateBands_I(iFftLength, f_s):
60
61 # constants
62 iNumBands = 33
63 f_max = 2000
64 f_min = 300
65
66 # initialize
67 f_band_bounds = f_min * np.exp(np.log(f_max / f_min) * range(iNumBands+1) / iNumBands)
68 f_fft = np.arange(iFftLength / 2 + 1) / iFftLength * f_s
69 H = np.zeros([iNumBands, iFftLength // 2 + 1])
70 idx = np.zeros([len(f_band_bounds), 2]).astype(int)
71
72 # get indices falling into each band
73 for k in range(len(f_band_bounds)-1):
74 idx[k, 0] = np.ceil(ToolFreq2Bin(f_band_bounds[k], iFftLength, f_s)).astype(int)
75 idx[k, 1] = np.floor(ToolFreq2Bin(f_band_bounds[k+1], iFftLength, f_s)).astype(int)
76 H[k, idx[k, 0]:idx[k, 1] + 1] = 1
77
78 return H
79
80
81
84 from pyACA.ToolReadAudio import ToolReadAudio
85
86 # read audio file
87 [f_s, x] = ToolReadAudio(cPath)
88
89 # compute fingerprint
90 [F, t] = computeFingerprint(x, f_s)
91
92 return F, t
93
94
95if __name__ == "__main__":
96 import argparse
97
98 # add command line args and parse them
99 parser = argparse.ArgumentParser(description='Extract fingerprint from wav file')
100 parser.add_argument('--infile', metavar='path', required=False,
101 help='path to input audio file')
102
103 # retrieve command line args
104 args = parser.parse_args()
105 cPath = args.infile
106
107 # only for debugging
108 if __debug__:
109 if not cPath:
110 cPath = "../ACA-Plots/audio/sax_example.wav"
111
112 # call the function
113 computeFingerprintCl(cPath)
generateBands_I(iFftLength, f_s)