Revision 1:150ad38c1871

View differences:

Makefile
1

  
2
CXXFLAGS	:= -I../vamp-plugin-sdk -O3 -Wall -march=pentium4 -msse -msse2 -fomit-frame-pointer -ffast-math
3

  
4
ofa-vamp-plugin.so:	OfaVampPlugin.o protocol.o
5
	g++ -shared $^ -o $@ -L../vamp-plugin-sdk/vamp-sdk -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -lofa -lcurl -lexpat
6

  
7
clean:	
8
	rm *.o
9

  
10
OfaVampPlugin.o: OfaVampPlugin.h protocol.h
11
protocol.o: protocol.h
OfaVampPlugin.cpp
1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2

  
3
#include "OfaVampPlugin.h"
4

  
5
#include <vamp/vamp.h>
6
#include <vamp-sdk/PluginAdapter.h>
7
#include <vamp-sdk/RealTime.h>
8

  
9
#include <cstdlib>
10
#include <cmath>
11

  
12
#include <ofa1/ofa.h>
13

  
14
#include <endian.h>
15

  
16
#include "protocol.h"
17

  
18
using std::string;
19

  
20
OfaVampPlugin::OfaVampPlugin(float inputSampleRate) :
21
    Plugin(inputSampleRate),
22
    m_buffer(0),
23
    m_bufsiz(0),
24
    m_bufidx(0),
25
    m_channels(0),
26
    m_blockSize(0),
27
    m_totalCount(0),
28
    m_enough(false)
29
{
30
}
31

  
32
OfaVampPlugin::~OfaVampPlugin()
33
{
34
    if (m_buffer) free(m_buffer);
35
}
36

  
37
string
38
OfaVampPlugin::getIdentifier() const
39
{
40
    return "ofa";
41
}
42

  
43
string
44
OfaVampPlugin::getName() const
45
{
46
    return "MusicIP OFA Audio Fingerprinter";
47
}
48

  
49
string
50
OfaVampPlugin::getDescription() const
51
{
52
    return "Calculates an audio fingerprint using the MusicIP fingerprinting library";
53
}
54

  
55
string
56
OfaVampPlugin::getMaker() const
57
{
58
    return "Chris Cannam";
59
}
60

  
61
int
62
OfaVampPlugin::getPluginVersion() const
63
{
64
    return 1;
65
}
66

  
67
string
68
OfaVampPlugin::getCopyright() const
69
{
70
    return ""; //!!!
71
}
72

  
73
OfaVampPlugin::ParameterList
74
OfaVampPlugin::getParameterDescriptors() const
75
{
76
    ParameterList list;
77

  
78
    return list;
79
}
80

  
81
float
82
OfaVampPlugin::getParameter(std::string name) const
83
{
84
    return 0.0;
85
}
86

  
87
void
88
OfaVampPlugin::setParameter(std::string name, float value)
89
{
90
}
91

  
92
size_t
93
OfaVampPlugin::getPreferredStepSize() const
94
{
95
    return 0;
96
}
97

  
98
size_t
99
OfaVampPlugin::getPreferredBlockSize() const
100
{
101
    return 0;
102
}
103

  
104
bool
105
OfaVampPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
106
{
107
    if (stepSize != blockSize) {
108
        std::cerr << "ERROR: OfaVampPlugin::initialise: stepSize must be equal to blockSize (" << stepSize << " != " << blockSize << ")" << std::endl;
109
        return false;
110
    }
111

  
112
    m_bufsiz = 1048576;
113
    m_buffer = (int16_t *)malloc(m_bufsiz * sizeof(int16_t));
114
    m_bufidx = 0;
115
    m_channels = channels;
116
    m_blockSize = blockSize;
117
    m_totalCount = 0;
118
    m_enough = false;
119
    return true;
120
}
121

  
122
void
123
OfaVampPlugin::reset()
124
{
125
    m_bufidx = 0;
126
    m_totalCount = 0;
127
    m_print = "";
128
    m_enough = false;
129
}
130

  
131
OfaVampPlugin::OutputList
132
OfaVampPlugin::getOutputDescriptors() const
133
{
134
    OutputList list;
135

  
136
    OutputDescriptor desc;
137
    desc.identifier = "fingerprint";
138
    desc.name = "Fingerprint";
139
    desc.description = "Single result containing the audio fingerprint as its label";
140
    desc.unit = "";
141
    desc.hasFixedBinCount = true;
142
    desc.binCount = 0;
143
    desc.hasKnownExtents = false;
144
    desc.isQuantized = false;
145
    desc.sampleType = OutputDescriptor::VariableSampleRate;
146
    desc.sampleRate = m_inputSampleRate;
147
    list.push_back(desc);
148

  
149
    desc.identifier = "puid";
150
    desc.name = "PUID";
151
    desc.description = "Single result containing the MusicIP online PUID for this audio track, if available";
152
    desc.unit = "";
153
    desc.hasFixedBinCount = true;
154
    desc.binCount = 0;
155
    desc.hasKnownExtents = false;
156
    desc.isQuantized = false;
157
    desc.sampleType = OutputDescriptor::VariableSampleRate;
158
    desc.sampleRate = m_inputSampleRate;
159
    list.push_back(desc);
160

  
161
    return list;
162
}
163

  
164
// client id: a008bd70c9d3c681e2ff336e3ceaa6dc (limited)
165

  
166
OfaVampPlugin::FeatureSet
167
OfaVampPlugin::process(const float *const *inputBuffers,
168
                       Vamp::RealTime timestamp)
