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.
27 #include "stored_playlist.h"
30 #include "player_thread.h"
37 #include "player_control.h"
39 #include "sig_handlers.h"
41 #include "output_all.h"
44 #include "permission.h"
45 #include "replay_gain_config.h"
46 #include "decoder_list.h"
47 #include "input_init.h"
48 #include "playlist_list.h"
49 #include "state_file.h"
53 #include "event_pipe.h"
59 #include "inotify_update.h"
67 #include "archive_list.h"
87 DEFAULT_BUFFER_SIZE
= 2048,
88 DEFAULT_BUFFER_BEFORE_PLAY
= 10,
97 glue_daemonize_init(const struct options
*options
)
99 daemonize_init(config_get_string(CONF_USER
, NULL
),
100 config_get_string(CONF_GROUP
, NULL
),
101 config_get_path(CONF_PID_FILE
));
108 glue_mapper_init(void)
110 const char *music_dir
, *playlist_dir
;
112 music_dir
= config_get_path(CONF_MUSIC_DIR
);
113 #if GLIB_CHECK_VERSION(2,14,0)
114 if (music_dir
== NULL
)
115 music_dir
= g_get_user_special_dir(G_USER_DIRECTORY_MUSIC
);
118 playlist_dir
= config_get_path(CONF_PLAYLIST_DIR
);
120 mapper_init(music_dir
, playlist_dir
);
124 * Returns the database. If this function returns false, this has not
125 * succeeded, and the caller should create the database after the
126 * process has been daemonized.
129 glue_db_init_and_load(void)
131 const char *path
= config_get_path(CONF_DB_FILE
);
133 GError
*error
= NULL
;
135 if (!mapper_has_music_directory()) {
137 g_message("Found " CONF_DB_FILE
" setting without "
138 CONF_MUSIC_DIR
" - disabling database");
144 g_error(CONF_DB_FILE
" setting missing");
148 ret
= db_load(&error
);
150 g_warning("Failed to load database: %s", error
->message
);
158 /* run database update after daemonization */
166 * Configure and initialize the sticker subsystem.
169 glue_sticker_init(void)
173 GError
*error
= NULL
;
175 success
= sticker_global_init(config_get_path(CONF_STICKER_FILE
),
178 g_error("%s", error
->message
);
183 glue_state_file_init(void)
185 state_file_init(config_get_path(CONF_STATE_FILE
));
189 * Windows-only initialization of the Winsock2 library.
191 static void winsock_init(void)
197 retval
= WSAStartup(MAKEWORD(2, 2), &sockinfo
);
200 g_error("Attempt to open Winsock2 failed; error code %d\n",
204 if (LOBYTE(sockinfo
.wVersion
) != 2)
206 g_error("We use Winsock2 but your version is either too new or "
207 "old; please install Winsock 2.x\n");
213 * Initialize the decoder and player core, including the music pipe.
216 initialize_decoder_and_player(void)
218 const struct config_param
*param
;
222 unsigned buffered_chunks
;
223 unsigned buffered_before_play
;
225 param
= config_get_param(CONF_AUDIO_BUFFER_SIZE
);
227 buffer_size
= strtol(param
->value
, &test
, 10);
228 if (*test
!= '\0' || buffer_size
<= 0)
229 g_error("buffer size \"%s\" is not a positive integer, "
230 "line %i\n", param
->value
, param
->line
);
232 buffer_size
= DEFAULT_BUFFER_SIZE
;
236 buffered_chunks
= buffer_size
/ CHUNK_SIZE
;
238 if (buffered_chunks
>= 1 << 15)
239 g_error("buffer size \"%li\" is too big\n", (long)buffer_size
);
241 param
= config_get_param(CONF_BUFFER_BEFORE_PLAY
);
243 perc
= strtod(param
->value
, &test
);
244 if (*test
!= '%' || perc
< 0 || perc
> 100) {
245 g_error("buffered before play \"%s\" is not a positive "
246 "percentage and less than 100 percent, line %i",
247 param
->value
, param
->line
);
250 perc
= DEFAULT_BUFFER_BEFORE_PLAY
;
252 buffered_before_play
= (perc
/ 100) * buffered_chunks
;
253 if (buffered_before_play
> buffered_chunks
)
254 buffered_before_play
= buffered_chunks
;
256 pc_init(buffered_chunks
, buffered_before_play
);
260 * event_pipe callback function for PIPE_EVENT_IDLE
263 idle_event_emitted(void)
265 /* send "idle" notificaions to all subscribed
267 unsigned flags
= idle_get();
269 client_manager_idle_add(flags
);
272 int main(int argc
, char *argv
[])
274 struct options options
;
277 GError
*error
= NULL
;
280 daemonize_close_stdin();
283 /* initialize locale */
284 setlocale(LC_CTYPE
,"");
287 g_set_application_name("Music Player Daemon");
289 /* enable GLib's thread safety code */
297 config_global_init();
299 success
= parse_cmdline(argc
, argv
, &options
, &error
);
301 g_warning("%s", error
->message
);
306 glue_daemonize_init(&options
);
310 log_init(options
.verbose
, options
.log_stderr
);
312 success
= listen_global_init(&error
);
314 g_warning("%s", error
->message
);
319 daemonize_set_user();
321 main_task
= g_thread_self();
322 main_loop
= g_main_loop_new(NULL
, FALSE
);
323 main_cond
= g_cond_new();
326 event_pipe_register(PIPE_EVENT_IDLE
, idle_event_emitted
);
331 playlist_global_init();
333 #ifdef ENABLE_ARCHIVE
334 archive_plugin_init_all();
336 decoder_plugin_init_all();
337 update_global_init();
339 create_db
= !glue_db_init_and_load();
344 initialize_decoder_and_player();
347 audio_output_all_init();
348 client_manager_init();
349 replay_gain_global_init();
351 if (!input_stream_global_init(&error
)) {
352 g_warning("%s", error
->message
);
357 playlist_list_global_init();
359 daemonize(options
.daemon
);
361 setup_log_output(options
.log_stderr
);
370 /* the database failed to load: recreate the
372 unsigned job
= update_enqueue(NULL
, true);
374 g_error("directory update failed");
377 glue_state_file_init();
379 success
= config_get_bool(CONF_AUTO_UPDATE
, false);
380 #ifdef ENABLE_INOTIFY
381 if (success
&& mapper_has_music_directory())
382 mpd_inotify_init(config_get_unsigned(CONF_AUTO_UPDATE_DEPTH
,
386 g_warning("inotify: auto_update was disabled. enable during compilation phase");
389 config_global_check();
391 /* enable all audio outputs (if not already done by
392 playlist_state_restore() */
395 /* run the main loop */
397 g_main_loop_run(main_loop
);
401 g_main_loop_unref(main_loop
);
403 #ifdef ENABLE_INOTIFY
404 mpd_inotify_finish();
410 client_manager_deinit();
411 listen_global_finish();
412 playlist_global_finish();
416 g_debug("db_finish took %f seconds",
417 ((float)(clock()-start
))/CLOCKS_PER_SEC
);
420 sticker_global_finish();
423 g_cond_free(main_cond
);
426 playlist_list_global_finish();
427 input_stream_global_finish();
428 audio_output_all_finish();
431 path_global_finish();
435 update_global_finish();
436 decoder_plugin_deinit_all();
437 #ifdef ENABLE_ARCHIVE
438 archive_plugin_deinit_all();
440 config_global_finish();
445 stats_global_finish();