1 /****************************************************************************************
2  * Copyright (c) 2010-2012 Leo Franchi <lfranchi@kde.org>                               *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 
18 #ifndef ECHONEST_TRACK_H
19 #define ECHONEST_TRACK_H
20 
21 #include "AudioSummary.h"
22 #include "echonest_export.h"
23 #include "Util.h"
24 
25 #include <QObject>
26 #include <QString>
27 #include <QDebug>
28 #include <QSharedData>
29 #include <QUrl>
30 #include "Config.h"
31 
32 class QNetworkReply;
33 class TrackData;
34 
35 namespace Echonest
36 {
37 
38 class Song;
39 /**
40  * Upload-based Echo Nest Track API. If you want to search The Echo Nest for songs, use the Song API.
41  *  If you want to upload your own files and retrieve the acoustic information about them, use this Track
42  *   class. You can also fetch acoustic information from a track if you have the Track ID or MD5 of the file.
43  *
44  * A Track encapsulates the audio analysis from The Echo Nest.
45  *
46  * This class is implicitly shared.
47  *
48  */
49 class ECHONEST_EXPORT Track
50 {
51 public:
52 
53   Track();
54   explicit Track( const QByteArray& id );
55   Track( const Track& other );
56   Track& operator=( const Track& track );
57   ~Track();
58 
59   /**
60    * The track's artist.
61    */
62   QString artist() const;
63   void setArtist( const QString& artist );
64 
65   /**
66    * The track's title.
67    */
68   QString title() const;
69   void setTitle( const QString& title );
70 
71   /**
72    * The Echo Nest artist ID for this track.
73    */
74   QByteArray id() const;
75   void setId( const QByteArray& id );
76 
77   /**
78    * The MD5 hash of the track.
79    */
80   QByteArray md5() const;
81   void setMD5( const QByteArray& md5 );
82 
83   /**
84    * The album name of this track.
85    */
86   QString release() const;
87   void setRelease( const QString& release );
88 
89   /**
90    * The MD5 hashsum of the audio data.
91    */
92   QByteArray audioMD5() const;
93   void setAudioMD5( const QByteArray& md5 );
94 
95   /**
96    * The analyzer version that was used in this track's analysis.
97    */
98   QString analyzerVersion() const;
99   void setAnalyzerVersion( const QString& analyzerVersion );
100 
101   /**
102    * The samplerate of the track
103    */
104   int samplerate() const;
105   void setSamplerate( int samplerate );
106 
107   /**
108    * The bitrate of the track
109    */
110   int bitrate() const;
111   void setBitrate( int );
112 
113   /**
114    * If this track is fetched from a tracks bucket of a song search, the following information
115    *  will be populated for some id spaces.
116    */
117 
118   /**
119    * The catalog this track is from, if not a native Echo Nest track
120    */
121   QString catalog() const;
122   void setCatalog( const QString& catalog );
123 
124   /**
125    * The foreign id of this track, that is in the \c catalog catalog.
126    */
127   QByteArray foreignId() const;
128   void setForeignId( const QByteArray& id );
129 
130   /**
131    * The release image associated with this track
132    */
133   QUrl releaseImage() const;
134   void setReleaseImage( const QUrl& imgUrl );
135 
136   /**
137    * The preview url for this track, if it exists
138    */
139   QUrl previewUrl() const;
140   void setPreviewUrl( const QUrl& preview );
141 
142   /**
143    * The Echo Nest song associated with this track, if it exists
144    */
145   Song song() const;
146   void setSong( const Song& song );
147 
148   /**
149    * The analysis status
150    */
151   Analysis::AnalysisStatus status() const;
152   void setStatus( Analysis::AnalysisStatus );
153 
154   /**
155    * The full audio summary of the track. This contains information about the track's bars,
156    *  beats, sections, and detailed segment information as well as more metadata about the song's
157    *  acoustic properties.
158    *
159    *  Information about how to interpret the results of the audio summary can be found here:
160    *    http://developer.echonest.com/docs/v4/_static/AnalyzeDocumentation_2.2.pdf
161    *
162    * NOTE: This will return a copy of the AudioSummary object, which
163    *       is implicitly shared. If you make modifications to the returned
164    *       summary, for example by calling parseFullAnalysis(), it will detach
165    *       and you will have to call setAudioSummary() to save the changes back
166    *       to this Song object.
167    */
168   AudioSummary audioSummary() const;
169   void setAudioSummary( const AudioSummary& summary );
170 
171     /**
172    * Get a track object from the md5 hash of a song's contents.
173    *
174    * Call parseProfile() to get the track itself once the
175    *   QNetworkReply() emits the finished() signal.
176    */
177   static QNetworkReply* profileFromMD5( const QByteArray& md5 );
178 
179   /**
180    * Get a track object from an Echo Nest track id.
181    *
182    * Call parseProfile() to get the track itself once the
183    *   QNetworkReply() emits the finished() signal.
184    */
185   static QNetworkReply* profileFromTrackId( const QByteArray& id );
186 
187   /**
188    * Upload a track to The Echo Nest for analysis. The file can either be
189    *  a local filetype and include the file data as a parameter, or a url to a file on the internet.
190    *
191    * When the QNetworkReply emits its finished() signal, you can call parseProfile()
192    *  to get the resulting Track object. Be sure to check the status of the new track,
193    *  as it might be 'pending', which means it is still being analyzed and must be asked
194    *  for again later.
195    *
196    * Note that in the case of uploading a local file, the data QByteArray must stay in scope for the
197    *  whole completion of the upload operation.
198    */
199   static QNetworkReply* uploadLocalFile( const QUrl& localFile, const QByteArray& data, bool waitForResult = true );
200   static QNetworkReply* uploadURL( const QUrl& remoteURL, bool waitForResult = true );
201 
202   /**
203    * Analyze a previously uploaded track with the current version of the analyzer.
204    * It can be referenced by either track ID or file md5.
205    */
206   static QNetworkReply* analyzeTrackId( const QByteArray& id, bool wait = true );
207   static QNetworkReply* analyzeTrackMD5( const QByteArray& id, bool wait = true );
208 
209   /**
210    * Parse the result of a track request, and turn it into a
211    *  Track object.
212    *
213    * Call this function after the QNetworkReply* object returned
214    *  from the parse*, upload*, and analyze* emits its finished() signal
215    */
216   static Track parseProfile( QNetworkReply* ) throw( ParseError );
217 
218 private:
219 
220     QSharedDataPointer<TrackData> d;
221 };
222 
223 typedef QVector<Track> Tracks;
224 ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Track& track);
225 
226 
227 } // namespace
228 
229 #endif
230