169
{
170
    m_totalCount += m_blockSize;
171

  
172
    if (m_enough) return FeatureSet();
173

  
174
    // libofa requires the first 135 seconds of audio (where available)
175
    size_t reqd = lrintf(ceil(135.f * m_inputSampleRate));
176

  
177
    size_t effectiveChannels = m_channels;
178
    if (effectiveChannels > 2) effectiveChannels = 2;
179

  
180
    if (m_bufidx + m_blockSize * effectiveChannels > m_bufsiz) {
181
        m_bufsiz *= 2;
182
        m_buffer = (int16_t *)realloc(m_buffer, m_bufsiz * sizeof(int16_t));
183
        std::cerr << "realloc " << m_bufsiz/2 << " -> " << m_bufsiz << std::endl;
184
    }
185

  
186
    for (size_t i = 0; i < m_blockSize; ++i) {
187
        for (size_t c = 0; c < effectiveChannels; ++c) {
188
            m_buffer[m_bufidx + i * effectiveChannels + c] = 
189
                int16_t(inputBuffers[c][i] * 32767.0);
190
        }
191
    }
192
    
193
    m_bufidx += m_blockSize * effectiveChannels;
194

  
195
    if (m_bufidx >= reqd * effectiveChannels) {
196

  
197
        m_enough = true;
198

  
199
        FeatureSet fset;
200

  
201
        int endian = OFA_LITTLE_ENDIAN;
202

  
203
#ifdef __BYTE_ORDER
204
#if __BYTE_ORDER == _BIG_ENDIAN
205
        endian = OFA_BIG_ENDIAN;
206
#endif
207
#endif
208

  
209
        const char *print = ofa_create_print
210
            ((unsigned char *)m_buffer,
211
             endian,
212
             m_bufidx,
213
             lrintf(m_inputSampleRate),
214
             m_channels > 1);
215
        
216
        if (!print) {
217
            std::cerr << "OfaVampPlugin: ERROR from libofa" << std::endl;
218
            return fset;
219
        }
220

  
221
        m_print = print;
222

  
223
        Feature feature;
224
        feature.hasTimestamp = true;
225
        feature.timestamp = Vamp::RealTime::zeroTime;
226
        feature.label = m_print;
227
        fset[0].push_back(feature);
228
        return fset;
229
    }
230

  
231
    return FeatureSet();
232
}
233

  
234
OfaVampPlugin::FeatureSet
235
OfaVampPlugin::getRemainingFeatures()
236
{
237
    FeatureSet fset;
238

  
239
    if (m_print == "") return fset;
240

  
241
    Feature feature;
242
    feature.hasTimestamp = true;
243
    feature.timestamp = Vamp::RealTime::zeroTime;
244

  
245
    int endian = OFA_LITTLE_ENDIAN;
246

  
247
#ifdef __BYTE_ORDER
248
#if __BYTE_ORDER == _BIG_ENDIAN
249
        endian = OFA_BIG_ENDIAN;
250
#endif
251
#endif
252

  
253
    AudioData data;
254
    data.setData
255
        (0, 
256
         endian,
257
         m_bufidx,
258
         lrintf(m_inputSampleRate),
259
         m_channels > 1,
260
         lrintf((m_totalCount * 1000.f) / m_inputSampleRate), //!!! approx
261
         "wav"); //!!!
262

  
263
    data.info.setPrint(m_print);
264

  
265
    TrackInformation *info = data.getMetadata
266
        ("a008bd70c9d3c681e2ff336e3ceaa6dc",
267
         "1",
268
         false);
269
    
270
    if (!info) {
271
        std::cerr << "OfaVampPlugin: ERROR from ofa/protocol, unable to retrieve PUID for fingerprint" << std::endl;
272
        std::cerr << "Fingerprint was: " << m_print << std::endl;
273
    } else {
274
        feature.label = info->getPUID();
275
        fset[1].push_back(feature);
276
    }
277

  
278
    return fset;
279
}
280

  
281
static Vamp::PluginAdapter<OfaVampPlugin> ofaAdapter;
282

  
283
const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version,
284
                                                    unsigned int index)
