This repository has been archived by the owner on Mar 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 291
/
Codegen.cxx
91 lines (74 loc) · 2.57 KB
/
Codegen.cxx
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
//
// echoprint-codegen
// Copyright 2011 The Echo Nest Corporation. All rights reserved.
//
#include <sstream>
#include <iostream>
#include <iomanip>
#include <memory>
#include "Codegen.h"
#include "AudioBufferInput.h"
#include "Fingerprint.h"
#include "Whitening.h"
#include "SubbandAnalysis.h"
#include "Fingerprint.h"
#include "Common.h"
#include "Base64.h"
#include <zlib.h>
using std::string;
using std::vector;
Codegen::Codegen(const float* pcm, unsigned int numSamples, int start_offset) {
if (Params::AudioStreamInput::MaxSamples < (uint)numSamples)
throw std::runtime_error("File was too big\n");
Whitening *pWhitening = new Whitening(pcm, numSamples);
pWhitening->Compute();
AudioBufferInput *pAudio = new AudioBufferInput();
pAudio->SetBuffer(pWhitening->getWhitenedSamples(), pWhitening->getNumSamples());
SubbandAnalysis *pSubbandAnalysis = new SubbandAnalysis(pAudio);
pSubbandAnalysis->Compute();
Fingerprint *pFingerprint = new Fingerprint(pSubbandAnalysis, start_offset);
pFingerprint->Compute();
_CodeString = createCodeString(pFingerprint->getCodes());
_NumCodes = pFingerprint->getCodes().size();
delete pFingerprint;
delete pSubbandAnalysis;
delete pWhitening;
delete pAudio;
}
string Codegen::createCodeString(vector<FPCode> vCodes) {
if (vCodes.size() < 3) {
return "";
}
std::ostringstream codestream;
codestream << std::setfill('0') << std::hex;
for (uint i = 0; i < vCodes.size(); i++)
codestream << std::setw(5) << vCodes[i].frame;
for (uint i = 0; i < vCodes.size(); i++) {
int hash = vCodes[i].code;
codestream << std::setw(5) << hash;
}
return compress(codestream.str());
}
string Codegen::compress(const string& s) {
long max_compressed_length = s.size()*2;
unsigned char *compressed = new unsigned char[max_compressed_length];
// zlib the code string
z_stream stream;
stream.next_in = (Bytef*)(unsigned char*)s.c_str();
stream.avail_in = (uInt)s.size();
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
deflateInit(&stream, Z_DEFAULT_COMPRESSION);
do {
stream.next_out = compressed;
stream.avail_out = max_compressed_length;
if(deflate(&stream, Z_FINISH) == Z_STREAM_END) break;
} while (stream.avail_out == 0);
uint compressed_length = stream.total_out;
deflateEnd(&stream);
// base64 the zlib'd code string
string encoded = base64_encode(compressed, compressed_length, true);
delete [] compressed;
return encoded;
}