1 // Copyright (C) 2016  Lukas Lalinsky
2 // Distributed under the MIT license, see the LICENSE file for details.
3 
4 #ifndef CHROMAPRINT_FINGERPRINTER_CONFIGURATION_H_
5 #define CHROMAPRINT_FINGERPRINTER_CONFIGURATION_H_
6 
7 #include <algorithm>
8 #include "classifier.h"
9 #include "chromaprint.h"
10 
11 namespace chromaprint {
12 
13 static const int DEFAULT_SAMPLE_RATE = 11025;
14 
15 class FingerprinterConfiguration
16 {
17 public:
18 
FingerprinterConfiguration()19 	FingerprinterConfiguration()
20 		: m_num_classifiers(0), m_classifiers(0), m_remove_silence(false), m_silence_threshold(0), m_frame_size(0), m_frame_overlap(0)
21 	{
22 	}
23 
num_filter_coefficients()24 	int num_filter_coefficients() const
25 	{
26 		return m_num_filter_coefficients;
27 	}
28 
filter_coefficients()29 	const double *filter_coefficients() const
30 	{
31 		return m_filter_coefficients;
32 	}
33 
set_filter_coefficients(const double * filter_coefficients,int size)34 	void set_filter_coefficients(const double *filter_coefficients, int size)
35 	{
36 		m_filter_coefficients = filter_coefficients;
37 		m_num_filter_coefficients = size;
38 	}
39 
num_classifiers()40 	int num_classifiers() const
41 	{
42 		return m_num_classifiers;
43 	}
44 
classifiers()45 	const Classifier *classifiers() const
46 	{
47 		return m_classifiers;
48 	}
49 
max_filter_width()50 	int max_filter_width() const {
51 		return m_max_filter_width;
52 	}
53 
set_classifiers(const Classifier * classifiers,int size)54 	void set_classifiers(const Classifier *classifiers, int size)
55 	{
56 		m_classifiers = classifiers;
57 		m_num_classifiers = size;
58 		m_max_filter_width = 0;
59 		for (int i = 0; i < size; i++) {
60 			m_max_filter_width = std::max(m_max_filter_width, classifiers[i].filter().width());
61 		}
62 	}
63 
interpolate()64 	bool interpolate() const
65 	{
66 		return m_interpolate;
67 	}
68 
set_interpolate(bool value)69 	void set_interpolate(bool value)
70 	{
71 		m_interpolate = value;
72 	}
73 
remove_silence()74 	bool remove_silence() const
75 	{
76 		return m_remove_silence;
77 	}
78 
set_remove_silence(bool value)79 	void set_remove_silence(bool value)
80 	{
81 		m_remove_silence = value;
82 	}
83 
silence_threshold()84 	int silence_threshold() const
85 	{
86 		return m_silence_threshold;
87 	}
88 
set_silence_threshold(int value)89 	void set_silence_threshold(int value)
90 	{
91 		m_silence_threshold = value;
92 	}
93 
frame_size()94 	int frame_size() const
95 	{
96 		return m_frame_size;
97 	}
98 
set_frame_size(int value)99 	void set_frame_size(int value)
100 	{
101 		m_frame_size = value;
102 	}
103 
frame_overlap()104 	int frame_overlap() const
105 	{
106 		return m_frame_overlap;
107 	}
108 
set_frame_overlap(int value)109 	void set_frame_overlap(int value)
110 	{
111 		m_frame_overlap = value;
112 	}
113 
sample_rate()114 	int sample_rate() const {
115 		return DEFAULT_SAMPLE_RATE;
116 	}
117 
item_duration()118 	int item_duration() const {
119 		return m_frame_size - m_frame_overlap;
120 	}
121 
item_duration_in_seconds()122 	double item_duration_in_seconds() const {
123 		return item_duration() * 1.0 / sample_rate();
124 	}
125 
delay()126 	int delay() const {
127 		return ((m_num_filter_coefficients - 1) + (m_max_filter_width - 1)) * item_duration() + m_frame_overlap;
128 	}
129 
delay_in_seconds()130 	double delay_in_seconds() const {
131 		return delay() * 1.0 / sample_rate();
132 	}
133 
134 private:
135 	int m_num_classifiers;
136 	int m_max_filter_width;
137 	const Classifier *m_classifiers;
138 	int m_num_filter_coefficients;
139 	const double *m_filter_coefficients;
140 	bool m_interpolate;
141 	bool m_remove_silence;
142 	int m_silence_threshold;
143 	int m_frame_size;
144 	int m_frame_overlap;
145 };
146 
147 // Used for http://oxygene.sk/lukas/2010/07/introducing-chromaprint/
148 // Trained on a randomly selected test data
149 class FingerprinterConfigurationTest1 : public FingerprinterConfiguration
150 {
151 public:
152 	FingerprinterConfigurationTest1();
153 };
154 
155 // Trained on 60k pairs based on eMusic samples (mp3)
156 class FingerprinterConfigurationTest2 : public FingerprinterConfiguration
157 {
158 public:
159 	FingerprinterConfigurationTest2();
160 };
161 
162 // Trained on 60k pairs based on eMusic samples with interpolation enabled (mp3)
163 class FingerprinterConfigurationTest3 : public FingerprinterConfiguration
164 {
165 public:
166 	FingerprinterConfigurationTest3();
167 };
168 
169 // Same as v2, but trims leading silence
170 class FingerprinterConfigurationTest4 : public FingerprinterConfigurationTest2
171 {
172 public:
173 	FingerprinterConfigurationTest4();
174 };
175 
176 // Same as v2, but with 2x more precise sampling
177 class FingerprinterConfigurationTest5 : public FingerprinterConfigurationTest2
178 {
179 public:
180 	FingerprinterConfigurationTest5();
181 };
182 
CreateFingerprinterConfiguration(int algorithm)183 inline FingerprinterConfiguration *CreateFingerprinterConfiguration(int algorithm)
184 {
185 	switch (algorithm) {
186 	case CHROMAPRINT_ALGORITHM_TEST1:
187 		return new FingerprinterConfigurationTest1();
188 	case CHROMAPRINT_ALGORITHM_TEST2:
189 		return new FingerprinterConfigurationTest2();
190 	case CHROMAPRINT_ALGORITHM_TEST3:
191 		return new FingerprinterConfigurationTest3();
192 	case CHROMAPRINT_ALGORITHM_TEST4:
193 		return new FingerprinterConfigurationTest4();
194 	case CHROMAPRINT_ALGORITHM_TEST5:
195 		return new FingerprinterConfigurationTest5();
196 	}
197 	return 0;
198 }
199 
200 }; // namespace chromaprint
201 
202 #endif
203