285
{
286
    if (version < 1) return 0;
287

  
288
    switch (index) {
289
    case  0: return ofaAdapter.getDescriptor();
290
    default: return 0;
291
    }
292
}
293

  
OfaVampPlugin.h
1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2

  
3
#ifndef _OFA_VAMP_PLUGIN_H_
4
#define _OFA_VAMP_PLUGIN_H_
5

  
6
#include <vamp-sdk/Plugin.h>
7

  
8
#include <pthread.h>
9

  
10
class OfaVampPlugin : public Vamp::Plugin
11
{
12
public:
13
    OfaVampPlugin(float inputSampleRate);
14
    virtual ~OfaVampPlugin();
15

  
16
    bool initialise(size_t channels, size_t stepSize, size_t blockSize);
17
    void reset();
18

  
19
    InputDomain getInputDomain() const { return TimeDomain; }
20

  
21
    size_t getPreferredStepSize() const;
22
    size_t getPreferredBlockSize() const;
23

  
24
    size_t getMinChannelCount() const { return 1; }
25
    size_t getMaxChannelCount() const { return 2; }
26

  
27
    std::string getIdentifier() const;
28
    std::string getName() const;
29
    std::string getDescription() const;
30
    std::string getMaker() const;
31
    int getPluginVersion() const;
32
    std::string getCopyright() const;
33

  
34
    ParameterList getParameterDescriptors() const;
35
    float getParameter(std::string) const;
36
    void setParameter(std::string, float);
37

  
38
    OutputList getOutputDescriptors() const;
39

  
40
    FeatureSet process(const float *const *inputBuffers,
41
                       Vamp::RealTime timestamp);
42

  
43
    FeatureSet getRemainingFeatures();
44

  
45
protected:
46
    int16_t *m_buffer;
47
    size_t m_bufsiz;
48
    size_t m_bufidx;
49
    size_t m_channels;
50
    size_t m_blockSize;
51
    size_t m_totalCount;
52
    std::string m_print;
53
    bool m_enough;
54
};
55

  
56

  
57
#endif
ofa-vamp-plugin.cat
1
vamp:ofa-vamp-plugin:ofa::Fingerprinting
protocol.cpp
1
/* ------------------------------------------------------------------
2

  
3
   libofa -- the Open Fingerprint Architecture library
4

  
5
   Public Domain (PD) 2006 MusicIP Corporation
6
   No rights reserved.
7

  
8
-------------------------------------------------------------------*/
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string>
12
#include <map>
13
#include <expat.h>
14
#include <curl/curl.h>
15
#include <curl/types.h>
16
#include <curl/easy.h>
17

  
18
using namespace std;
19

  
20
#include "protocol.h"
21

  
22
const char *url = "http://ofa.musicdns.org/ofa/1/track"; 
23
const char *userAgent = "libofa_example";
24
const char *unknown = "unknown";
25

  
26
// Lookup by fingerprint
27
const char *request_format = 
28
    "cid=%s&"       // Client ID
