1 //Copyright: (C) 2003 Mark Kretschmann
2 // (C) 2004 Max Howell, <max.howell@methylblue.com>
5 #ifndef AMAROK_ENGINEBASE_H
6 #define AMAROK_ENGINEBASE_H
8 #include "plugin/plugin.h" //baseclass
9 #include "amarok_export.h"
13 #include <q3valuelist.h> //stack alloc
16 #include <QObject> //baseclass
18 #include <sys/types.h>
24 * @author Mark Kretschmann
27 * This is an abstract base class that you need to derive when making your own backends.
28 * It is typdefed to EngineBase for your conveniece.
30 * The only key thing to get right is what to return from state(), as some Amarok
31 * behaviour is dependent on you returning the right state at the right time.
33 * Empty = No URL loaded and ready to play
34 * Idle = URL ready for play, but not playing, so before AND after playback
35 * Playing = Playing a stream
36 * Paused = Stream playback is paused
38 * Not returning idle when you have reached End-Of-Stream but Amarok has not told you
39 * to stop would be bad because some components behave differently when the engine is
40 * Empty or not. You are Idle because you still have a URL assigned.
42 * load( KUrl ) is a key function because after this point your engine is loaded, and
43 * Amarok will expect you to be able to play the URL until stop() or another load() is
46 * You must handle your own media, do not rely on Amarok to call stop() before play() etc.
48 * At this time, emitting stateChanged( Engine::Idle ) is not necessary, otherwise you should
49 * let Amarok know of state changes so it updates the UI correctly.
51 * Basically, reimplement everything virtual and ensure you emit stateChanged() correctly,
52 * try not to block in any function that is called by Amarok, try to keep the user informed
53 * with emit statusText()
55 * Only canDecode() needs to be thread-safe. Everything else is only called from the GUI thread.
58 #include "engine_fwd.h"
63 typedef std::vector
<int16_t> Scope
;
64 class SimpleMetaBundle
;
66 class AMAROK_EXPORT Base
: public QObject
, public Amarok::Plugin
71 /** Emitted when end of current track is reached. */
74 /** Transmits status message, the message disappears after ~2s. */
75 void statusText( const QString
& );
78 * Shows a long message in a non-invasive manner, you should prefer
79 * this over KMessageBoxes, but do use KMessageBox when you must
80 * interrupt the user or the message is very important.
82 void infoMessage( const QString
& );
84 /** Transmits metadata package. */
85 void metaData( const Engine::SimpleMetaBundle
& );
87 void metaData( const QHash
<qint64
, QString
> &newMetaData
);
89 /** Signals a change in the engine's state. */
90 void stateChanged( Engine::State
);
92 /** Shows Amarok config dialog at specified page */
93 void showConfigDialog( const QByteArray
& );
99 * Initializes the engine. Must be called after the engine was loaded.
100 * @return True if initialization was successful.
102 virtual bool init() = 0;
105 * Determines if the engine is able to play a given URL.
106 * @param url The URL of the file/stream.
107 * @return True if we can play the URL.
109 virtual bool canDecode( const KUrl
&url
) const = 0;
112 * Determines if current track is a stream.
113 * @return True if track is a stream.
115 inline bool isStream() { return m_isStream
; }
118 * Load new track for playing.
119 * @param url URL to be played.
120 * @param stream True if URL is a stream.
121 * @return True for success.
123 virtual bool load( const KUrl
&url
, bool stream
= false );
126 * Load new track and start Playback. Convenience function for Amarok to use.
127 * @param url URL to be played.
128 * @param stream True if URL is a stream.
129 * @return True for success.
131 bool play( const KUrl
&u
, bool stream
= false ) { return load( u
, stream
) && play(); }
135 * @param offset Start playing at @p msec position.
136 * @return True for success.
138 virtual bool play( uint offset
= 0 ) = 0;
140 /** Stops playback */
141 virtual void stop() = 0;
143 /** Pauses playback */
144 virtual void pause() = 0;
146 /** Resumes playback if paused */
147 virtual void unpause() = 0;
150 * Get current engine status.
151 * @return the correct State as described at the enum
153 virtual State
state() const = 0;
155 /** Get time position (msec). */
156 virtual uint
position() const = 0;
158 /** Get track length (msec). */
159 virtual uint
length() const { return 0; }
162 * Jump to new time position.
163 * @param ms New position.
165 virtual void seek( uint ms
) = 0;
168 * Determines whether media is currently loaded.
169 * @return True if media is loaded, system is ready to play.
171 inline bool loaded() const { return state() != Empty
; }
173 inline uint
volume() const { return m_volume
; }
176 * Fetch the current audio sample buffer.
177 * @return Audio sample buffer.
179 virtual const Scope
&scope() { return m_scope
; }
182 * Set new volume value.
183 * @param value Volume in range 0 to 100.
185 void setVolume( uint value
);
187 /** Set new crossfade length (msec) */
188 void setXfadeLength( int value
) { m_xfadeLength
= value
; }
190 /** Set whether to crossfade the next track
191 * Used when the engine is switching tracks automatically
192 * instead of manually.
194 void setXFadeNextTrack( bool enable
) { m_xfadeNextTrack
= enable
; }
196 /** Set whether equalizer is enabled
197 * You don't need to cache the parameters, setEqualizerParameters is called straight after this
198 * function, _always_.
200 virtual void setEqualizerEnabled( bool ) {}
202 /** Set equalizer parameters, all in range -100..100, where 0 = no adjustment
203 * @param preamp the preamplification value
204 * @param bandGains a list of 10 integers, ascending in frequency, the exact frequencies you amplify
205 * are not too-important at this time
207 virtual void setEqualizerParameters( int /*preamp*/, const Q3ValueList
<int> &/*bandGains*/ ) {}
210 /** Tries to retrieve metadata for the given url (called only if url
211 * is not in the collection). The intended usage is to retrieve
212 * information for AudiCD tracks when they are added to the playlist
213 * (i.e. before they are actually played)
214 * @param url the url of the item
215 * @param bundle the SimpleMetaBundle to fill
216 * @return true if metadata found, false otherwise
218 virtual bool metaDataForUrl(const KUrl
&, Engine::SimpleMetaBundle
&)
221 /** returns true if this engine performs some special action to play
222 * audio cds: in this case, the KUrl::List is filled with the urls of
223 * the songs in the cd...
225 * @param device the cdrom device , with QString::null meaning use engine-specific default value
226 * @param urls the list of urls for AudioCD tracks to fill
227 * @return true if the engine has the feature of reading from audio cds, false otherwise (note that this should return true also in case of error if the engine is capable of reading audio cds in general...)
229 virtual bool getAudioCDContents(const QString
&, KUrl::List
&)
232 /** flush the current stream buffer */
233 virtual bool flushBuffer() { return false; }
235 /** allow the engine to perform necessary work on changes in the playlist **/
236 virtual void playlistChanged() { }
241 /** Shows the Amarok configuration dialog at the engine page */
242 void showEngineConfigDialog() { emit
showConfigDialog( "Engine" ); }
244 virtual void setVolumeSW( uint percent
) = 0;
246 /** Converts master volume to a logarithmic scale */
247 static uint
makeVolumeLogarithmic( uint volume
);
249 Base( const Base
& ); //disable copy constructor
250 const Base
&operator=( const Base
& ); //disable copy constructor
253 bool m_xfadeNextTrack
;
256 static const int SCOPESIZE
= 1024;
264 class SimpleMetaBundle
{