/**************************************************************************************** * Copyright (c) 2010 Leo Franchi * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef ECHONEST_PLAYLIST_H #define ECHONEST_PLAYLIST_H #include "echonest_export.h" #include "Song.h" #include #include #include "Artist.h" #include #include "Catalog.h" class QNetworkReply; class DynamicPlaylistData; namespace Echonest{ typedef struct { qreal served_time; QByteArray artist_id; QByteArray id; QString artist_name; QString title; int rating; } SessionItem; typedef struct { TermList terms; SongList seed_songs; // description .. what data is in here? Artists banned_artists; QVector< QString > rules; QByteArray session_id; Artists seeds; QVector< SessionItem > skipped_songs; QVector< SessionItem > banned_songs; QString playlist_type; Catalogs seed_catalogs; QVector< SessionItem > rated_songs; QVector< SessionItem > history; } SessionInfo; /** * This encapsulates an Echo Nest dynamic playlist. It contains a playlist ID and * the current song, and can fetch the next song. * * See http://developer.echonest.com/docs/v4/playlist.html#dynamic * for more information */ class ECHONEST_EXPORT DynamicPlaylist { public: /** * The types of playlist that can be generated. Artist plays songs for the given artist, * ArtistRadio takes into account similar artists, and ArtistDescription plays songs matching * the given description. */ enum ArtistTypeEnum { ArtistType, ArtistRadioType, ArtistDescriptionType, CatalogType, CatalogRadioType, SongRadioType }; /** * Different ways to sort a generated playlist */ enum SortingType { SortTempoAscending, SortTempoDescending, SortDurationAscending, SortDurationDescending, SortArtistFamiliarityAscending, SortArtistFamiliarityDescending, SortArtistHotttnessAscending, SortArtistHotttnessDescending, SortSongHotttnesssAscending, SortSongHotttnesssDescending, SortLatitudeAscending, SortLatitudeDescending, SortLongitudeAscending, SortLongitudeDescending, SortModeAscending, SortModeDescending, SortKeyAscending, SortKeyDescending, SortLoudnessAscending, SortLoudnessDescending, SortEnergyAscending, SortEnergyDescending, SortDanceabilityAscending, SortDanceabilityDescending }; /** * Different ways of picking artists in Artist radios. */ enum ArtistPick { PickSongHotttnesssAscending, PickTempoAscending, PickDurationAscending, PickLoudnessAscending, PickModeAscending, PickKeyAscending, PickSongHotttnesssDescending, PickTempoDescending, PickDurationDescending, PickLoudnessDescending, PickModeDescending, PickKeyDescending }; /** * The various parameters that can be passed to the playlist building * functions. */ enum PlaylistParam { Type, /// The type of playlist to generate. Value is the DynamicPlaylist::ArtistTypeEnum enum Format, /// Either xml (default) or xspf. If the result is xspf, the raw xspf playlist is returned, else the xml is parsed and exposed programmatically. If using XSPF, you must specify a catalog, the tracks bucket, and limit = true Pick, /// How the artists are picked for each artist in ArtistType playlists. Value is Playlist::ArtistPick enum value. Variety, /// 0 < variety < 1 The maximum variety of artists to be represented in the playlist. A higher number will allow for more variety in the artists. ArtistId, /// ID(s) of seed artist(s) for the playlist Artist, /// Artist names of seeds for playlist ArtistSeedCatalog, /// ID of seed artist catalog for the playlist SourceCatalog, /// ID of catalog (artist or song) for catalog type playlists SongId, /// IDs of seed songs for the playlist Description, /// Textual description for sort of songs that can be included in the playlist Results, /// 0-100, how many sonsg to include in the playlist, default 15 MaxTempo, /// 0.0 < tempo < 500.0 (BPM) The maximum tempo for any included songs MinTempo, /// 0.0 < tempo < 500.0 (BPM) the minimum tempo for any included songs MaxDuration, /// 0.0 < duration < 3600.0 (seconds) the maximum duration of any song on the playlist MinDuration, /// 0.0 < duration < 3600.0 (seconds) the minimum duration of any song on the playlist MaxLoudness, /// -100.0 < loudness < 100.0 (dB) the maximum loudness of any song on the playlist MinLoudness, /// -100.0 < loudness < 100.0 (dB) the minimum loudness of any song on the playlist MinDanceability, /// 0 < danceability < 1 a measure of the minimum danceability of the song MaxDanceability, /// 0 < danceability < 1 a measure of the maximum danceability of the song MinEnergy, /// 0 < danceability < 1 a measure of the maximum energy of the song MaxEnergy, /// 0 < danceability < 1 a measure of the maximum energy of the song ArtistMaxFamiliarity, /// 0.0 < familiarity < 1.0 the maximum artist familiarity for songs in the playlist ArtistMinFamiliarity, /// 0.0 < familiarity < 1.0 the minimum artist familiarity for songs in the playlist ArtistMaxHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for artists in the playlist ArtistMinHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for artists in the playlist SongMaxHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for songs in the playlist SongMinHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for songs in the playlist ArtistMinLongitude, /// -180.0 < longitude < 180.0 the minimum longitude for the location of artists in the playlist ArtistMaxLongitude, /// -180.0 < longitude < 180.0 the maximum longitude for the location of artists in the playlist ArtistMinLatitude, /// -90.0 < latitude < 90.0 the minimum latitude for the location of artists in the playlist ArtistMaxLatitude, /// -90.0 < latitude < 90.0 the maximum latitude for the location of artists in the playlist Mode, /// (minor, major) 0, 1 the mode of songs in the playlist Key, /// (c, c-sharp, d, e-flat, e, f, f-sharp, g, a-flat, a, b-flat, b) 0 - 11 the key of songs in the playlist SongInformation, /// what sort of song information should be returned. Should be an Echonest::SongInformation object Sort, /// SortingType enum, the type of sorting to use, Limit, /// true, false if true songs will be limited to those that appear in the catalog specified by the id: bucket Audio, /// true, false, if true songs will be limited to those that have associated audio DMCA, /// true, false Only valid for dynamic playlists. Sets if playlist will follow DMCA rules (see web api doc for details) ChainXSPF, /// true, false If true, returns an xspf for this dynamic playlist with 2 items. The second item will be a link to the API call for the next track in the chain. Please note that this sidesteps libechonest's handling of the tracks. Mood, /// A mood to limit this playlist to, for example "happy" or "sad". Multiples of this param are okay. See the method Artist::listTerms for details on what moods are currently available Style, /// A style to limit this playlist to, for example "happy" or "sad". Multiples of this param are okay. See the method Artist::listTerms for details on what styles are currently available Adventurousness }; typedef QPair< PlaylistParam, QVariant > PlaylistParamData; typedef QVector< PlaylistParamData > PlaylistParams; /** * The various controls for a dynamic playlist. * * Please see The Echo Nest API documentation for more information */ enum DynamicControlItem { Steer = 0, SteerDescription, Rating, Ban }; typedef QPair< DynamicControlItem, QString > DynamicControl; typedef QVector< DynamicControl > DynamicControls; DynamicPlaylist(); virtual ~DynamicPlaylist(); DynamicPlaylist( const DynamicPlaylist& other ); DynamicPlaylist& operator=( const DynamicPlaylist& playlist ); /** * Start a dynamic playlist with the given parameters. * Once the QNetworkReply has finished, pass it to parseStart() * and the inital song will be populated and returned. The sessionId(), currentSong(), * and fetchNextSong() methods will then be useful. */ QNetworkReply* start( const PlaylistParams& params ) const; Song parseStart( QNetworkReply* ) throw( ParseError ); /** * The session id of this dynamic playlist. If the playlist has ended, or has not been started, * the result is empty. * */ QByteArray sessionId() const; void setSessionId( const QByteArray& id ); /** * The current song of this dynamic playlist. Once this song has been played, * or whenever is desired, call fetchNextSong() to get the next song. */ Song currentSong() const; void setCurrentSong( const Song& song ); /** * Queries The Echo Nest for the next playable song in this * dynamic playlist. * * Once the query has emitted the finished() signal, pass it to parseNextSong(), which will * return the new song to play. It will also set the current song to the newly parsed song. * * If the playlist has no more songs, the returned song object will be have no name nor id. * * @param rating The rating for the song that was just played. Ranges from 1 (lowest) to 5 (highest) * @param controls The controls to apply when fetching the next track. * */ QNetworkReply* fetchNextSong( int rating = -1 ) const; QNetworkReply* fetchNextSong( const DynamicControls& controls ) const; Song parseNextSong( QNetworkReply* reply ); /** * Returns a description of this dynamic playlist session */ QNetworkReply* fetchSessionInfo() const; SessionInfo parseSessionInfo( QNetworkReply* reply ) throw( ParseError ); /** * Generate a static playlist, according to the desired criteria. Use parseXSPFPlaylist if * you pass format=xspf to \c staticPlaylist(). */ static QNetworkReply* staticPlaylist( const PlaylistParams& params ); static SongList parseStaticPlaylist( QNetworkReply* reply ) throw( ParseError ); /** * Parse an xspf playlist. Returns the full xspf content with no modifications. */ static QByteArray parseXSPFPlaylist( QNetworkReply* reply ) throw( ParseError ); private: static QByteArray playlistParamToString( PlaylistParam param ); static QNetworkReply* generateInternal( const PlaylistParams& params, const QByteArray& type ); static QByteArray playlistSortToString(SortingType sorting); static QByteArray playlistArtistPickToString(ArtistPick pick); static QByteArray dynamicControlToString(DynamicControlItem control); QSharedDataPointer d; }; ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::DynamicPlaylist& playlist); } // namespace Q_DECLARE_METATYPE( Echonest::DynamicPlaylist ) #endif