29
    "cvr=%s&"       // Client Version
30
    "fpt=%s&"       // Fingerprint
31
    "rmd=%d&"       // m = 1: return metadata; m = 0: only return id 
32
    "brt=%d&"       // bitrate (kbps)
33
    "fmt=%s&"       // File extension (e.g. mp3, ogg, flac)
34
    "dur=%ld&"      // Length of track (milliseconds)
35
    "art=%s&"       // Artist name. If there is none, send "unknown"
36
    "ttl=%s&"       // Track title. If there is none, send "unknown"
37
    "alb=%s&"       // Album name. If there is none, send "unknown"
38
    "tnm=%d&"       // Track number in album. If there is none, send "0"
39
    "gnr=%s&"       // Genre. If there is none, send "unknown"
40
    "yrr=%s&"       // Year. If there is none, send "0"
41
    "enc=%s&"       // Encoding. e = true: ISO-8859-15; e = false: UTF-8 (default). Optional.
42
    "\r\n";
43

  
44
// Lookup by PUID (Most fields drop out)
45
const char *request_format2 =
46
    "cid=%s&"       // Client ID
47
    "cvr=%s&"       // Client Version
48
    "pid=%s&"       // PUID 
49
    "rmd=%d&"       // m = 1: return metadata; m = 0: only return id 
50
    "brt=%d&"       // bitrate (kbps)
51
    "fmt=%s&"       // File extension (e.g. mp3, ogg, flac)
52
    "dur=%ld&"      // Length of track (milliseconds)
53
    "art=%s&"       // Artist name. If there is none, send "unknown"
54
    "ttl=%s&"       // Track title. If there is none, send "unknown"
55
    "alb=%s&"       // Album name. If there is none, send "unknown"
56
    "tnm=%d&"       // Track number in album. If there is none, send "0"
57
    "gnr=%s&"       // Genre. If there is none, send "unknown"
58
    "yrr=%s&"       // Year. If there is none, send "0"
59
    "enc=%s&"       // Encoding. e = true: ISO-8859-15; e = false: UTF-8 (default). Optional.
60
    "\r\n";
61

  
62

  
63
// --------------------------------------------------------------------
64
// HTTP POST support using standard curl calls
65
// --------------------------------------------------------------------
66
size_t data_callback(void *ptr, size_t size, size_t num, void *arg)
67
{
68
    string *str = (string *)arg;
69
    (*str) += string((const char *)ptr, size * num);
70
    return size * num;
71
}
72

  
73
long http_post(const string &url, const string &userAgent, const string &postData, string &doc)
74
{
75
  CURL              *curl;
76
  long               ret = 0;
77
  struct curl_slist *headerlist=NULL;
78

  
79
  headerlist = curl_slist_append(headerlist, "Expect:"); 
80

  
81
  curl_global_init(CURL_GLOBAL_ALL);
82
  curl = curl_easy_init();
83
  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
84
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&doc);
85
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, data_callback);
86
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
87
  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.length());
