1 /*
2    Copyright 2009 Last.fm Ltd.
3       - Primarily authored by Max Howell, Jono Cole and Doug Mansell
4 
5    This file is part of liblastfm.
6 
7    liblastfm is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    liblastfm is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with liblastfm.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 #ifndef LASTFM_FINGERPRINT_H
21 #define LASTFM_FINGERPRINT_H
22 
23 #include "global.h"
24 
25 #include "FingerprintId.h"
26 
27 namespace lastfm
28 {
29     class FingerprintableSource;
30     class Track;
31 
32     class LASTFM_FINGERPRINT_DLLEXPORT Fingerprint
33     {
34     protected:
35         class FingerprintPrivate * const d;
36 
37     public:
38         /** represents a partial fingerprint of 20 seconds of music, this is
39           * considered 99.9999...9999% unique and so we use it for most stuff as
40           * it is much quicker than a complete fingerprint, still though, you
41           * should do the generate step in a thread. */
42         Fingerprint( const lastfm::Track& );
43         ~Fingerprint();
44 
45         /** if the id isNull(), then you'll need to do generate, submit and decode */
46         FingerprintId id() const;
47 
48         /** The actual data that is the fingerprint, this is about 70kB or so,
49           * there isn't anything in it until you call generate. */
50         QByteArray data() const;
51 
52         enum Error
53         {
54             ReadError = 0,
55 
56             /** failed to extract samplerate, bitrate, channels, duration etc */
57             HeadersError,
58 
59             DecodeError,
60 
61             /** there is a minimum track duration for fingerprinting */
62             TrackTooShortError,
63 
64             /** the fingerprint service went wrong, or we submitted bad data,
65               * or myabe the request failed, whatever, we couldn't parse the
66               * result */
67             BadResponseError,
68 
69             /** sorry, liblastfm sucks, report bug with log! */
70             InternalError
71         };
72 
73         /** This is CPU intensive, do it in a thread in your GUI application */
74         void generate( FingerprintableSource* ) throw( Error );
75 
76         /** Submits the fingerprint data to Last.fm in order to get a FingerprintId
77           * back. You need to wait for the QNetworkReply to finish before you can
78           * pass it to decode clearly. */
79         QNetworkReply* submit() const;
80 
81         /** Pass a finished reply from submit(), if the response is sound, id()
82           * will be valid. Otherwise we will throw. You always get a valid id
83           * or a throw.
84           */
85         void decode( QNetworkReply*, bool* lastfm_needs_a_complete_fingerprint = 0 ) throw( Error );
86     };
87 
88 
89     class LASTFM_FINGERPRINT_DLLEXPORT CompleteFingerprint : public Fingerprint
90     {
91         CompleteFingerprint( const lastfm::Track& t );
92         ~CompleteFingerprint();
93     };
94 }
95 
96 
97 QDebug LASTFM_FINGERPRINT_DLLEXPORT operator<<( QDebug d, lastfm::Fingerprint::Error e );
98 
99 #endif
100