-
Notifications
You must be signed in to change notification settings - Fork 5
/
fingerprinting.c
109 lines (91 loc) · 3.36 KB
/
fingerprinting.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#include "fingerprinting.h"
#include "haar.h"
#include "minhash.h"
#include "rawfingerprints.h"
#include "spectralimages.h"
#include "wav.h"
int generate_fingerprint(const char* wav, struct signatures* *fingerprint,
char* *artist, char* *track_title, char* *album_title) {
// Let's make sure we have a wave file we can read
struct wav_reader* reader;
int res = new_wav_reader(wav, &reader);
if (res != SUCCESS) {
return res;
}
if (reader->artist != NULL) {
fprintf(stderr, "Artist: %s\n", reader->artist);
}
if (reader->track_title != NULL) {
fprintf(stderr, "Track title: %s\n", reader->track_title);
}
if (reader->album_title != NULL) {
fprintf(stderr, "Album title: %s\n", reader->album_title);
}
// Let's steal the metadata from the wav reader
if (artist != NULL) *artist = reader->artist;
if (track_title != NULL) *track_title = reader->track_title;
if (album_title != NULL) *album_title = reader->album_title;
reader->artist = NULL;
reader->track_title = NULL;
reader->album_title = NULL;
// Let's downsample the file into 5512Hz mono float samples between -1.0 and 1.0
float* samples;
int n = read_samples(reader, &samples);
free_wav_reader(reader);
fprintf(stderr, "%d 5512Hz mono samples\n", n);
if (n < SAMPLES_PER_FRAME) {
free(samples);
return n < 0 ? n : FILE_TOO_SMALL;
}
// Once we get the 5512Hz mono audio samples, the next step
// is to build many small signatures corresponding to small
// sample zones that overlap a lot.
struct spectral_images* spectral_images;
res = build_spectral_images(samples, n, &spectral_images);
free(samples);
if (res != SUCCESS) {
return res;
}
fprintf(stderr, "Got %d spectral images\n", spectral_images->n_images);
fprintf(stderr, "Applying Haar transform to spectral images\n");
apply_Haar_transform(spectral_images);
fprintf(stderr, "Building raw fingerprints\n");
struct rawfingerprints* rawfingerprints = build_raw_fingerprints(spectral_images);
free_spectral_images(spectral_images);
if (rawfingerprints == NULL) {
return MEMORY_ERROR;
}
struct signatures* signatures = build_signatures(rawfingerprints);
free_rawfingerprints(rawfingerprints);
if (signatures == NULL) {
return MEMORY_ERROR;
}
fprintf(stderr, "Generated %d signatures\n", signatures->n_signatures);
*fingerprint = signatures;
return SUCCESS;
}
int generate_fingerprint_from_samples(float* samples, unsigned int size, struct signatures* *fingerprint) {
if (size < SAMPLES_PER_FRAME) {
return FILE_TOO_SMALL;
}
struct spectral_images* spectral_images;
int res = build_spectral_images(samples, size, &spectral_images);
if (res != SUCCESS) {
return res;
}
apply_Haar_transform(spectral_images);
struct rawfingerprints* rawfingerprints = build_raw_fingerprints(spectral_images);
free_spectral_images(spectral_images);
if (rawfingerprints == NULL) {
return MEMORY_ERROR;
}
struct signatures* signatures = build_signatures(rawfingerprints);
free_rawfingerprints(rawfingerprints);
if (signatures == NULL) {
return MEMORY_ERROR;
}
*fingerprint = signatures;
return SUCCESS;
}