88
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
89
  curl_easy_setopt(curl, CURLOPT_POST, 1);
90
  curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
91
  curl_easy_perform(curl);
92
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ret);
93
  curl_easy_cleanup(curl);
94

  
95
  curl_slist_free_all (headerlist);
96

  
97
  return ret;
98
}
99

  
100
// --------------------------------------------------------------------
101
// XML Parsing support 
102
// --------------------------------------------------------------------
103

  
104
struct ParseInfo
105
{
106
    string path;
107
    string pcdata;
108
    TrackInformation *info;
109
};
110

  
111
void begin_element(void *data, const XML_Char *el, const XML_Char **attr)
112
{
113
    map<string, string> attrs;
114

  
115
    for(; *attr;) {
116
        string key = string((char *)*(attr++));
117
	string value = string((char *)*(attr++));
118
        attrs[key] = value;
119
    }
120

  
121
    ((ParseInfo *)data)->path += string("/") + string(el);
122
    if (((ParseInfo *)data)->path == "/metadata/track/puid-list/puid")
123
         ((ParseInfo *)data)->info->setPUID(attrs["id"]);
124

  
125
    ((ParseInfo *)data)->pcdata = "";
126
}
127

  
128
void end_element(void *data, const XML_Char *el)
129
{
130
    string::size_type pos;
131

  
132
    if (((ParseInfo *)data)->path == "/metadata/track/title")
133
         ((ParseInfo *)data)->info->setTrack(((ParseInfo *)data)->pcdata);
134
    if (((ParseInfo *)data)->path == "/metadata/track/artist/name")
135
         ((ParseInfo *)data)->info->setArtist(((ParseInfo *)data)->pcdata);
136

  
137
    pos = ((ParseInfo *)data)->path.rfind("/");
138
    if (pos != string::npos)
139
       ((ParseInfo *)data)->path = ((ParseInfo *)data)->path.substr(0, pos);
140
}
141

  
142
void pc_data(void *data, const XML_Char *charData, int len)
143
{
144
    char *temp;
145

  
146
    temp = new char[len + 1];
147
    strncpy(temp, (char *)charData, len);
148
    temp[len] = 0;
149
    ((ParseInfo *)data)->pcdata += string(temp);
150
    delete temp;
151
}
152

  
153
bool parse_xml(const string &doc, TrackInformation *info, string &err) 
154
{
155
    ParseInfo pinfo;
156

  
157
    err = "";
158
    pinfo.info = info;
159
    XML_Parser parser = XML_ParserCreate(NULL);
160
    XML_SetUserData(parser, (void *)&pinfo);
161
    XML_SetElementHandler(parser, ::begin_element, ::end_element);
162
    XML_SetCharacterDataHandler(parser, ::pc_data);
163
    int ret = XML_Parse(parser, doc.c_str(), doc.length(), 1);
164

  
165
    if (ret)
166
    {
167
        XML_ParserFree(parser);
168
        return true;
169
    }
170

  
171
    err = string(XML_ErrorString(XML_GetErrorCode(parser)));
172
    char num[10];
173
    sprintf(num, "%d", XML_GetCurrentLineNumber(parser));
174
    err += string(" on line ") + string(num);
175
    XML_ParserFree(parser);
176

  
177
    return false;
178
}
179

  
180
// --------------------------------------------------------------------
181
// Retrieve metadata for fingerprint
182
// --------------------------------------------------------------------
183

  
184
// Returns true on success
185
bool retrieve_metadata(string client_key, string client_version,
186
	TrackInformation *info, bool getMetadata) 
