Big commit:
[someplayer] / src / player / player.cpp
1 #include "player.h"
2 #include <phonon/MediaSource>
3
4 using namespace SomePlayer::Playback;
5 using namespace SomePlayer::DataObjects;
6
7 Player::Player(QObject *parent) :
8     QObject(parent)
9 {
10         _player = new Phonon::MediaObject(this);
11         _output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
12         _player->setTickInterval(1000);
13         connect(_player, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(_stateChanged(Phonon::State,Phonon::State)));
14         connect(_player, SIGNAL(tick(qint64)), this, SLOT(_tick(qint64)));
15         Phonon::createPath(_player, _output);
16         int seed = reinterpret_cast<int> (_player);
17         qsrand(seed);
18         _random = false;
19         _repeat = false;
20         _current = -1;
21 }
22
23 void Player::setTrackId(int id) {
24         _current = id;
25         if (!_history.isEmpty() && _history.top() != _current || _history.isEmpty()) {
26                 _history.push(_current);
27         }
28         _track = _playlist.tracks().at(_current);
29         _set_source();
30         _state = PLAYER_LOADING;
31         emit stateChanged(_state);
32 }
33
34 void Player::toggle() {
35         if (_state == PLAYER_PLAYING) { // pause
36                 _player->pause();
37                 _state = PLAYER_PAUSED;
38                 emit stateChanged(_state);
39         } else { //play
40                 play();
41         }
42 }
43
44 void Player::stop() {
45         _player->stop();
46         _state = PLAYER_STOPPED;
47         emit stateChanged(_state);
48 }
49
50 void Player::next() {
51         int count = _playlist.tracks().count();
52         if (count == 0) {
53                 stop(); // empty playlist
54                 return;
55         }
56         _history.push(_current % count);
57         if (!_queue.isEmpty()) {
58                 _current = _queue.dequeue();
59         } else {
60                 if (_random) {
61                         _current = (count + (qrand()  + qrand() + qrand()) % count) % count;
62                 } else {
63                         _current = _current + 1;
64                 }
65         }
66         if (_random && _history.count() >= count && !_repeat ||
67                 !_repeat && _current >= count) {
68                 _history.clear();
69                 stop();
70         } else {
71                 _current %= count;
72                 _track = _playlist.tracks().at(_current);
73                 _set_source();
74                 play();
75         }
76 }
77
78 void Player::_set_source() {
79         _player->setCurrentSource(Phonon::MediaSource(_track.source()));
80         emit trackChanged(_track);
81 }
82
83 void Player::prev() {
84         if (_history.count() > 0) {
85                 _queue.push_front(_current);
86                 _current = _history.pop();
87                 _track = _playlist.tracks().at(_current);
88         }
89         _set_source();
90         play();
91 }
92
93 void Player::_stateChanged(Phonon::State newState, Phonon::State oldState) {
94         switch (newState) {
95         case Phonon::PlayingState:
96                 if (_state == PLAYER_LOADING) {
97                         _state = PLAYER_PLAYING;
98                         emit stateChanged(_state);
99                 }
100                 break;
101         case Phonon::StoppedState:
102                 break;
103         case Phonon::LoadingState:
104                 break;
105         case Phonon::PausedState:
106                 if (_state == PLAYER_PLAYING) {
107                         next();
108                 } else if (_state == PLAYER_ERROR) {
109                         play();
110                 }
111                 break;
112         case Phonon::BufferingState:
113                 break;
114         case Phonon::ErrorState:
115                 _state = PLAYER_ERROR;
116                 qDebug() << _player->errorString();
117                 break;
118         }
119 }
120
121 void Player::_tick(qint64 ticks) {
122         int done = ticks/1000;
123         int all = _track.metadata().length();
124         emit tick(done, all);
125         if (done+2 == all) {
126                 _track.setCount(_track.count()+1);
127                 emit trackDone(_track);
128         }
129 }
130
131 void Player::setPlaylist(Playlist playlist) {
132         _playlist = playlist;
133         _history.clear();
134 }
135
136 void Player::seek(int s) {
137         _player->seek(s*1000);
138 }
139
140 void Player::play() {
141         _state = PLAYER_PLAYING;
142         emit stateChanged(_state);
143         if (_current == -1) {
144                 _current = 0;
145                 _track = _playlist.tracks().at(0);
146                 _set_source();
147         }
148         _player->play();
149 }
150
151 void Player::enqueue(int id) {
152         _queue.enqueue(id);
153 }