1 | #!/usr/bin/env python
|
---|
2 |
|
---|
3 | from __future__ import absolute_import
|
---|
4 | from __future__ import division
|
---|
5 | from __future__ import print_function
|
---|
6 |
|
---|
7 | import sys
|
---|
8 | import os
|
---|
9 |
|
---|
10 | import essentia
|
---|
11 | import essentia.standard as esstandard
|
---|
12 | import essentia.streaming as esstreaming
|
---|
13 |
|
---|
14 | # https://stackoverflow.com/questions/9622163/save-plot-to-image-file-instead-of-displaying-it-using-matplotlib
|
---|
15 | # Statements need to be in this order for MacOS operating a venv python2, otherwise an error message results
|
---|
16 | # related to the version being used not being a system OS 'Framework'
|
---|
17 | import matplotlib
|
---|
18 | # Select the Anti-Grain Geometry C++ backend for rendering to a file
|
---|
19 | matplotlib.use('Agg')
|
---|
20 | import matplotlib.pyplot as pyplot
|
---|
21 |
|
---|
22 | argc = len(sys.argv)
|
---|
23 |
|
---|
24 | input_audio_filename = None
|
---|
25 | output_filename_root = None
|
---|
26 |
|
---|
27 | if argc <= 1:
|
---|
28 | print("Usage: "+sys.argv[0] +" input_file [output_file]\n",file=sys.stderr)
|
---|
29 | sys.exit(1)
|
---|
30 | else:
|
---|
31 | input_audio_filename = sys.argv[1]
|
---|
32 | if argc == 2:
|
---|
33 | output_filename_root = os.path.splitext(input_audio_filename)[0]
|
---|
34 | else:
|
---|
35 | # output_filename_root = sys.argv[2]
|
---|
36 | output_filename_root = os.path.splitext(sys.argv[2])[0]
|
---|
37 |
|
---|
38 |
|
---|
39 |
|
---|
40 | # Initialize algorithms we will use
|
---|
41 | loader = esstreaming.MonoLoader(filename=input_audio_filename)
|
---|
42 |
|
---|
43 | framecutter = esstreaming.FrameCutter(frameSize=4096, hopSize=2048, silentFrames='noise')
|
---|
44 | windowing = esstreaming.Windowing(type='blackmanharris62')
|
---|
45 | spectrum = esstreaming.Spectrum()
|
---|
46 | spectralpeaks = esstreaming.SpectralPeaks(orderBy='magnitude',
|
---|
47 | magnitudeThreshold=0.00001,
|
---|
48 | minFrequency=20,
|
---|
49 | maxFrequency=3500,
|
---|
50 | maxPeaks=60)
|
---|
51 |
|
---|
52 |
|
---|
53 | # Use default HPCP parameters for plots, however we will need higher resolution
|
---|
54 | # and custom parameters for better Key estimation
|
---|
55 |
|
---|
56 | hpcp = esstreaming.HPCP()
|
---|
57 | hpcp_key = esstreaming.HPCP(size=36, # we will need higher resolution for Key estimation
|
---|
58 | referenceFrequency=440, # assume tuning frequency is 44100.
|
---|
59 | bandPreset=False,
|
---|
60 | minFrequency=20,
|
---|
61 | maxFrequency=3500,
|
---|
62 | weightType='cosine',
|
---|
63 | nonLinear=False,
|
---|
64 | windowSize=1.)
|
---|
65 |
|
---|
66 | key = esstreaming.Key(profileType='edma', # Use profile for electronic music
|
---|
67 | numHarmonics=4,
|
---|
68 | pcpSize=36,
|
---|
69 | slope=0.6,
|
---|
70 | usePolyphony=True,
|
---|
71 | useThreeChords=True)
|
---|
72 |
|
---|
73 | # Use pool to store data
|
---|
74 | pool = essentia.Pool()
|
---|
75 |
|
---|
76 | # Connect streaming algorithms
|
---|
77 | loader.audio >> framecutter.signal
|
---|
78 | framecutter.frame >> windowing.frame >> spectrum.frame
|
---|
79 | spectrum.spectrum >> spectralpeaks.spectrum
|
---|
80 | spectralpeaks.magnitudes >> hpcp.magnitudes
|
---|
81 | spectralpeaks.frequencies >> hpcp.frequencies
|
---|
82 |
|
---|
83 | spectralpeaks.magnitudes >> hpcp_key.magnitudes
|
---|
84 | spectralpeaks.frequencies >> hpcp_key.frequencies
|
---|
85 | hpcp_key.hpcp >> key.pcp
|
---|
86 |
|
---|
87 | hpcp.hpcp >> (pool, 'tonal.hpcp')
|
---|
88 |
|
---|
89 | key.key >> (pool, 'tonal.key_key')
|
---|
90 | key.scale >> (pool, 'tonal.key_scale')
|
---|
91 | key.strength >> (pool, 'tonal.key_strength')
|
---|
92 |
|
---|
93 | # Run streaming network
|
---|
94 | essentia.run(loader)
|
---|
95 |
|
---|
96 |
|
---|
97 | output_filename_hpcp = output_filename_root + ".png"
|
---|
98 |
|
---|
99 | # Plot HPCP
|
---|
100 | # data vals get normalized to be [0..1]
|
---|
101 | pyplot.imshow(pool['tonal.hpcp'].T, aspect='auto', origin='lower', interpolation='none')
|
---|
102 |
|
---|
103 | pyplot.axis('off')
|
---|
104 | pyplot.savefig(output_filename_hpcp , bbox_inches="tight", pad_inches=0)
|
---|
105 |
|
---|
106 |
|
---|
107 | output_filename_hpcp_json = output_filename_root + ".json"
|
---|
108 | output = esstandard.YamlOutput(filename=output_filename_hpcp_json, format='json')
|
---|
109 | output(pool)
|
---|
110 |
|
---|
111 | # print("Estimated key and scale:", pool['tonal.key_key'] + " " + pool['tonal.key_scale'])
|
---|
112 |
|
---|