187
{
188
    if (!info)
189
	return false;
190

  
191
    // All metadata fields must be provided before this call if the
192
    // information is available, as part of the Terms of Service.
193
    // This helps create a better database for all users of the system.
194
    //
195
    // If the fields are not available, you can use default values.
196
    // Here we check for fields which have no default values.
197
    if (client_key.length() == 0)
198
	return false;
199
    if (client_version.length() == 0)
200
	return false;
201

  
202
    bool lookupByPrint = false;
203
    if (info->getPUID().length() == 0) {
204
	// Lookup by fingerprint
205
	if (info->getPrint().length() == 0)
206
	    return false;
207
	if (info->getFormat().length() == 0)
208
	    return false;
209
	if (info->getLengthInMS() == 0)
210
	    return false;
211

  
212
        lookupByPrint = true;
213
    }
214

  
215
    // Sloppily estimate the size of the resultant URL. Err on the side of making the string too big.
216
    int bufSize = strlen(lookupByPrint ? request_format : request_format2) +
217
            client_key.length() + client_version.length() +
218
            (lookupByPrint ? info->getPrint().length() : info->getPUID().length()) + 
219
            16 + // getMetadata ? 1 : 0, 
220
            16 + // info->getBitrate(),
221
            16 + //info->getFormat().c_str(), 
222
            16 + //info->getLengthInMS(), 
223
            ((info->getArtist().c_str() == 0) ? strlen(unknown) : info->getArtist().length()) +
224
            ((info->getTrack().c_str() == 0) ?  strlen(unknown) : info->getTrack().length()) +
225
            ((info->getAlbum().c_str() == 0) ?  strlen(unknown) : info->getAlbum().length()) +
226
            16 + // info->getTrackNum() + 
227
            ((info->getGenre().c_str() == 0) ?  strlen(unknown) : info->getGenre().length()) +
228
            ((info->getYear().c_str() == 0) ? 1 : info->getYear().length()) +
229
            info->getEncoding().length();
230
        
231
    char *buf = new char[bufSize];
232
    sprintf(buf, lookupByPrint ? request_format : request_format2, 
233
            client_key.c_str(), 
234
            client_version.c_str(),
235
            lookupByPrint ? info->getPrint().c_str() : info->getPUID().c_str(), 
236
            getMetadata ? 1 : 0, 
237
            info->getBitrate(),
238
            info->getFormat().c_str(), 
239
            info->getLengthInMS(), 
240
            (info->getArtist().length() == 0) ? unknown : info->getArtist().c_str(),
241
            (info->getTrack().length() == 0) ? unknown : info->getTrack().c_str(),
242
            (info->getAlbum().length() == 0) ? unknown : info->getAlbum().c_str(),
243
            info->getTrackNum(), 
244
            (info->getGenre().length() == 0) ? unknown : info->getGenre().c_str(),
245
            (info->getYear().length() == 0) ? "0" : info->getYear().c_str(),
246
            info->getEncoding().c_str());
247

  
248
    string response;
249
//    printf("request: '%s'\n", buf);
250
    long ret = http_post(url, userAgent, buf, response);
251
    delete [] buf;
252

  
253
    if (ret != 200)
254
    {
255
//	     printf("Error: %ld\n", ret);
256
//	     printf("response: %s\n\n", response.c_str());
257
        return false;
258
    }
259
//    printf("response: %s\n\n", response.c_str());
260

  
261
    unsigned int q = response.find("<?xml");
262
    if (q != string::npos) {
263
        response = response.substr(q);
264
    }
265
    string err;
266
    if (!parse_xml(response, info, err)) {
267
        // Clears title if it wasn't returned
268
        info->setTrack("");
269

  
270
        // Clears artists if it wasn't returned
271
        info->setArtist("");
272
    }
273
    return true;
274
}
protocol.h
1
/* ------------------------------------------------------------------
2

  
3
   libofa -- the Open Fingerprint Architecture library
4

  
5
   Public Domain (PD) 2006 MusicIP Corporation
6
   No rights reserved.
7

  
8
-------------------------------------------------------------------*/
9
#ifndef __PROTOCOL_H__
10
#define __PROTOCOL_H__
11

  
12
#include <string>
13
#include "ofa1/ofa.h"
14

  
15
using namespace std;
16

  
17
// This object must be filled out completely prior to making any
18
// calls to the server.  On return, some fields will be filled out.
19
class TrackInformation {
20
private:
21
    string puid;
22
    string print;
23
    string encoding;        // All other strings must honor this encoding
24
    int    bitrate;         // i.e. "192kbps", use 0 for VBR or freeformat
25
    string format;          // File extension
26
    long   length_in_ms;    // In milliseconds
27
    string artist;
28
    string track;
29
    string album;
30
    int    trackNum;        // use 0 if not known
31
    string genre;
32
    string year;
33
public:
34
    TrackInformation() :
35
	bitrate(0), length_in_ms(0), trackNum(0) {}
36
    ~TrackInformation() {}
37
    void setPrint(string p) { print = p; }
38
    string getPrint() const { return print; }
39
    // Only supported encodings are UTF-8 (default) and ISO-8859-15
40
    void setEncoding(string e) { encoding = e; }
41
    string getEncoding() const { return encoding; }
42
    void setBitrate(int b) { bitrate = b; }
43
    int getBitrate() const { return bitrate; }
44
    void setFormat(string fmt) { format = fmt; }
45
    string getFormat() const { return format; }
46
    void setLengthInMS(long ms) { length_in_ms = ms; }
47
    long getLengthInMS() const { return length_in_ms; }
48
    void setArtist(string name) { artist = name; }
49
    string getArtist() const { return artist; }
50
    void setTrack(string name) { track = name; }
51
    string getTrack() const { return track; }
52
    void setAlbum(string name) { album = name; }
53
    string getAlbum() const { return album; }
54
    void setTrackNum(int t) { trackNum = t; }
55
    int getTrackNum() const { return trackNum; }
56
    void setGenre(string g) { genre = g; }
57
    string getGenre() const { return genre; }
58
    void setYear(string y) { year = y; }
59
    string getYear() const { return year; }
60
    void setPUID(string id)  { puid = id; }
61
    string getPUID() const { return puid; }
62
};
63

  
64
// Get your unique key at http://www.musicdns.org
65
bool retrieve_metadata(string client_key, string client_verstion,
66
	TrackInformation *info, bool getMetadata);
