2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "player_control.h"
22 #include "decoder_control.h"
28 #include "pcm_volume.h"
34 struct player_control pc
;
36 void pc_init(unsigned buffer_chunks
, unsigned int buffered_before_play
)
38 pc
.buffer_chunks
= buffer_chunks
;
39 pc
.buffered_before_play
= buffered_before_play
;
41 pc
.mutex
= g_mutex_new();
42 pc
.cond
= g_cond_new();
44 pc
.command
= PLAYER_COMMAND_NONE
;
45 pc
.error
= PLAYER_ERROR_NOERROR
;
46 pc
.state
= PLAYER_STATE_STOP
;
47 pc
.cross_fade_seconds
= 0;
53 g_mutex_free(pc
.mutex
);
57 player_wait_decoder(struct decoder_control
*dc
)
59 /* during this function, the decoder lock is held, because
60 we're waiting for the decoder thread */
61 g_cond_wait(pc
.cond
, dc
->mutex
);
65 pc_song_deleted(const struct song
*song
)
67 if (pc
.errored_song
== song
) {
68 pc
.error
= PLAYER_ERROR_NOERROR
;
69 pc
.errored_song
= NULL
;
74 player_command_wait_locked(void)
76 while (pc
.command
!= PLAYER_COMMAND_NONE
)
77 g_cond_wait(main_cond
, pc
.mutex
);
81 player_command_locked(enum player_command cmd
)
83 assert(pc
.command
== PLAYER_COMMAND_NONE
);
87 player_command_wait_locked();
91 player_command(enum player_command cmd
)
94 player_command_locked(cmd
);
99 pc_play(struct song
*song
)
101 assert(song
!= NULL
);
103 if (pc
.state
!= PLAYER_STATE_STOP
)
104 player_command(PLAYER_COMMAND_STOP
);
106 assert(pc
.next_song
== NULL
);
108 pc_enqueue_song(song
);
110 assert(pc
.next_song
== NULL
);
112 idle_add(IDLE_PLAYER
);
117 player_command(PLAYER_COMMAND_CANCEL
);
118 assert(pc
.next_song
== NULL
);
124 player_command(PLAYER_COMMAND_CLOSE_AUDIO
);
125 assert(pc
.next_song
== NULL
);
127 idle_add(IDLE_PLAYER
);
131 pc_update_audio(void)
133 player_command(PLAYER_COMMAND_UPDATE_AUDIO
);
139 assert(pc
.thread
!= NULL
);
141 player_command(PLAYER_COMMAND_EXIT
);
142 g_thread_join(pc
.thread
);
145 idle_add(IDLE_PLAYER
);
151 if (pc
.state
!= PLAYER_STATE_STOP
) {
152 player_command(PLAYER_COMMAND_PAUSE
);
153 idle_add(IDLE_PLAYER
);
158 pc_set_pause(bool pause_flag
)
161 case PLAYER_STATE_STOP
:
164 case PLAYER_STATE_PLAY
:
169 case PLAYER_STATE_PAUSE
:
177 pc_get_status(struct player_status
*status
)
180 player_command_locked(PLAYER_COMMAND_REFRESH
);
182 status
->state
= pc
.state
;
184 if (pc
.state
!= PLAYER_STATE_STOP
) {
185 status
->bit_rate
= pc
.bit_rate
;
186 status
->audio_format
= pc
.audio_format
;
187 status
->total_time
= pc
.total_time
;
188 status
->elapsed_time
= pc
.elapsed_time
;
203 pc
.error
= PLAYER_ERROR_NOERROR
;
204 pc
.errored_song
= NULL
;
214 pc_errored_song_uri(void)
216 return song_get_uri(pc
.errored_song
);
220 pc_get_error_message(void)
226 case PLAYER_ERROR_NOERROR
:
229 case PLAYER_ERROR_FILENOTFOUND
:
230 uri
= pc_errored_song_uri();
231 error
= g_strdup_printf("file \"%s\" does not exist or is inaccessible", uri
);
235 case PLAYER_ERROR_FILE
:
236 uri
= pc_errored_song_uri();
237 error
= g_strdup_printf("problems decoding \"%s\"", uri
);
241 case PLAYER_ERROR_AUDIO
:
242 return g_strdup("problems opening audio device");
244 case PLAYER_ERROR_SYSTEM
:
245 return g_strdup("system error occured");
247 case PLAYER_ERROR_UNKTYPE
:
248 uri
= pc_errored_song_uri();
249 error
= g_strdup_printf("file type of \"%s\" is unknown", uri
);
259 pc_enqueue_song(struct song
*song
)
261 assert(song
!= NULL
);
264 assert(pc
.next_song
== NULL
);
267 player_command_locked(PLAYER_COMMAND_QUEUE
);
272 pc_seek(struct song
*song
, float seek_time
)
274 assert(song
!= NULL
);
276 if (pc
.state
== PLAYER_STATE_STOP
)
281 pc
.seek_where
= seek_time
;
282 player_command_locked(PLAYER_COMMAND_SEEK
);
285 assert(pc
.next_song
== NULL
);
287 idle_add(IDLE_PLAYER
);
293 pc_get_cross_fade(void)
295 return pc
.cross_fade_seconds
;
299 pc_set_cross_fade(float cross_fade_seconds
)
301 if (cross_fade_seconds
< 0)
302 cross_fade_seconds
= 0;
303 pc
.cross_fade_seconds
= cross_fade_seconds
;
305 idle_add(IDLE_OPTIONS
);
309 pc_get_total_play_time(void)
311 return pc
.total_play_time
;