67

  
68
class AudioData {
69
private:
70
    unsigned char *samples;
71
    int byteOrder;
72
    long size;
73
    int sRate;
74
    bool stereo;
75
public:
76
    TrackInformation info;
77
    AudioData() : samples(0), size(0), sRate(0), stereo(false) {}
78
    ~AudioData() {
79
	delete[] samples;
80
    }
81
    // size is number of samples (half the number of bytes)
82
    void setData(unsigned char*_samples, int _byteOrder, long _size,
83
	   	 int _sRate, bool _stereo, int _ms, string _fmt) {
84
	samples = _samples;
85
	byteOrder = _byteOrder;
86
	size = _size;
87
	sRate = _sRate;
88
	stereo = _stereo;
89
	// These two fields are used later for the protocol layer
90
	info.setLengthInMS(_ms);
91
	info.setFormat(_fmt);
92
    }
93
    int getByteOrder() const { return byteOrder; }
94
    long getSize() const { return size; }
95
    int getSRate() const { return sRate; }
96
    bool getStereo() const { return stereo; }
97
    bool createPrint() {
98
	const char *print = ofa_create_print(samples, byteOrder, size, sRate, stereo);
99
	if (!print)
100
	    return false;
101
	info.setPrint(print);
102
	return true;
103
    }
104
    // Get your unique key at http://www.musicdns.org
105
    TrackInformation *getMetadata(string client_key, string client_version, 
106
	    bool metadataFlag)
107
    {
108
	if (!retrieve_metadata(client_key, client_version, &info, metadataFlag))
109
	    return 0;
110
	return &info;
111
    }
112
};
113

  
114
#endif

Also available in: Unified diff