diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/DumpDatabase.cxx | 149 | ||||
-rw-r--r-- | test/FakeReplayGainConfig.cxx (renamed from test/signals.h) | 16 | ||||
-rw-r--r-- | test/FakeSong.cxx (renamed from test/test_pcm_all.h) | 47 | ||||
-rw-r--r-- | test/dump_playlist.cxx (renamed from test/dump_playlist.c) | 157 | ||||
-rw-r--r-- | test/dump_rva2.cxx (renamed from test/dump_rva2.c) | 47 | ||||
-rw-r--r-- | test/dump_text_file.cxx (renamed from test/dump_text_file.c) | 101 | ||||
-rw-r--r-- | test/read_conf.cxx (renamed from test/read_conf.c) | 25 | ||||
-rw-r--r-- | test/read_mixer.cxx (renamed from test/read_mixer.c) | 85 | ||||
-rw-r--r-- | test/read_tags.cxx (renamed from test/read_tags.c) | 161 | ||||
-rw-r--r-- | test/run_convert.cxx (renamed from test/run_convert.c) | 55 | ||||
-rw-r--r-- | test/run_decoder.cxx (renamed from test/run_decoder.c) | 141 | ||||
-rw-r--r-- | test/run_encoder.cxx (renamed from test/run_encoder.c) | 72 | ||||
-rw-r--r-- | test/run_filter.cxx (renamed from test/run_filter.c) | 116 | ||||
-rw-r--r-- | test/run_inotify.cxx (renamed from test/run_inotify.c) | 47 | ||||
-rw-r--r-- | test/run_input.cxx (renamed from test/run_input.c) | 103 | ||||
-rw-r--r-- | test/run_normalize.cxx (renamed from test/run_normalize.c) | 21 | ||||
-rw-r--r-- | test/run_output.cxx (renamed from test/run_output.c) | 144 | ||||
-rw-r--r-- | test/run_resolver.cxx (renamed from test/run_resolver.c) | 20 | ||||
-rw-r--r-- | test/run_tcp_connect.c | 164 | ||||
-rw-r--r-- | test/software_volume.cxx (renamed from test/software_volume.c) | 28 | ||||
-rw-r--r-- | test/test_pcm_all.hxx (renamed from test/signals.c) | 84 | ||||
-rw-r--r-- | test/test_pcm_channels.cxx (renamed from test/test_pcm_channels.c) | 45 | ||||
-rw-r--r-- | test/test_pcm_dither.cxx (renamed from test/test_pcm_dither.c) | 51 | ||||
-rw-r--r-- | test/test_pcm_format.cxx | 116 | ||||
-rw-r--r-- | test/test_pcm_main.cxx (renamed from test/test_pcm_main.c) | 14 | ||||
-rw-r--r-- | test/test_pcm_mix.cxx | 84 | ||||
-rw-r--r-- | test/test_pcm_pack.cxx (renamed from test/test_pcm_pack.c) | 44 | ||||
-rw-r--r-- | test/test_pcm_util.hxx | 85 | ||||
-rw-r--r-- | test/test_pcm_volume.cxx (renamed from test/test_pcm_volume.c) | 131 | ||||
-rw-r--r-- | test/test_queue_priority.c | 175 | ||||
-rw-r--r-- | test/test_queue_priority.cxx | 188 | ||||
-rw-r--r-- | test/test_vorbis_encoder.c | 111 | ||||
-rw-r--r-- | test/test_vorbis_encoder.cxx | 106 | ||||
-rw-r--r-- | test/visit_archive.cxx | 121 |
34 files changed, 1628 insertions, 1426 deletions
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx new file mode 100644 index 000000000..395ff4f23 --- /dev/null +++ b/test/DumpDatabase.cxx @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2003-2012 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "DatabaseRegistry.hxx" +#include "DatabasePlugin.hxx" +#include "DatabaseSelection.hxx" +#include "Directory.hxx" +#include "Song.hxx" +#include "PlaylistVector.hxx" +#include "ConfigGlobal.hxx" +#include "ConfigData.hxx" +#include "tag/TagConfig.hxx" +#include "fs/Path.hxx" +#include "util/Error.hxx" + +#include <glib.h> + +#include <iostream> +using std::cout; +using std::cerr; +using std::endl; + +#include <stdlib.h> + +static void +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) +{ + if (log_domain != NULL) + g_printerr("%s: %s\n", log_domain, message); + else + g_printerr("%s\n", message); +} + +static bool +DumpDirectory(const Directory &directory, Error &) +{ + cout << "D " << directory.path << endl; + return true; +} + +static bool +DumpSong(Song &song, Error &) +{ + cout << "S " << song.parent->path << "/" << song.uri << endl; + return true; +} + +static bool +DumpPlaylist(const PlaylistInfo &playlist, + const Directory &directory, Error &) +{ + cout << "P " << directory.path << "/" << playlist.name.c_str() << endl; + return true; +} + +int +main(int argc, char **argv) +{ + if (argc != 3) { + cerr << "Usage: DumpDatabase CONFIG PLUGIN" << endl; + return 1; + } + + const Path config_path = Path::FromFS(argv[1]); + const char *const plugin_name = argv[2]; + + const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name); + if (plugin == NULL) { + cerr << "No such database plugin: " << plugin_name << endl; + return EXIT_FAILURE; + } + + /* initialize GLib */ + +#if !GLIB_CHECK_VERSION(2,32,0) + g_thread_init(nullptr); +#endif + + g_log_set_default_handler(my_log_func, nullptr); + + /* initialize MPD */ + + config_global_init(); + + Error error; + if (!ReadConfigFile(config_path, error)) { + cerr << error.GetMessage() << endl; + return EXIT_FAILURE; + } + + TagLoadConfig(); + + /* do it */ + + const struct config_param *path = config_get_param(CONF_DB_FILE); + config_param param("database", path->line); + if (path != nullptr) + param.AddBlockParam("path", path->value, path->line); + + Database *db = plugin->create(param, error); + + if (db == nullptr) { + cerr << error.GetMessage() << endl; + return EXIT_FAILURE; + } + + if (!db->Open(error)) { + delete db; + cerr << error.GetMessage() << endl; + return EXIT_FAILURE; + } + + const DatabaseSelection selection("", true); + + if (!db->Visit(selection, DumpDirectory, DumpSong, DumpPlaylist, + error)) { + db->Close(); + delete db; + cerr << error.GetMessage() << endl; + return EXIT_FAILURE; + } + + db->Close(); + delete db; + + /* deinitialize everything */ + + config_global_finish(); + + return EXIT_SUCCESS; +} diff --git a/test/signals.h b/test/FakeReplayGainConfig.cxx index e524d35e2..3305b79a3 100644 --- a/test/signals.h +++ b/test/FakeReplayGainConfig.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,13 +17,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef MPD_SIGNALS_H -#define MPD_SIGNALS_H +#include "config.h" +#include "ReplayGainConfig.hxx" -void -on_quit(void); - -void -signals_init(void); - -#endif +float replay_gain_preamp = 1.0; +float replay_gain_missing_preamp = 1.0; +bool replay_gain_limit = true; diff --git a/test/test_pcm_all.h b/test/FakeSong.cxx index 493619b55..ef7879f1b 100644 --- a/test/test_pcm_all.h +++ b/test/FakeSong.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2012 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,40 +17,17 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef MPD_TEST_PCM_ALL_H -#define MPD_TEST_PCM_ALL_H +#include "config.h" +#include "Song.hxx" +#include "directory.h" +#include "gcc.h" -void -test_pcm_dither_24(void); +#include <stdlib.h> -void -test_pcm_dither_32(void); +struct directory detached_root; -void -test_pcm_pack_24(void); - -void -test_pcm_unpack_24(void); - -void -test_pcm_channels_16(void); - -void -test_pcm_channels_32(void); - -void -test_pcm_volume_8(void); - -void -test_pcm_volume_16(void); - -void -test_pcm_volume_24(void); - -void -test_pcm_volume_32(void); - -void -test_pcm_volume_float(void); - -#endif +Song * +song_dup_detached(gcc_unused const Song *src) +{ + abort(); +} diff --git a/test/dump_playlist.c b/test/dump_playlist.cxx index 84ac69045..2f6b3ed2a 100644 --- a/test/dump_playlist.c +++ b/test/dump_playlist.cxx @@ -18,26 +18,33 @@ */ #include "config.h" -#include "io_thread.h" -#include "input_init.h" -#include "input_stream.h" -#include "tag_pool.h" -#include "tag_save.h" -#include "conf.h" -#include "song.h" -#include "decoder_api.h" -#include "decoder_list.h" -#include "playlist_list.h" -#include "playlist_plugin.h" +#include "TagSave.hxx" +#include "Song.hxx" +#include "SongEnumerator.hxx" +#include "Directory.hxx" +#include "InputStream.hxx" +#include "ConfigGlobal.hxx" +#include "DecoderAPI.hxx" +#include "DecoderList.hxx" +#include "InputInit.hxx" +#include "IOThread.hxx" +#include "PlaylistRegistry.hxx" +#include "PlaylistPlugin.hxx" +#include "fs/Path.hxx" +#include "util/Error.hxx" +#include "Log.hxx" #include <glib.h> #include <unistd.h> #include <stdlib.h> +Directory::Directory() {} +Directory::~Directory() {} + static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -46,69 +53,70 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, } void -decoder_initialized(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED const struct audio_format *audio_format, - G_GNUC_UNUSED bool seekable, - G_GNUC_UNUSED float total_time) +decoder_initialized(gcc_unused struct decoder *decoder, + gcc_unused const AudioFormat audio_format, + gcc_unused bool seekable, + gcc_unused float total_time) { } -enum decoder_command -decoder_get_command(G_GNUC_UNUSED struct decoder *decoder) +DecoderCommand +decoder_get_command(gcc_unused struct decoder *decoder) { - return DECODE_COMMAND_NONE; + return DecoderCommand::NONE; } void -decoder_command_finished(G_GNUC_UNUSED struct decoder *decoder) +decoder_command_finished(gcc_unused struct decoder *decoder) { } double -decoder_seek_where(G_GNUC_UNUSED struct decoder *decoder) +decoder_seek_where(gcc_unused struct decoder *decoder) { return 1.0; } void -decoder_seek_error(G_GNUC_UNUSED struct decoder *decoder) +decoder_seek_error(gcc_unused struct decoder *decoder) { } size_t -decoder_read(G_GNUC_UNUSED struct decoder *decoder, +decoder_read(gcc_unused struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { - return input_stream_lock_read(is, buffer, length, NULL); + Error error; + return is->LockRead(buffer, length, error); } void -decoder_timestamp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED double t) +decoder_timestamp(gcc_unused struct decoder *decoder, + gcc_unused double t) { } -enum decoder_command -decoder_data(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, +DecoderCommand +decoder_data(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, const void *data, size_t datalen, - G_GNUC_UNUSED uint16_t kbit_rate) + gcc_unused uint16_t kbit_rate) { - G_GNUC_UNUSED ssize_t nbytes = write(1, data, datalen); - return DECODE_COMMAND_NONE; + gcc_unused ssize_t nbytes = write(1, data, datalen); + return DecoderCommand::NONE; } -enum decoder_command -decoder_tag(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, - G_GNUC_UNUSED const struct tag *tag) +DecoderCommand +decoder_tag(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, + gcc_unused Tag &&tag) { - return DECODE_COMMAND_NONE; + return DecoderCommand::NONE; } -float -decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, +void +decoder_replay_gain(gcc_unused struct decoder *decoder, const struct replay_gain_info *replay_gain_info) { const struct replay_gain_tuple *tuple = @@ -121,13 +129,10 @@ decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, if (replay_gain_tuple_defined(tuple)) g_printerr("replay_gain[track]: gain=%f peak=%f\n", tuple->gain, tuple->peak); - - return 0.0; } void -decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED float replay_gain_db, +decoder_mixramp(gcc_unused struct decoder *decoder, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -138,44 +143,39 @@ int main(int argc, char **argv) { const char *uri; struct input_stream *is = NULL; - bool success; - GError *error = NULL; - struct playlist_provider *playlist; - struct song *song; + Song *song; if (argc != 3) { g_printerr("Usage: dump_playlist CONFIG URI\n"); return 1; } + const Path config_path = Path::FromFS(argv[1]); uri = argv[2]; /* initialize GLib */ +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + g_log_set_default_handler(my_log_func, NULL); /* initialize MPD */ - tag_pool_init(); config_global_init(); - success = config_read_file(argv[1], &error); - if (!success) { - g_printerr("%s\n", error->message); - g_error_free(error); + + Error error; + if (!ReadConfigFile(config_path, error)) { + g_printerr("%s\n", error.GetMessage()); return 1; } io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } + io_thread_start(); - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); + if (!input_stream_global_init(error)) { + LogError(error); return 2; } @@ -184,30 +184,29 @@ int main(int argc, char **argv) /* open the playlist */ - GMutex *mutex = g_mutex_new(); - GCond *cond = g_cond_new(); + Mutex mutex; + Cond cond; - playlist = playlist_list_open_uri(uri, mutex, cond); + auto playlist = playlist_list_open_uri(uri, mutex, cond); if (playlist == NULL) { /* open the stream and wait until it becomes ready */ - is = input_stream_open(uri, mutex, cond, &error); + is = input_stream::Open(uri, mutex, cond, error); if (is == NULL) { - if (error != NULL) { - g_warning("%s", error->message); - g_error_free(error); - } else - g_printerr("input_stream_open() failed\n"); + if (error.IsDefined()) + LogError(error); + else + g_printerr("input_stream::Open() failed\n"); return 2; } - input_stream_lock_wait_ready(is); + is->LockWaitReady(); /* open the playlist */ playlist = playlist_list_open_stream(is, uri); if (playlist == NULL) { - input_stream_close(is); + is->Close(); g_printerr("Failed to open playlist\n"); return 2; } @@ -215,7 +214,7 @@ int main(int argc, char **argv) /* dump the playlist */ - while ((song = playlist_plugin_read(playlist)) != NULL) { + while ((song = playlist->NextSong()) != NULL) { g_print("%s\n", song->uri); if (song->end_ms > 0) @@ -230,26 +229,22 @@ int main(int argc, char **argv) (song->start_ms / 1000) % 60); if (song->tag != NULL) - tag_save(stdout, song->tag); + tag_save(stdout, *song->tag); - song_free(song); + song->Free(); } /* deinitialize everything */ - playlist_plugin_close(playlist); + delete playlist; if (is != NULL) - input_stream_close(is); - - g_cond_free(cond); - g_mutex_free(mutex); + is->Close(); decoder_plugin_deinit_all(); playlist_list_global_finish(); input_stream_global_finish(); io_thread_deinit(); config_global_finish(); - tag_pool_deinit(); return 0; } diff --git a/test/dump_rva2.c b/test/dump_rva2.cxx index 4a726518a..3206f970a 100644 --- a/test/dump_rva2.c +++ b/test/dump_rva2.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,14 +18,16 @@ */ #include "config.h" -#include "tag_id3.h" -#include "tag_rva2.h" -#include "replay_gain_info.h" -#include "conf.h" -#include "tag.h" +#include "tag/TagId3.hxx" +#include "tag/TagRva2.hxx" +#include "ReplayGainInfo.hxx" +#include "ConfigGlobal.hxx" +#include "util/Error.hxx" #include <id3tag.h> +#include <glib.h> + #ifdef HAVE_LOCALE_H #include <locale.h> #endif @@ -33,33 +35,14 @@ #include <stdlib.h> const char * -config_get_string(G_GNUC_UNUSED const char *name, const char *default_value) +config_get_string(gcc_unused enum ConfigOption option, + const char *default_value) { return default_value; } -struct tag * -tag_new(void) -{ - return NULL; -} - -void -tag_add_item_n(G_GNUC_UNUSED struct tag *tag, G_GNUC_UNUSED enum tag_type type, - G_GNUC_UNUSED const char *value, G_GNUC_UNUSED size_t len) -{ -} - -void -tag_free(struct tag *tag) -{ - g_free(tag); -} - int main(int argc, char **argv) { - GError *error = NULL; - #ifdef HAVE_LOCALE_H /* initialize locale */ setlocale(LC_CTYPE,""); @@ -72,12 +55,12 @@ int main(int argc, char **argv) const char *path = argv[1]; - struct id3_tag *tag = tag_id3_load(path, &error); + Error error; + struct id3_tag *tag = tag_id3_load(path, error); if (tag == NULL) { - if (error != NULL) { - g_printerr("%s\n", error->message); - g_error_free(error); - } else + if (error.IsDefined()) + g_printerr("%s\n", error.GetMessage()); + else g_printerr("No ID3 tag found\n"); return EXIT_FAILURE; diff --git a/test/dump_text_file.c b/test/dump_text_file.cxx index f14371441..685f0fbb9 100644 --- a/test/dump_text_file.c +++ b/test/dump_text_file.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,16 +18,17 @@ */ #include "config.h" -#include "io_thread.h" -#include "input_init.h" -#include "input_stream.h" -#include "text_input_stream.h" -#include "tag_pool.h" -#include "conf.h" +#include "IOThread.hxx" +#include "InputInit.hxx" +#include "InputStream.hxx" +#include "ConfigGlobal.hxx" #include "stdbin.h" +#include "TextInputStream.hxx" +#include "util/Error.hxx" +#include "Log.hxx" #ifdef ENABLE_ARCHIVE -#include "archive_list.h" +#include "ArchiveList.hxx" #endif #include <glib.h> @@ -37,8 +38,8 @@ #include <stdlib.h> static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -47,56 +48,53 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, } static void -dump_text_file(struct text_input_stream *is) +dump_text_file(TextInputStream &is) { - const char *line; - while ((line = text_input_stream_read(is)) != NULL) - printf("'%s'\n", line); + std::string line; + while (is.ReadLine(line)) + printf("'%s'\n", line.c_str()); } static int dump_input_stream(struct input_stream *is) { - GError *error = NULL; + Error error; - input_stream_lock(is); + is->Lock(); /* wait until the stream becomes ready */ - input_stream_wait_ready(is); + is->WaitReady(); - if (!input_stream_check(is, &error)) { - g_warning("%s", error->message); - g_error_free(error); - input_stream_unlock(is); + if (!is->Check(error)) { + LogError(error); + is->Unlock(); return EXIT_FAILURE; } /* read data and tags from the stream */ - input_stream_unlock(is); - - struct text_input_stream *tis = text_input_stream_new(is); - dump_text_file(tis); - text_input_stream_free(tis); + is->Unlock(); + { + TextInputStream tis(is); + dump_text_file(tis); + } - input_stream_lock(is); + is->Lock(); - if (!input_stream_check(is, &error)) { - g_warning("%s", error->message); - g_error_free(error); - input_stream_unlock(is); + if (!is->Check(error)) { + LogError(error); + is->Unlock(); return EXIT_FAILURE; } - input_stream_unlock(is); + is->Unlock(); return 0; } int main(int argc, char **argv) { - GError *error = NULL; struct input_stream *is; int ret; @@ -107,52 +105,46 @@ int main(int argc, char **argv) /* initialize GLib */ +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + g_log_set_default_handler(my_log_func, NULL); /* initialize MPD */ - tag_pool_init(); config_global_init(); io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } + io_thread_start(); #ifdef ENABLE_ARCHIVE archive_plugin_init_all(); #endif - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); + Error error; + if (!input_stream_global_init(error)) { + LogError(error); return 2; } /* open the stream and dump it */ - GMutex *mutex = g_mutex_new(); - GCond *cond = g_cond_new(); + Mutex mutex; + Cond cond; - is = input_stream_open(argv[1], mutex, cond, &error); + is = input_stream::Open(argv[1], mutex, cond, error); if (is != NULL) { ret = dump_input_stream(is); - input_stream_close(is); + is->Close(); } else { - if (error != NULL) { - g_warning("%s", error->message); - g_error_free(error); - } else - g_printerr("input_stream_open() failed\n"); + if (error.IsDefined()) + LogError(error); + else + g_printerr("input_stream::Open() failed\n"); ret = 2; } - g_cond_free(cond); - g_mutex_free(mutex); - /* deinitialize everything */ input_stream_global_finish(); @@ -164,7 +156,6 @@ int main(int argc, char **argv) io_thread_deinit(); config_global_finish(); - tag_pool_deinit(); return ret; } diff --git a/test/read_conf.c b/test/read_conf.cxx index 4f6005c6f..d5eacec67 100644 --- a/test/read_conf.c +++ b/test/read_conf.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,16 +18,18 @@ */ #include "config.h" -#include "conf.h" +#include "ConfigGlobal.hxx" +#include "fs/Path.hxx" +#include "util/Error.hxx" #include <glib.h> #include <assert.h> static void -my_log_func(G_GNUC_UNUSED const gchar *log_domain, +my_log_func(gcc_unused const gchar *log_domain, GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) + const gchar *message, gcc_unused gpointer user_data) { if (log_level > G_LOG_LEVEL_WARNING) return; @@ -42,22 +44,23 @@ int main(int argc, char **argv) return 1; } - const char *path = argv[1]; + const Path config_path = Path::FromFS(argv[1]); const char *name = argv[2]; g_log_set_default_handler(my_log_func, NULL); config_global_init(); - GError *error = NULL; - bool success = config_read_file(path, &error); - if (!success) { - g_printerr("%s:", error->message); - g_error_free(error); + Error error; + if (!ReadConfigFile(config_path, error)) { + g_printerr("%s:", error.GetMessage()); return 1; } - const char *value = config_get_string(name, NULL); + ConfigOption option = ParseConfigOptionName(name); + const char *value = option != CONF_MAX + ? config_get_string(option, nullptr) + : nullptr; int ret; if (value != NULL) { g_print("%s\n", value); diff --git a/test/read_mixer.c b/test/read_mixer.cxx index f6de8177d..8426443ae 100644 --- a/test/read_mixer.c +++ b/test/read_mixer.cxx @@ -18,11 +18,15 @@ */ #include "config.h" -#include "mixer_control.h" -#include "mixer_list.h" -#include "filter_registry.h" -#include "pcm_volume.h" -#include "event_pipe.h" +#include "MixerControl.hxx" +#include "MixerList.hxx" +#include "FilterRegistry.hxx" +#include "pcm/PcmVolume.hxx" +#include "GlobalEvents.hxx" +#include "Main.hxx" +#include "event/Loop.hxx" +#include "ConfigData.hxx" +#include "util/Error.hxx" #include <glib.h> @@ -30,35 +34,37 @@ #include <string.h> #include <unistd.h> +EventLoop *main_loop; + #ifdef HAVE_PULSE -#include "output/pulse_output_plugin.h" +#include "output/PulseOutputPlugin.hxx" void -pulse_output_lock(G_GNUC_UNUSED struct pulse_output *po) +pulse_output_lock(gcc_unused PulseOutput *po) { } void -pulse_output_unlock(G_GNUC_UNUSED struct pulse_output *po) +pulse_output_unlock(gcc_unused PulseOutput *po) { } void -pulse_output_set_mixer(G_GNUC_UNUSED struct pulse_output *po, - G_GNUC_UNUSED struct pulse_mixer *pm) +pulse_output_set_mixer(gcc_unused PulseOutput *po, + gcc_unused PulseMixer *pm) { } void -pulse_output_clear_mixer(G_GNUC_UNUSED struct pulse_output *po, - G_GNUC_UNUSED struct pulse_mixer *pm) +pulse_output_clear_mixer(gcc_unused PulseOutput *po, + gcc_unused PulseMixer *pm) { } bool -pulse_output_set_volume(G_GNUC_UNUSED struct pulse_output *po, - G_GNUC_UNUSED const struct pa_cvolume *volume, - G_GNUC_UNUSED GError **error_r) +pulse_output_set_volume(gcc_unused PulseOutput *po, + gcc_unused const struct pa_cvolume *volume, + gcc_unused Error &error) { return false; } @@ -66,17 +72,17 @@ pulse_output_set_volume(G_GNUC_UNUSED struct pulse_output *po, #endif #ifdef HAVE_ROAR -#include "output/roar_output_plugin.h" +#include "output/RoarOutputPlugin.hxx" int -roar_output_get_volume(G_GNUC_UNUSED struct roar *roar) +roar_output_get_volume(gcc_unused RoarOutput *roar) { return -1; } bool -roar_output_set_volume(G_GNUC_UNUSED struct roar *roar, - G_GNUC_UNUSED unsigned volume) +roar_output_set_volume(gcc_unused RoarOutput *roar, + gcc_unused unsigned volume) { return true; } @@ -84,31 +90,28 @@ roar_output_set_volume(G_GNUC_UNUSED struct roar *roar, #endif void -event_pipe_emit(G_GNUC_UNUSED enum pipe_event event) +GlobalEvents::Emit(gcc_unused Event event) { } const struct filter_plugin * -filter_plugin_by_name(G_GNUC_UNUSED const char *name) +filter_plugin_by_name(gcc_unused const char *name) { assert(false); return NULL; } bool -pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED size_t length, - G_GNUC_UNUSED enum sample_format format, - G_GNUC_UNUSED int volume) +pcm_volume(gcc_unused void *buffer, gcc_unused size_t length, + gcc_unused SampleFormat format, + gcc_unused int volume) { assert(false); return false; } -int main(int argc, G_GNUC_UNUSED char **argv) +int main(int argc, gcc_unused char **argv) { - GError *error = NULL; - struct mixer *mixer; - bool success; int volume; if (argc != 2) { @@ -116,34 +119,38 @@ int main(int argc, G_GNUC_UNUSED char **argv) return 1; } +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif - mixer = mixer_new(&alsa_mixer_plugin, NULL, NULL, &error); + main_loop = new EventLoop(EventLoop::Default()); + + Error error; + Mixer *mixer = mixer_new(&alsa_mixer_plugin, nullptr, + config_param(), error); if (mixer == NULL) { - g_printerr("mixer_new() failed: %s\n", error->message); - g_error_free(error); + g_printerr("mixer_new() failed: %s\n", error.GetMessage()); return 2; } - success = mixer_open(mixer, &error); - if (!success) { + if (!mixer_open(mixer, error)) { mixer_free(mixer); - g_printerr("failed to open the mixer: %s\n", error->message); - g_error_free(error); + g_printerr("failed to open the mixer: %s\n", error.GetMessage()); return 2; } - volume = mixer_get_volume(mixer, &error); + volume = mixer_get_volume(mixer, error); mixer_close(mixer); mixer_free(mixer); + delete main_loop; + assert(volume >= -1 && volume <= 100); if (volume < 0) { - if (error != NULL) { + if (error.IsDefined()) { g_printerr("failed to read volume: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); } else g_printerr("failed to read volume\n"); return 2; diff --git a/test/read_tags.c b/test/read_tags.cxx index faf9a45c0..b4e5b2bb0 100644 --- a/test/read_tags.c +++ b/test/read_tags.cxx @@ -18,17 +18,17 @@ */ #include "config.h" -#include "io_thread.h" -#include "decoder_list.h" -#include "decoder_api.h" -#include "input_init.h" -#include "input_stream.h" -#include "audio_format.h" -#include "pcm_volume.h" -#include "tag_ape.h" -#include "tag_id3.h" -#include "tag_handler.h" -#include "idle.h" +#include "IOThread.hxx" +#include "DecoderList.hxx" +#include "DecoderAPI.hxx" +#include "InputInit.hxx" +#include "InputStream.hxx" +#include "AudioFormat.hxx" +#include "tag/TagHandler.hxx" +#include "tag/TagId3.hxx" +#include "tag/ApeTag.hxx" +#include "util/Error.hxx" +#include "Log.hxx" #include <glib.h> @@ -40,94 +40,74 @@ #include <locale.h> #endif -/** - * No-op dummy. - */ void -idle_add(G_GNUC_UNUSED unsigned flags) -{ -} - -/** - * No-op dummy. - */ -bool -pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED size_t length, - G_GNUC_UNUSED enum sample_format format, - G_GNUC_UNUSED int volume) +decoder_initialized(gcc_unused struct decoder *decoder, + gcc_unused const AudioFormat audio_format, + gcc_unused bool seekable, + gcc_unused float total_time) { - return true; } -void -decoder_initialized(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED const struct audio_format *audio_format, - G_GNUC_UNUSED bool seekable, - G_GNUC_UNUSED float total_time) +DecoderCommand +decoder_get_command(gcc_unused struct decoder *decoder) { + return DecoderCommand::NONE; } -enum decoder_command -decoder_get_command(G_GNUC_UNUSED struct decoder *decoder) +void decoder_command_finished(gcc_unused struct decoder *decoder) { - return DECODE_COMMAND_NONE; } -void decoder_command_finished(G_GNUC_UNUSED struct decoder *decoder) -{ -} - -double decoder_seek_where(G_GNUC_UNUSED struct decoder *decoder) +double decoder_seek_where(gcc_unused struct decoder *decoder) { return 1.0; } -void decoder_seek_error(G_GNUC_UNUSED struct decoder *decoder) +void decoder_seek_error(gcc_unused struct decoder *decoder) { } size_t -decoder_read(G_GNUC_UNUSED struct decoder *decoder, +decoder_read(gcc_unused struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { - return input_stream_lock_read(is, buffer, length, NULL); + Error error; + return is->LockRead(buffer, length, error); } void -decoder_timestamp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED double t) +decoder_timestamp(gcc_unused struct decoder *decoder, + gcc_unused double t) { } -enum decoder_command -decoder_data(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, +DecoderCommand +decoder_data(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, const void *data, size_t datalen, - G_GNUC_UNUSED uint16_t bit_rate) + gcc_unused uint16_t bit_rate) { - G_GNUC_UNUSED ssize_t nbytes = write(1, data, datalen); - return DECODE_COMMAND_NONE; + gcc_unused ssize_t nbytes = write(1, data, datalen); + return DecoderCommand::NONE; } -enum decoder_command -decoder_tag(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, - G_GNUC_UNUSED const struct tag *tag) +DecoderCommand +decoder_tag(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, + gcc_unused Tag &&tag) { - return DECODE_COMMAND_NONE; + return DecoderCommand::NONE; } -float -decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED const struct replay_gain_info *replay_gain_info) +void +decoder_replay_gain(gcc_unused struct decoder *decoder, + gcc_unused const struct replay_gain_info *replay_gain_info) { - return 0.0; } void -decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED float replay_gain_db, +decoder_mixramp(gcc_unused struct decoder *decoder, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -137,33 +117,32 @@ decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, static bool empty = true; static void -print_duration(unsigned seconds, G_GNUC_UNUSED void *ctx) +print_duration(unsigned seconds, gcc_unused void *ctx) { g_print("duration=%d\n", seconds); } static void -print_tag(enum tag_type type, const char *value, G_GNUC_UNUSED void *ctx) +print_tag(enum tag_type type, const char *value, gcc_unused void *ctx) { g_print("[%s]=%s\n", tag_item_names[type], value); empty = false; } static void -print_pair(const char *name, const char *value, G_GNUC_UNUSED void *ctx) +print_pair(const char *name, const char *value, gcc_unused void *ctx) { g_print("\"%s\"=%s\n", name, value); } static const struct tag_handler print_handler = { - .duration = print_duration, - .tag = print_tag, - .pair = print_pair, + print_duration, + print_tag, + print_pair, }; int main(int argc, char **argv) { - GError *error = NULL; const char *decoder_name, *path; const struct decoder_plugin *plugin; @@ -180,17 +159,16 @@ int main(int argc, char **argv) decoder_name = argv[1]; path = argv[2]; +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } + io_thread_start(); - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); + Error error; + if (!input_stream_global_init(error)) { + LogError(error); return 2; } @@ -205,25 +183,34 @@ int main(int argc, char **argv) bool success = decoder_plugin_scan_file(plugin, path, &print_handler, NULL); if (!success && plugin->scan_stream != NULL) { - GMutex *mutex = g_mutex_new(); - GCond *cond = g_cond_new(); - - struct input_stream *is = - input_stream_open(path, mutex, cond, &error); + Mutex mutex; + Cond cond; + input_stream *is = input_stream::Open(path, mutex, cond, + error); if (is == NULL) { g_printerr("Failed to open %s: %s\n", - path, error->message); - g_error_free(error); + path, error.GetMessage()); return 1; } + mutex.lock(); + + is->WaitReady(); + + if (!is->Check(error)) { + mutex.unlock(); + + g_printerr("Failed to read %s: %s\n", + path, error.GetMessage()); + return EXIT_FAILURE; + } + + mutex.unlock(); + success = decoder_plugin_scan_stream(plugin, is, &print_handler, NULL); - input_stream_close(is); - - g_cond_free(cond); - g_mutex_free(mutex); + is->Close(); } decoder_plugin_deinit_all(); diff --git a/test/run_convert.c b/test/run_convert.cxx index 4f57400fd..939e279d0 100644 --- a/test/run_convert.c +++ b/test/run_convert.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,11 +24,12 @@ */ #include "config.h" -#include "audio_parser.h" -#include "audio_format.h" -#include "pcm_convert.h" -#include "conf.h" -#include "fifo_buffer.h" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" +#include "pcm/PcmConvert.hxx" +#include "ConfigGlobal.hxx" +#include "util/fifo_buffer.h" +#include "util/Error.hxx" #include "stdbin.h" #include <glib.h> @@ -38,8 +39,8 @@ #include <unistd.h> static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -48,16 +49,15 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, } const char * -config_get_string(G_GNUC_UNUSED const char *name, const char *default_value) +config_get_string(gcc_unused enum ConfigOption option, + const char *default_value) { return default_value; } int main(int argc, char **argv) { - GError *error = NULL; - struct audio_format in_audio_format, out_audio_format; - struct pcm_convert_state state; + AudioFormat in_audio_format, out_audio_format; const void *output; ssize_t nbytes; size_t length; @@ -69,27 +69,28 @@ int main(int argc, char **argv) g_log_set_default_handler(my_log_func, NULL); - if (!audio_format_parse(&in_audio_format, argv[1], - false, &error)) { + Error error; + if (!audio_format_parse(in_audio_format, argv[1], + false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); + error.GetMessage()); return 1; } - struct audio_format out_audio_format_mask; - if (!audio_format_parse(&out_audio_format_mask, argv[2], - true, &error)) { + AudioFormat out_audio_format_mask; + if (!audio_format_parse(out_audio_format_mask, argv[2], + true, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); + error.GetMessage()); return 1; } out_audio_format = in_audio_format; - audio_format_mask_apply(&out_audio_format, &out_audio_format_mask); + out_audio_format.ApplyMask(out_audio_format_mask); - const size_t in_frame_size = audio_format_frame_size(&in_audio_format); + const size_t in_frame_size = in_audio_format.GetFrameSize(); - pcm_convert_init(&state); + PcmConvert state; struct fifo_buffer *buffer = fifo_buffer_new(4096); @@ -112,15 +113,15 @@ int main(int argc, char **argv) fifo_buffer_consume(buffer, length); - output = pcm_convert(&state, &in_audio_format, src, length, - &out_audio_format, &length, &error); + output = state.Convert(in_audio_format, src, length, + out_audio_format, &length, error); if (output == NULL) { - g_printerr("Failed to convert: %s\n", error->message); + g_printerr("Failed to convert: %s\n", error.GetMessage()); return 2; } - G_GNUC_UNUSED ssize_t ignored = write(1, output, length); + gcc_unused ssize_t ignored = write(1, output, length); } - pcm_convert_deinit(&state); + return EXIT_SUCCESS; } diff --git a/test/run_decoder.c b/test/run_decoder.cxx index e6712c75b..c2aa1d7d6 100644 --- a/test/run_decoder.c +++ b/test/run_decoder.cxx @@ -18,15 +18,14 @@ */ #include "config.h" -#include "io_thread.h" -#include "decoder_list.h" -#include "decoder_api.h" -#include "tag_pool.h" -#include "input_init.h" -#include "input_stream.h" -#include "audio_format.h" -#include "pcm_volume.h" -#include "idle.h" +#include "IOThread.hxx" +#include "DecoderList.hxx" +#include "DecoderAPI.hxx" +#include "InputInit.hxx" +#include "InputStream.hxx" +#include "AudioFormat.hxx" +#include "util/Error.hxx" +#include "Log.hxx" #include "stdbin.h" #include <glib.h> @@ -36,8 +35,8 @@ #include <stdlib.h> static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -45,25 +44,6 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, g_printerr("%s\n", message); } -/** - * No-op dummy. - */ -void -idle_add(G_GNUC_UNUSED unsigned flags) -{ -} - -/** - * No-op dummy. - */ -bool -pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED size_t length, - G_GNUC_UNUSED enum sample_format format, - G_GNUC_UNUSED int volume) -{ - return true; -} - struct decoder { const char *uri; @@ -74,14 +54,14 @@ struct decoder { void decoder_initialized(struct decoder *decoder, - const struct audio_format *audio_format, - G_GNUC_UNUSED bool seekable, - G_GNUC_UNUSED float total_time) + const AudioFormat audio_format, + gcc_unused bool seekable, + gcc_unused float total_time) { struct audio_format_string af_string; assert(!decoder->initialized); - assert(audio_format_valid(audio_format)); + assert(audio_format.IsValid()); g_printerr("audio_format=%s\n", audio_format_to_string(audio_format, &af_string)); @@ -89,59 +69,59 @@ decoder_initialized(struct decoder *decoder, decoder->initialized = true; } -enum decoder_command -decoder_get_command(G_GNUC_UNUSED struct decoder *decoder) +DecoderCommand +decoder_get_command(gcc_unused struct decoder *decoder) { - return DECODE_COMMAND_NONE; + return DecoderCommand::NONE; } -void decoder_command_finished(G_GNUC_UNUSED struct decoder *decoder) +void decoder_command_finished(gcc_unused struct decoder *decoder) { } -double decoder_seek_where(G_GNUC_UNUSED struct decoder *decoder) +double decoder_seek_where(gcc_unused struct decoder *decoder) { return 1.0; } -void decoder_seek_error(G_GNUC_UNUSED struct decoder *decoder) +void decoder_seek_error(gcc_unused struct decoder *decoder) { } size_t -decoder_read(G_GNUC_UNUSED struct decoder *decoder, +decoder_read(gcc_unused struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { - return input_stream_lock_read(is, buffer, length, NULL); + return is->LockRead(buffer, length, IgnoreError()); } void -decoder_timestamp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED double t) +decoder_timestamp(gcc_unused struct decoder *decoder, + gcc_unused double t) { } -enum decoder_command -decoder_data(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, +DecoderCommand +decoder_data(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, const void *data, size_t datalen, - G_GNUC_UNUSED uint16_t kbit_rate) + gcc_unused uint16_t kbit_rate) { - G_GNUC_UNUSED ssize_t nbytes = write(1, data, datalen); - return DECODE_COMMAND_NONE; + gcc_unused ssize_t nbytes = write(1, data, datalen); + return DecoderCommand::NONE; } -enum decoder_command -decoder_tag(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED struct input_stream *is, - G_GNUC_UNUSED const struct tag *tag) +DecoderCommand +decoder_tag(gcc_unused struct decoder *decoder, + gcc_unused struct input_stream *is, + gcc_unused Tag &&tag) { - return DECODE_COMMAND_NONE; + return DecoderCommand::NONE; } -float -decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, +void +decoder_replay_gain(gcc_unused struct decoder *decoder, const struct replay_gain_info *replay_gain_info) { const struct replay_gain_tuple *tuple = @@ -154,13 +134,10 @@ decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, if (replay_gain_tuple_defined(tuple)) g_printerr("replay_gain[track]: gain=%f peak=%f\n", tuple->gain, tuple->peak); - - return 0.0; } void -decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED float replay_gain_db, +decoder_mixramp(gcc_unused struct decoder *decoder, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -169,7 +146,6 @@ decoder_mixramp(G_GNUC_UNUSED struct decoder *decoder, int main(int argc, char **argv) { - GError *error = NULL; const char *decoder_name; struct decoder decoder; @@ -181,21 +157,18 @@ int main(int argc, char **argv) decoder_name = argv[1]; decoder.uri = argv[2]; +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + g_log_set_default_handler(my_log_func, NULL); io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - tag_pool_init(); + io_thread_start(); - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); + Error error; + if (!input_stream_global_init(error)) { + LogError(error); return 2; } @@ -213,27 +186,23 @@ int main(int argc, char **argv) decoder_plugin_file_decode(decoder.plugin, &decoder, decoder.uri); } else if (decoder.plugin->stream_decode != NULL) { - GMutex *mutex = g_mutex_new(); - GCond *cond = g_cond_new(); + Mutex mutex; + Cond cond; - struct input_stream *is = - input_stream_open(decoder.uri, mutex, cond, &error); + input_stream *is = + input_stream::Open(decoder.uri, mutex, cond, error); if (is == NULL) { - if (error != NULL) { - g_warning("%s", error->message); - g_error_free(error); - } else - g_printerr("input_stream_open() failed\n"); + if (error.IsDefined()) + LogError(error); + else + g_printerr("input_stream::Open() failed\n"); return 1; } decoder_plugin_stream_decode(decoder.plugin, &decoder, is); - input_stream_close(is); - - g_cond_free(cond); - g_mutex_free(mutex); + is->Close(); } else { g_printerr("Decoder plugin is not usable\n"); return 1; @@ -248,7 +217,5 @@ int main(int argc, char **argv) return 1; } - tag_pool_deinit(); - return 0; } diff --git a/test/run_encoder.c b/test/run_encoder.cxx index db4d3af9b..838ee708e 100644 --- a/test/run_encoder.c +++ b/test/run_encoder.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,11 +18,12 @@ */ #include "config.h" -#include "encoder_list.h" -#include "encoder_plugin.h" -#include "audio_format.h" -#include "audio_parser.h" -#include "conf.h" +#include "EncoderList.hxx" +#include "EncoderPlugin.hxx" +#include "AudioFormat.hxx" +#include "AudioParser.hxx" +#include "ConfigData.hxx" +#include "util/Error.hxx" #include "stdbin.h" #include <glib.h> @@ -31,27 +32,20 @@ #include <unistd.h> static void -encoder_to_stdout(struct encoder *encoder) +encoder_to_stdout(Encoder &encoder) { size_t length; static char buffer[32768]; - while ((length = encoder_read(encoder, buffer, sizeof(buffer))) > 0) { - G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length); + while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) { + gcc_unused ssize_t ignored = write(1, buffer, length); } } int main(int argc, char **argv) { - GError *error = NULL; - struct audio_format audio_format; - bool ret; const char *encoder_name; - const struct encoder_plugin *plugin; - struct encoder *encoder; - struct config_param *param; static char buffer[32768]; - ssize_t nbytes; /* parse command line */ @@ -65,70 +59,62 @@ int main(int argc, char **argv) else encoder_name = "vorbis"; - audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); - /* create the encoder */ - plugin = encoder_plugin_get(encoder_name); + const auto plugin = encoder_plugin_get(encoder_name); if (plugin == NULL) { g_printerr("No such encoder: %s\n", encoder_name); return 1; } - param = config_new_param(NULL, -1); - config_add_block_param(param, "quality", "5.0", -1); + config_param param; + param.AddBlockParam("quality", "5.0", -1); - encoder = encoder_init(plugin, param, &error); + Error error; + const auto encoder = encoder_init(*plugin, param, error); if (encoder == NULL) { g_printerr("Failed to initialize encoder: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } /* open the encoder */ + AudioFormat audio_format(44100, SampleFormat::S16, 2); if (argc > 2) { - ret = audio_format_parse(&audio_format, argv[2], - false, &error); - if (!ret) { + if (!audio_format_parse(audio_format, argv[2], false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } } - if (!encoder_open(encoder, &audio_format, &error)) { + if (!encoder_open(encoder, audio_format, error)) { g_printerr("Failed to open encoder: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); /* do it */ + ssize_t nbytes; while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) { - ret = encoder_write(encoder, buffer, nbytes, &error); - if (!ret) { + if (!encoder_write(encoder, buffer, nbytes, error)) { g_printerr("encoder_write() failed: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); } - ret = encoder_end(encoder, &error); - if (!ret) { + if (!encoder_end(encoder, error)) { g_printerr("encoder_flush() failed: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); } diff --git a/test/run_filter.c b/test/run_filter.cxx index 8e793b768..085fc256b 100644 --- a/test/run_filter.c +++ b/test/run_filter.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,15 +18,18 @@ */ #include "config.h" -#include "conf.h" -#include "audio_parser.h" -#include "audio_format.h" -#include "filter_plugin.h" -#include "pcm_volume.h" -#include "idle.h" -#include "mixer_control.h" -#include "playlist.h" +#include "ConfigData.hxx" +#include "ConfigGlobal.hxx" +#include "fs/Path.hxx" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "pcm/PcmVolume.hxx" +#include "MixerControl.hxx" #include "stdbin.h" +#include "util/Error.hxx" +#include "system/FatalError.hxx" #include <glib.h> @@ -35,23 +38,16 @@ #include <errno.h> #include <unistd.h> -struct playlist g_playlist; - -void -idle_add(G_GNUC_UNUSED unsigned flags) -{ -} - bool -mixer_set_volume(G_GNUC_UNUSED struct mixer *mixer, - G_GNUC_UNUSED unsigned volume, G_GNUC_UNUSED GError **error_r) +mixer_set_volume(gcc_unused Mixer *mixer, + gcc_unused unsigned volume, gcc_unused Error &error) { return true; } static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -60,13 +56,12 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, } static const struct config_param * -find_named_config_block(const char *block, const char *name) +find_named_config_block(ConfigOption option, const char *name) { const struct config_param *param = NULL; - while ((param = config_get_next_param(block, param)) != NULL) { - const char *current_name = - config_get_block_string(param, "name", NULL); + while ((param = config_get_next_param(option, param)) != NULL) { + const char *current_name = param->GetBlockValue("name"); if (current_name != NULL && strcmp(current_name, name) == 0) return param; } @@ -74,23 +69,21 @@ find_named_config_block(const char *block, const char *name) return NULL; } -static struct filter * +static Filter * load_filter(const char *name) { const struct config_param *param; - struct filter *filter; - GError *error = NULL; - param = find_named_config_block("filter", name); + param = find_named_config_block(CONF_AUDIO_FILTER, name); if (param == NULL) { g_printerr("No such configured filter: %s\n", name); - return false; + return nullptr; } - filter = filter_configured_new(param, &error); + Error error; + Filter *filter = filter_configured_new(*param, error); if (filter == NULL) { - g_printerr("Failed to load filter: %s\n", error->message); - g_error_free(error); + g_printerr("Failed to load filter: %s\n", error.GetMessage()); return NULL; } @@ -99,12 +92,8 @@ load_filter(const char *name) int main(int argc, char **argv) { - struct audio_format audio_format; struct audio_format_string af_string; - bool success; - GError *error = NULL; - struct filter *filter; - const struct audio_format *out_audio_format; + Error error2; char buffer[4096]; if (argc < 3 || argc > 4) { @@ -112,49 +101,48 @@ int main(int argc, char **argv) return 1; } - audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); + const Path config_path = Path::FromFS(argv[1]); + + AudioFormat audio_format(44100, SampleFormat::S16, 2); /* initialize GLib */ +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + g_log_set_default_handler(my_log_func, NULL); /* read configuration file (mpd.conf) */ config_global_init(); - success = config_read_file(argv[1], &error); - if (!success) { - g_printerr("%s:", error->message); - g_error_free(error); - return 1; - } + if (!ReadConfigFile(config_path, error2)) + FatalError(error2); /* parse the audio format */ if (argc > 3) { - success = audio_format_parse(&audio_format, argv[3], - false, &error); - if (!success) { + Error error; + if (!audio_format_parse(audio_format, argv[3], false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } } /* initialize the filter */ - filter = load_filter(argv[2]); + Filter *filter = load_filter(argv[2]); if (filter == NULL) return 1; /* open the filter */ - out_audio_format = filter_open(filter, &audio_format, &error); - if (out_audio_format == NULL) { - g_printerr("Failed to open filter: %s\n", error->message); - g_error_free(error); - filter_free(filter); + Error error; + const AudioFormat out_audio_format = filter->Open(audio_format, error); + if (!out_audio_format.IsDefined()) { + g_printerr("Failed to open filter: %s\n", error.GetMessage()); + delete filter; return 1; } @@ -172,28 +160,28 @@ int main(int argc, char **argv) if (nbytes <= 0) break; - dest = filter_filter(filter, buffer, (size_t)nbytes, - &length, &error); + dest = filter->FilterPCM(buffer, (size_t)nbytes, + &length, error); if (dest == NULL) { - g_printerr("Filter failed: %s\n", error->message); - filter_close(filter); - filter_free(filter); + g_printerr("Filter failed: %s\n", error.GetMessage()); + filter->Close(); + delete filter; return 1; } nbytes = write(1, dest, length); if (nbytes < 0) { g_printerr("Failed to write: %s\n", g_strerror(errno)); - filter_close(filter); - filter_free(filter); + filter->Close(); + delete filter; return 1; } } /* cleanup and exit */ - filter_close(filter); - filter_free(filter); + filter->Close(); + delete filter; config_global_finish(); diff --git a/test/run_inotify.c b/test/run_inotify.cxx index 3e7c70dba..6796480e5 100644 --- a/test/run_inotify.c +++ b/test/run_inotify.cxx @@ -18,18 +18,22 @@ */ #include "config.h" -#include "inotify_source.h" +#include "InotifySource.hxx" +#include "event/Loop.hxx" +#include "util/Error.hxx" +#include "Log.hxx" + +#include <glib.h> -#include <stdbool.h> #include <sys/inotify.h> #include <signal.h> -static GMainLoop *main_loop; +static EventLoop *event_loop; static void -exit_signal_handler(G_GNUC_UNUSED int signum) +exit_signal_handler(gcc_unused int signum) { - g_main_loop_quit(main_loop); + event_loop->Break(); } enum { @@ -41,15 +45,14 @@ enum { }; static void -my_inotify_callback(G_GNUC_UNUSED int wd, unsigned mask, - const char *name, G_GNUC_UNUSED void *ctx) +my_inotify_callback(gcc_unused int wd, unsigned mask, + const char *name, gcc_unused void *ctx) { g_print("mask=0x%x name='%s'\n", mask, name); } int main(int argc, char **argv) { - GError *error = NULL; const char *path; if (argc != 2) { @@ -59,26 +62,24 @@ int main(int argc, char **argv) path = argv[1]; - struct mpd_inotify_source *source = - mpd_inotify_source_new(my_inotify_callback, NULL, - &error); + event_loop = new EventLoop(EventLoop::Default()); + + Error error; + InotifySource *source = InotifySource::Create(*event_loop, + my_inotify_callback, + nullptr, error); if (source == NULL) { - g_warning("%s", error->message); - g_error_free(error); + LogError(error); return 2; } - int descriptor = mpd_inotify_source_add(source, path, - IN_MASK, &error); + int descriptor = source->Add(path, IN_MASK, error); if (descriptor < 0) { - mpd_inotify_source_free(source); - g_warning("%s", error->message); - g_error_free(error); + delete source; + LogError(error); return 2; } - main_loop = g_main_loop_new(NULL, false); - struct sigaction sa; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); @@ -86,8 +87,8 @@ int main(int argc, char **argv) sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); - g_main_loop_run(main_loop); - g_main_loop_unref(main_loop); + event_loop->Run(); - mpd_inotify_source_free(source); + delete source; + delete event_loop; } diff --git a/test/run_input.c b/test/run_input.cxx index 676e4e618..d278676ce 100644 --- a/test/run_input.c +++ b/test/run_input.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,16 +18,18 @@ */ #include "config.h" -#include "io_thread.h" -#include "input_init.h" -#include "input_stream.h" -#include "tag_pool.h" -#include "tag_save.h" -#include "conf.h" +#include "TagSave.hxx" #include "stdbin.h" +#include "tag/Tag.hxx" +#include "ConfigGlobal.hxx" +#include "InputStream.hxx" +#include "InputInit.hxx" +#include "IOThread.hxx" +#include "util/Error.hxx" +#include "Log.hxx" #ifdef ENABLE_ARCHIVE -#include "archive_list.h" +#include "ArchiveList.hxx" #endif #include <glib.h> @@ -36,8 +38,8 @@ #include <stdlib.h> static void -my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, - const gchar *message, G_GNUC_UNUSED gpointer user_data) +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) { if (log_domain != NULL) g_printerr("%s: %s\n", log_domain, message); @@ -48,46 +50,42 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, static int dump_input_stream(struct input_stream *is) { - GError *error = NULL; + Error error; char buffer[4096]; size_t num_read; ssize_t num_written; - input_stream_lock(is); + is->Lock(); /* wait until the stream becomes ready */ - input_stream_wait_ready(is); + is->WaitReady(); - if (!input_stream_check(is, &error)) { - g_warning("%s", error->message); - g_error_free(error); - input_stream_unlock(is); + if (!is->Check(error)) { + LogError(error); + is->Unlock(); return EXIT_FAILURE; } /* print meta data */ - if (is->mime != NULL) - g_printerr("MIME type: %s\n", is->mime); + if (!is->mime.empty()) + g_printerr("MIME type: %s\n", is->mime.c_str()); /* read data and tags from the stream */ - while (!input_stream_eof(is)) { - struct tag *tag = input_stream_tag(is); + while (!is->IsEOF()) { + Tag *tag = is->ReadTag(); if (tag != NULL) { g_printerr("Received a tag:\n"); - tag_save(stderr, tag); - tag_free(tag); + tag_save(stderr, *tag); + delete tag; } - num_read = input_stream_read(is, buffer, sizeof(buffer), - &error); + num_read = is->Read(buffer, sizeof(buffer), error); if (num_read == 0) { - if (error != NULL) { - g_warning("%s", error->message); - g_error_free(error); - } + if (error.IsDefined()) + LogError(error); break; } @@ -97,21 +95,20 @@ dump_input_stream(struct input_stream *is) break; } - if (!input_stream_check(is, &error)) { - g_warning("%s", error->message); - g_error_free(error); - input_stream_unlock(is); + if (!is->Check(error)) { + LogError(error); + is->Unlock(); return EXIT_FAILURE; } - input_stream_unlock(is); + is->Unlock(); return 0; } int main(int argc, char **argv) { - GError *error = NULL; + Error error; struct input_stream *is; int ret; @@ -122,52 +119,45 @@ int main(int argc, char **argv) /* initialize GLib */ +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif + g_log_set_default_handler(my_log_func, NULL); /* initialize MPD */ - tag_pool_init(); config_global_init(); io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } + io_thread_start(); #ifdef ENABLE_ARCHIVE archive_plugin_init_all(); #endif - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); + if (!input_stream_global_init(error)) { + LogError(error); return 2; } /* open the stream and dump it */ - GMutex *mutex = g_mutex_new(); - GCond *cond = g_cond_new(); + Mutex mutex; + Cond cond; - is = input_stream_open(argv[1], mutex, cond, &error); + is = input_stream::Open(argv[1], mutex, cond, error); if (is != NULL) { ret = dump_input_stream(is); - input_stream_close(is); + is->Close(); } else { - if (error != NULL) { - g_warning("%s", error->message); - g_error_free(error); - } else - g_printerr("input_stream_open() failed\n"); + if (error.IsDefined()) + LogError(error); + else + g_printerr("input_stream::Open() failed\n"); ret = 2; } - g_cond_free(cond); - g_mutex_free(mutex); - /* deinitialize everything */ input_stream_global_finish(); @@ -179,7 +169,6 @@ int main(int argc, char **argv) io_thread_deinit(); config_global_finish(); - tag_pool_deinit(); return ret; } diff --git a/test/run_normalize.c b/test/run_normalize.cxx index fc26829ed..3193fefd2 100644 --- a/test/run_normalize.c +++ b/test/run_normalize.cxx @@ -25,8 +25,9 @@ #include "config.h" #include "AudioCompress/compress.h" -#include "audio_parser.h" -#include "audio_format.h" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" +#include "util/Error.hxx" #include "stdbin.h" #include <glib.h> @@ -37,9 +38,6 @@ int main(int argc, char **argv) { - GError *error = NULL; - struct audio_format audio_format; - bool ret; struct Compressor *compressor; static char buffer[4096]; ssize_t nbytes; @@ -49,16 +47,15 @@ int main(int argc, char **argv) return 1; } + AudioFormat audio_format(48000, SampleFormat::S16, 2); if (argc > 1) { - ret = audio_format_parse(&audio_format, argv[1], - false, &error); - if (!ret) { + Error error; + if (!audio_format_parse(audio_format, argv[1], false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); + error.GetMessage()); return 1; } - } else - audio_format_init(&audio_format, 48000, 16, 2); + } compressor = Compressor_new(0); @@ -66,7 +63,7 @@ int main(int argc, char **argv) Compressor_Process_int16(compressor, (int16_t *)buffer, nbytes / 2); - G_GNUC_UNUSED ssize_t ignored = write(1, buffer, nbytes); + gcc_unused ssize_t ignored = write(1, buffer, nbytes); } Compressor_delete(compressor); diff --git a/test/run_output.c b/test/run_output.cxx index bbb1be7d2..91cffbaf8 100644 --- a/test/run_output.c +++ b/test/run_output.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,19 +18,24 @@ */ #include "config.h" -#include "io_thread.h" -#include "output_plugin.h" -#include "output_internal.h" -#include "output_control.h" -#include "conf.h" -#include "audio_parser.h" -#include "filter_registry.h" -#include "pcm_convert.h" -#include "event_pipe.h" -#include "idle.h" -#include "playlist.h" -#include "player_control.h" +#include "OutputControl.hxx" +#include "OutputInternal.hxx" +#include "OutputPlugin.hxx" +#include "ConfigData.hxx" +#include "ConfigGlobal.hxx" +#include "ConfigOption.hxx" +#include "Idle.hxx" +#include "Main.hxx" +#include "event/Loop.hxx" +#include "GlobalEvents.hxx" +#include "IOThread.hxx" +#include "fs/Path.hxx" +#include "AudioParser.hxx" +#include "pcm/PcmConvert.hxx" +#include "FilterRegistry.hxx" +#include "PlayerControl.hxx" #include "stdbin.h" +#include "util/Error.hxx" #include <glib.h> @@ -39,54 +44,27 @@ #include <unistd.h> #include <stdlib.h> -struct playlist g_playlist; +EventLoop *main_loop; void -idle_add(G_GNUC_UNUSED unsigned flags) +GlobalEvents::Emit(gcc_unused Event event) { } -void -event_pipe_emit(G_GNUC_UNUSED enum pipe_event event) -{ -} - -void pcm_convert_init(G_GNUC_UNUSED struct pcm_convert_state *state) -{ -} - -void pcm_convert_deinit(G_GNUC_UNUSED struct pcm_convert_state *state) -{ -} - -const void * -pcm_convert(G_GNUC_UNUSED struct pcm_convert_state *state, - G_GNUC_UNUSED const struct audio_format *src_format, - G_GNUC_UNUSED const void *src, G_GNUC_UNUSED size_t src_size, - G_GNUC_UNUSED const struct audio_format *dest_format, - G_GNUC_UNUSED size_t *dest_size_r, - GError **error_r) -{ - g_set_error(error_r, pcm_convert_quark(), 0, - "Not implemented"); - return NULL; -} - const struct filter_plugin * -filter_plugin_by_name(G_GNUC_UNUSED const char *name) +filter_plugin_by_name(gcc_unused const char *name) { assert(false); return NULL; } static const struct config_param * -find_named_config_block(const char *block, const char *name) +find_named_config_block(ConfigOption option, const char *name) { const struct config_param *param = NULL; - while ((param = config_get_next_param(block, param)) != NULL) { - const char *current_name = - config_get_block_string(param, "name", NULL); + while ((param = config_get_next_param(option, param)) != NULL) { + const char *current_name = param->GetBlockValue("name"); if (current_name != NULL && strcmp(current_name, name) == 0) return param; } @@ -94,48 +72,48 @@ find_named_config_block(const char *block, const char *name) return NULL; } +player_control::player_control(gcc_unused unsigned _buffer_chunks, + gcc_unused unsigned _buffered_before_play) {} +player_control::~player_control() {} + static struct audio_output * load_audio_output(const char *name) { const struct config_param *param; - GError *error = NULL; param = find_named_config_block(CONF_AUDIO_OUTPUT, name); if (param == NULL) { g_printerr("No such configured audio output: %s\n", name); - return false; + return nullptr; } - static struct player_control dummy_player_control; + static struct player_control dummy_player_control(32, 4); + Error error; struct audio_output *ao = - audio_output_new(param, &dummy_player_control, &error); - if (ao == NULL) { - g_printerr("%s\n", error->message); - g_error_free(error); - } + audio_output_new(*param, &dummy_player_control, error); + if (ao == nullptr) + g_printerr("%s\n", error.GetMessage()); return ao; } static bool -run_output(struct audio_output *ao, struct audio_format *audio_format) +run_output(struct audio_output *ao, AudioFormat audio_format) { /* open the audio output */ - GError *error = NULL; - if (!ao_plugin_enable(ao, &error)) { + Error error; + if (!ao_plugin_enable(ao, error)) { g_printerr("Failed to enable audio output: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return false; } - if (!ao_plugin_open(ao, audio_format, &error)) { + if (!ao_plugin_open(ao, audio_format, error)) { ao_plugin_disable(ao); g_printerr("Failed to open audio output: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return false; } @@ -143,7 +121,7 @@ run_output(struct audio_output *ao, struct audio_format *audio_format) g_printerr("audio_format=%s\n", audio_format_to_string(audio_format, &af_string)); - size_t frame_size = audio_format_frame_size(audio_format); + size_t frame_size = audio_format.GetFrameSize(); /* play */ @@ -163,13 +141,12 @@ run_output(struct audio_output *ao, struct audio_format *audio_format) if (play_length > 0) { size_t consumed = ao_plugin_play(ao, buffer, play_length, - &error); + error); if (consumed == 0) { ao_plugin_close(ao); ao_plugin_disable(ao); g_printerr("Failed to play: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return false; } @@ -188,35 +165,33 @@ run_output(struct audio_output *ao, struct audio_format *audio_format) int main(int argc, char **argv) { - struct audio_format audio_format; - bool success; - GError *error = NULL; + Error error; if (argc < 3 || argc > 4) { g_printerr("Usage: run_output CONFIG NAME [FORMAT] <IN\n"); return 1; } - audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); + const Path config_path = Path::FromFS(argv[1]); + + AudioFormat audio_format(44100, SampleFormat::S16, 2); +#if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); +#endif /* read configuration file (mpd.conf) */ config_global_init(); - success = config_read_file(argv[1], &error); - if (!success) { - g_printerr("%s:", error->message); - g_error_free(error); + if (!ReadConfigFile(config_path, error)) { + g_printerr("%s\n", error.GetMessage()); return 1; } + main_loop = new EventLoop(EventLoop::Default()); + io_thread_init(); - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } + io_thread_start(); /* initialize the audio output */ @@ -227,19 +202,16 @@ int main(int argc, char **argv) /* parse the audio format */ if (argc > 3) { - success = audio_format_parse(&audio_format, argv[3], - false, &error); - if (!success) { + if (!audio_format_parse(audio_format, argv[3], false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); - g_error_free(error); + error.GetMessage()); return 1; } } /* do it */ - success = run_output(ao, &audio_format); + bool success = run_output(ao, audio_format); /* cleanup and exit */ @@ -247,6 +219,8 @@ int main(int argc, char **argv) io_thread_deinit(); + delete main_loop; + config_global_finish(); return success ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/test/run_resolver.c b/test/run_resolver.cxx index ee0bc0172..7da2fd5b2 100644 --- a/test/run_resolver.c +++ b/test/run_resolver.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,7 +18,11 @@ */ #include "config.h" -#include "resolver.h" +#include "system/Resolver.hxx" +#include "util/Error.hxx" +#include "Log.hxx" + +#include <glib.h> #ifdef WIN32 #include <ws2tcpip.h> @@ -37,23 +41,21 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - GError *error = NULL; + Error error; struct addrinfo *ai = resolve_host_port(argv[1], 80, AI_PASSIVE, SOCK_STREAM, - &error); + error); if (ai == NULL) { - g_printerr("%s\n", error->message); - g_error_free(error); + LogError(error); return EXIT_FAILURE; } for (const struct addrinfo *i = ai; i != NULL; i = i->ai_next) { char *p = sockaddr_to_string(i->ai_addr, i->ai_addrlen, - &error); + error); if (p == NULL) { freeaddrinfo(ai); - g_printerr("%s\n", error->message); - g_error_free(error); + LogError(error); return EXIT_FAILURE; } diff --git a/test/run_tcp_connect.c b/test/run_tcp_connect.c deleted file mode 100644 index bf8d9b82f..000000000 --- a/test/run_tcp_connect.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "resolver.h" -#include "io_thread.h" -#include "tcp_connect.h" -#include "fd_util.h" - -#include <assert.h> -#include <stdlib.h> - -#ifdef WIN32 -#include <ws2tcpip.h> -#include <winsock.h> -#else -#include <sys/socket.h> -#include <netdb.h> -#endif - -static struct tcp_connect *handle; -static GMutex *mutex; -static GCond *cond; -static bool done, success; - -static void -my_tcp_connect_success(int fd, G_GNUC_UNUSED void *ctx) -{ - assert(!done); - assert(!success); - - close_socket(fd); - g_print("success\n"); - - g_mutex_lock(mutex); - done = success = true; - g_cond_signal(cond); - g_mutex_unlock(mutex); -} - -static void -my_tcp_connect_error(GError *error, G_GNUC_UNUSED void *ctx) -{ - assert(!done); - assert(!success); - - g_printerr("error: %s\n", error->message); - g_error_free(error); - - g_mutex_lock(mutex); - done = true; - g_cond_signal(cond); - g_mutex_unlock(mutex); -} - -static void -my_tcp_connect_timeout(G_GNUC_UNUSED void *ctx) -{ - assert(!done); - assert(!success); - - g_printerr("timeout\n"); - - g_mutex_lock(mutex); - done = true; - g_cond_signal(cond); - g_mutex_unlock(mutex); -} - -static void -my_tcp_connect_canceled(G_GNUC_UNUSED void *ctx) -{ - assert(!done); - assert(!success); - - g_printerr("canceled\n"); - - g_mutex_lock(mutex); - done = true; - g_cond_signal(cond); - g_mutex_unlock(mutex); -} - -static const struct tcp_connect_handler my_tcp_connect_handler = { - .success = my_tcp_connect_success, - .error = my_tcp_connect_error, - .timeout = my_tcp_connect_timeout, - .canceled = my_tcp_connect_canceled, -}; - -int main(int argc, char **argv) -{ - if (argc != 2) { - g_printerr("Usage: run_tcp_connect IP:PORT\n"); - return 1; - } - - GError *error = NULL; - struct addrinfo *ai = resolve_host_port(argv[1], 80, 0, SOCK_STREAM, - &error); - if (ai == NULL) { - g_printerr("%s\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - /* initialize GLib */ - - g_thread_init(NULL); - - /* initialize MPD */ - - io_thread_init(); - if (!io_thread_start(&error)) { - freeaddrinfo(ai); - g_printerr("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - /* open the connection */ - - mutex = g_mutex_new(); - cond = g_cond_new(); - - tcp_connect_address(ai->ai_addr, ai->ai_addrlen, 5000, - &my_tcp_connect_handler, NULL, - &handle); - freeaddrinfo(ai); - - if (handle != NULL) { - g_mutex_lock(mutex); - while (!done) - g_cond_wait(cond, mutex); - g_mutex_unlock(mutex); - - tcp_connect_free(handle); - } - - g_cond_free(cond); - g_mutex_free(mutex); - - /* deinitialize everything */ - - io_thread_deinit(); - - return EXIT_SUCCESS; -} diff --git a/test/software_volume.c b/test/software_volume.cxx index 2357da672..19a0be88c 100644 --- a/test/software_volume.c +++ b/test/software_volume.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,9 +24,10 @@ */ #include "config.h" -#include "pcm_volume.h" -#include "audio_parser.h" -#include "audio_format.h" +#include "pcm/PcmVolume.hxx" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" +#include "util/Error.hxx" #include "stdbin.h" #include <glib.h> @@ -36,9 +37,6 @@ int main(int argc, char **argv) { - GError *error = NULL; - struct audio_format audio_format; - bool ret; static char buffer[4096]; ssize_t nbytes; @@ -47,24 +45,24 @@ int main(int argc, char **argv) return 1; } + Error error; + AudioFormat audio_format(48000, SampleFormat::S16, 2); if (argc > 1) { - ret = audio_format_parse(&audio_format, argv[1], - false, &error); - if (!ret) { + if (!audio_format_parse(audio_format, argv[1], false, error)) { g_printerr("Failed to parse audio format: %s\n", - error->message); + error.GetMessage()); return 1; } - } else - audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, 2); + } while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) { - if (!pcm_volume(buffer, nbytes, audio_format.format, + if (!pcm_volume(buffer, nbytes, + audio_format.format, PCM_VOLUME_1 / 2)) { g_printerr("pcm_volume() has failed\n"); return 2; } - G_GNUC_UNUSED ssize_t ignored = write(1, buffer, nbytes); + gcc_unused ssize_t ignored = write(1, buffer, nbytes); } } diff --git a/test/signals.c b/test/test_pcm_all.hxx index 15761f6b0..18202454b 100644 --- a/test/signals.c +++ b/test/test_pcm_all.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,46 +17,64 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "config.h" -#include "signals.h" -#ifndef WIN32 +#ifndef MPD_TEST_PCM_ALL_HXX +#define MPD_TEST_PCM_ALL_HXX -#include "mpd_error.h" +void +test_pcm_dither_24(); + +void +test_pcm_dither_32(); -#include <glib.h> +void +test_pcm_pack_24(); -#include <signal.h> -#include <errno.h> -#include <string.h> +void +test_pcm_unpack_24(); -static void -quit_signal_handler(G_GNUC_UNUSED int signum) -{ - on_quit(); -} +void +test_pcm_channels_16(); -static void -x_sigaction(int signum, const struct sigaction *act) -{ - if (sigaction(signum, act, NULL) < 0) - MPD_ERROR("sigaction() failed: %s", g_strerror(errno)); -} +void +test_pcm_channels_32(); -#endif +void +test_pcm_volume_8(); + +void +test_pcm_volume_16(); + +void +test_pcm_volume_24(); + +void +test_pcm_volume_32(); void -signals_init(void) -{ -#ifndef WIN32 - struct sigaction sa; +test_pcm_volume_float(); - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_IGN; - x_sigaction(SIGPIPE, &sa); +void +test_pcm_format_8_to_16(); + +void +test_pcm_format_16_to_24(); + +void +test_pcm_format_16_to_32(); + +void +test_pcm_format_float(); + +void +test_pcm_mix_8(); + +void +test_pcm_mix_16(); + +void +test_pcm_mix_24(); + +void +test_pcm_mix_32(); - sa.sa_handler = quit_signal_handler; - x_sigaction(SIGINT, &sa); - x_sigaction(SIGTERM, &sa); #endif -} diff --git a/test/test_pcm_channels.c b/test/test_pcm_channels.cxx index fb3ec5c3e..6642ed3d4 100644 --- a/test/test_pcm_channels.c +++ b/test/test_pcm_channels.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,29 +18,26 @@ */ #include "config.h" -#include "test_pcm_all.h" -#include "pcm_channels.h" -#include "pcm_buffer.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" +#include "pcm/PcmChannels.hxx" +#include "pcm/PcmBuffer.hxx" #include <glib.h> void -test_pcm_channels_16(void) +test_pcm_channels_16() { - enum { N = 256 }; - int16_t src[N * 2]; + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N * 2>(); - for (unsigned i = 0; i < G_N_ELEMENTS(src); ++i) - src[i] = g_random_int(); - - struct pcm_buffer buffer; - pcm_buffer_init(&buffer); + PcmBuffer buffer; /* stereo to mono */ size_t dest_size; const int16_t *dest = - pcm_convert_channels_16(&buffer, 1, 2, src, sizeof(src), + pcm_convert_channels_16(buffer, 1, 2, src, sizeof(src), &dest_size); g_assert(dest != NULL); g_assert_cmpint(dest_size, ==, sizeof(src) / 2); @@ -50,7 +47,7 @@ test_pcm_channels_16(void) /* mono to stereo */ - dest = pcm_convert_channels_16(&buffer, 2, 1, src, sizeof(src), + dest = pcm_convert_channels_16(buffer, 2, 1, src, sizeof(src), &dest_size); g_assert(dest != NULL); g_assert_cmpint(dest_size, ==, sizeof(src) * 2); @@ -58,27 +55,21 @@ test_pcm_channels_16(void) g_assert_cmpint(dest[i * 2], ==, src[i]); g_assert_cmpint(dest[i * 2 + 1], ==, src[i]); } - - pcm_buffer_deinit(&buffer); } void -test_pcm_channels_32(void) +test_pcm_channels_32() { - enum { N = 256 }; - int32_t src[N * 2]; + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int32_t, N * 2>(); - for (unsigned i = 0; i < G_N_ELEMENTS(src); ++i) - src[i] = g_random_int(); - - struct pcm_buffer buffer; - pcm_buffer_init(&buffer); + PcmBuffer buffer; /* stereo to mono */ size_t dest_size; const int32_t *dest = - pcm_convert_channels_32(&buffer, 1, 2, src, sizeof(src), + pcm_convert_channels_32(buffer, 1, 2, src, sizeof(src), &dest_size); g_assert(dest != NULL); g_assert_cmpint(dest_size, ==, sizeof(src) / 2); @@ -88,7 +79,7 @@ test_pcm_channels_32(void) /* mono to stereo */ - dest = pcm_convert_channels_32(&buffer, 2, 1, src, sizeof(src), + dest = pcm_convert_channels_32(buffer, 2, 1, src, sizeof(src), &dest_size); g_assert(dest != NULL); g_assert_cmpint(dest_size, ==, sizeof(src) * 2); @@ -96,6 +87,4 @@ test_pcm_channels_32(void) g_assert_cmpint(dest[i * 2], ==, src[i]); g_assert_cmpint(dest[i * 2 + 1], ==, src[i]); } - - pcm_buffer_deinit(&buffer); } diff --git a/test/test_pcm_dither.c b/test/test_pcm_dither.cxx index 44d105207..5694c17f8 100644 --- a/test/test_pcm_dither.c +++ b/test/test_pcm_dither.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,38 +17,21 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "test_pcm_all.h" -#include "pcm_dither.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" +#include "pcm/PcmDither.hxx" #include <glib.h> -/** - * Generate a random 24 bit PCM sample. - */ -static int32_t -random24(void) -{ - int32_t x = g_random_int() & 0xffffff; - if (x & 0x800000) - x |= 0xff000000; - return x; -} - void -test_pcm_dither_24(void) +test_pcm_dither_24() { - struct pcm_dither dither; - - pcm_dither_24_init(&dither); - - enum { N = 256 }; - int32_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = random24(); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int32_t, N>(GlibRandomInt24()); int16_t dest[N]; - - pcm_dither_24_to_16(&dither, dest, src, src + N); + PcmDither dither; + dither.Dither24To16(dest, src.begin(), src.end()); for (unsigned i = 0; i < N; ++i) { g_assert_cmpint(dest[i], >=, (src[i] >> 8) - 8); @@ -57,20 +40,14 @@ test_pcm_dither_24(void) } void -test_pcm_dither_32(void) +test_pcm_dither_32() { - struct pcm_dither dither; - - pcm_dither_24_init(&dither); - - enum { N = 256 }; - int32_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int32_t, N>(); int16_t dest[N]; - - pcm_dither_32_to_16(&dither, dest, src, src + N); + PcmDither dither; + dither.Dither32To16(dest, src.begin(), src.end()); for (unsigned i = 0; i < N; ++i) { g_assert_cmpint(dest[i], >=, (src[i] >> 16) - 8); diff --git a/test/test_pcm_format.cxx b/test/test_pcm_format.cxx new file mode 100644 index 000000000..65d744671 --- /dev/null +++ b/test/test_pcm_format.cxx @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" +#include "pcm/PcmFormat.hxx" +#include "pcm/PcmDither.hxx" +#include "pcm/PcmUtils.hxx" +#include "pcm/PcmBuffer.hxx" +#include "AudioFormat.hxx" + +#include <glib.h> + +void +test_pcm_format_8_to_16() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int8_t, N>(); + + PcmBuffer buffer; + + size_t d_size; + PcmDither dither; + auto d = pcm_convert_to_16(buffer, dither, SampleFormat::S8, + src, sizeof(src), &d_size); + auto d_end = pcm_end_pointer(d, d_size); + g_assert_cmpint(d_end - d, ==, N); + + for (size_t i = 0; i < N; ++i) + g_assert_cmpint(src[i], ==, d[i] >> 8); +} + +void +test_pcm_format_16_to_24() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + PcmBuffer buffer; + + size_t d_size; + auto d = pcm_convert_to_24(buffer, SampleFormat::S16, + src, sizeof(src), &d_size); + auto d_end = pcm_end_pointer(d, d_size); + g_assert_cmpint(d_end - d, ==, N); + + for (size_t i = 0; i < N; ++i) + g_assert_cmpint(src[i], ==, d[i] >> 8); +} + +void +test_pcm_format_16_to_32() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + PcmBuffer buffer; + + size_t d_size; + auto d = pcm_convert_to_32(buffer, SampleFormat::S16, + src, sizeof(src), &d_size); + auto d_end = pcm_end_pointer(d, d_size); + g_assert_cmpint(d_end - d, ==, N); + + for (size_t i = 0; i < N; ++i) + g_assert_cmpint(src[i], ==, d[i] >> 16); +} + +void +test_pcm_format_float() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + PcmBuffer buffer1, buffer2; + + size_t f_size; + auto f = pcm_convert_to_float(buffer1, SampleFormat::S16, + src, sizeof(src), &f_size); + auto f_end = pcm_end_pointer(f, f_size); + g_assert_cmpint(f_end - f, ==, N); + + for (auto i = f; i != f_end; ++i) { + g_assert(*i >= -1.); + g_assert(*i <= 1.); + } + + PcmDither dither; + + size_t d_size; + auto d = pcm_convert_to_16(buffer2, dither, + SampleFormat::FLOAT, + f, f_size, &d_size); + auto d_end = pcm_end_pointer(d, d_size); + g_assert_cmpint(d_end - d, ==, N); + + for (size_t i = 0; i < N; ++i) + g_assert_cmpint(src[i], ==, d[i]); +} diff --git a/test/test_pcm_main.c b/test/test_pcm_main.cxx index a483baaab..a221b26af 100644 --- a/test/test_pcm_main.c +++ b/test/test_pcm_main.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "test_pcm_all.h" +#include "test_pcm_all.hxx" #include <glib.h> @@ -38,5 +38,15 @@ main(int argc, char **argv) g_test_add_func("/pcm/volume/32", test_pcm_volume_32); g_test_add_func("/pcm/volume/float", test_pcm_volume_float); + g_test_add_func("/pcm/format/8_to_16", test_pcm_format_8_to_16); + g_test_add_func("/pcm/format/16_to_24", test_pcm_format_16_to_24); + g_test_add_func("/pcm/format/16_to_32", test_pcm_format_16_to_32); + g_test_add_func("/pcm/format/float", test_pcm_format_float); + + g_test_add_func("/pcm/mix/8", test_pcm_mix_8); + g_test_add_func("/pcm/mix/16", test_pcm_mix_16); + g_test_add_func("/pcm/mix/24", test_pcm_mix_24); + g_test_add_func("/pcm/mix/32", test_pcm_mix_32); + g_test_run(); } diff --git a/test/test_pcm_mix.cxx b/test/test_pcm_mix.cxx new file mode 100644 index 000000000..b0e89639c --- /dev/null +++ b/test/test_pcm_mix.cxx @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" +#include "pcm/PcmMix.hxx" + +#include <glib.h> + +template<typename T, SampleFormat format, typename G=GlibRandomInt<T>> +void +TestPcmMix(G g=G()) +{ + constexpr unsigned N = 256; + const auto src1 = TestDataBuffer<T, N>(g); + const auto src2 = TestDataBuffer<T, N>(g); + + /* portion1=1.0: result must be equal to src1 */ + auto result = src1; + bool success = pcm_mix(result.begin(), src2.begin(), sizeof(result), + format, 1.0); + g_assert(success); + AssertEqualWithTolerance(result, src1, 1); + + /* portion1=0.0: result must be equal to src2 */ + result = src1; + success = pcm_mix(result.begin(), src2.begin(), sizeof(result), + format, 0.0); + g_assert(success); + AssertEqualWithTolerance(result, src2, 1); + + /* portion1=0.5 */ + result = src1; + success = pcm_mix(result.begin(), src2.begin(), sizeof(result), + format, 0.5); + g_assert(success); + + auto expected = src1; + for (unsigned i = 0; i < N; ++i) + expected[i] = (int64_t(src1[i]) + int64_t(src2[i])) / 2; + + AssertEqualWithTolerance(result, expected, 1); +} + +void +test_pcm_mix_8() +{ + TestPcmMix<int8_t, SampleFormat::S8>(); +} + +void +test_pcm_mix_16() +{ + TestPcmMix<int16_t, SampleFormat::S16>(); +} + +void +test_pcm_mix_24() +{ + TestPcmMix<int32_t, SampleFormat::S24_P32>(GlibRandomInt24()); +} + +void +test_pcm_mix_32() +{ + TestPcmMix<int32_t, SampleFormat::S32>(); +} diff --git a/test/test_pcm_pack.c b/test/test_pcm_pack.cxx index 5127536fb..313948838 100644 --- a/test/test_pcm_pack.c +++ b/test/test_pcm_pack.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,34 +17,23 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "test_pcm_all.h" -#include "pcm_pack.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" -#include <glib.h> - -/** - * Generate a random 24 bit PCM sample. - */ -static int32_t -random24(void) -{ - int32_t x = g_random_int() & 0xffffff; - if (x & 0x800000) - x |= 0xff000000; - return x; +extern "C" { +#include "pcm/pcm_pack.h" } +#include <glib.h> + void -test_pcm_pack_24(void) +test_pcm_pack_24() { - enum { N = 256 }; - int32_t src[N * 3]; - for (unsigned i = 0; i < N; ++i) - src[i] = random24(); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int32_t, N>(GlibRandomInt24()); uint8_t dest[N * 3]; - - pcm_pack_24(dest, src, src + N); + pcm_pack_24(dest, src.begin(), src.end()); for (unsigned i = 0; i < N; ++i) { int32_t d; @@ -62,16 +51,13 @@ test_pcm_pack_24(void) } void -test_pcm_unpack_24(void) +test_pcm_unpack_24() { - enum { N = 256 }; - uint8_t src[N * 3]; - for (unsigned i = 0; i < G_N_ELEMENTS(src); ++i) - src[i] = g_random_int_range(0, 256); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<uint8_t, N * 3>(); int32_t dest[N]; - - pcm_unpack_24(dest, src, src + G_N_ELEMENTS(src)); + pcm_unpack_24(dest, src.begin(), src.end()); for (unsigned i = 0; i < N; ++i) { int32_t s; diff --git a/test/test_pcm_util.hxx b/test/test_pcm_util.hxx new file mode 100644 index 000000000..84ba074fd --- /dev/null +++ b/test/test_pcm_util.hxx @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <glib.h> + +#include <array> + +#include <stddef.h> +#include <stdint.h> + +template<typename T> +struct GlibRandomInt { + T operator()() const { + return T(g_random_int()); + } +}; + +struct GlibRandomInt24 : GlibRandomInt<int32_t> { + int32_t operator()() const { + auto t = GlibRandomInt::operator()(); + t &= 0xffffff; + if (t & 0x800000) + t |= 0xff000000; + return t; + } +}; + +struct GlibRandomFloat { + float operator()() const { + return g_random_double_range(-1.0, 1.0); + } +}; + +template<typename T, size_t N> +class TestDataBuffer : std::array<T, N> { +public: + using typename std::array<T, N>::const_pointer; + using std::array<T, N>::size; + using std::array<T, N>::begin; + using std::array<T, N>::end; + using std::array<T, N>::operator[]; + + template<typename G=GlibRandomInt<T>> + TestDataBuffer(G g=G()):std::array<T, N>() { + for (auto &i : *this) + i = g(); + + } + + operator typename std::array<T, N>::const_pointer() const { + return begin(); + } +}; + +template<typename T> +bool +AssertEqualWithTolerance(const T &a, const T &b, unsigned tolerance) +{ + g_assert_cmpint(a.size(), ==, b.size()); + + for (unsigned i = 0; i < a.size(); ++i) { + int64_t x = a[i], y = b[i]; + + g_assert_cmpint(x, >=, y - int64_t(tolerance)); + g_assert_cmpint(x, <=, y + int64_t(tolerance)); + } + + return true; +} diff --git a/test/test_pcm_volume.c b/test/test_pcm_volume.cxx index 713645cf1..d5aa3782e 100644 --- a/test/test_pcm_volume.c +++ b/test/test_pcm_volume.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2012 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,36 +17,37 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "test_pcm_all.h" -#include "pcm_volume.h" +#include "test_pcm_all.hxx" +#include "pcm/PcmVolume.hxx" +#include "test_pcm_util.hxx" #include <glib.h> +#include <algorithm> + #include <string.h> void -test_pcm_volume_8(void) +test_pcm_volume_8() { - enum { N = 256 }; - static const int8_t zero[N]; - int8_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + static int8_t zero[N]; + const auto src = TestDataBuffer<int8_t, N>(); int8_t dest[N]; - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S8, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S8, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S8, PCM_VOLUME_1 / 2), ==, true); for (unsigned i = 0; i < N; ++i) { @@ -56,28 +57,26 @@ test_pcm_volume_8(void) } void -test_pcm_volume_16(void) +test_pcm_volume_16() { - enum { N = 256 }; - static const int16_t zero[N]; - int16_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + static int16_t zero[N]; + const auto src = TestDataBuffer<int16_t, N>(); int16_t dest[N]; - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S16, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S16, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S16, PCM_VOLUME_1 / 2), ==, true); for (unsigned i = 0; i < N; ++i) { @@ -86,41 +85,27 @@ test_pcm_volume_16(void) } } -/** - * Generate a random 24 bit PCM sample. - */ -static int32_t -random24(void) -{ - int32_t x = g_random_int() & 0xffffff; - if (x & 0x800000) - x |= 0xff000000; - return x; -} - void -test_pcm_volume_24(void) +test_pcm_volume_24() { - enum { N = 256 }; - static const int32_t zero[N]; - int32_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = random24(); + constexpr unsigned N = 256; + static int32_t zero[N]; + const auto src = TestDataBuffer<int32_t, N>(GlibRandomInt24()); int32_t dest[N]; - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S24_P32, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S24_P32, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S24_P32, PCM_VOLUME_1 / 2), ==, true); for (unsigned i = 0; i < N; ++i) { @@ -130,28 +115,26 @@ test_pcm_volume_24(void) } void -test_pcm_volume_32(void) +test_pcm_volume_32() { - enum { N = 256 }; - static const int32_t zero[N]; - int32_t src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + static int32_t zero[N]; + const auto src = TestDataBuffer<int32_t, N>(); int32_t dest[N]; - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S32, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S32, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::S32, PCM_VOLUME_1 / 2), ==, true); for (unsigned i = 0; i < N; ++i) { @@ -161,28 +144,26 @@ test_pcm_volume_32(void) } void -test_pcm_volume_float(void) +test_pcm_volume_float() { - enum { N = 256 }; - static const float zero[N]; - float src[N]; - for (unsigned i = 0; i < N; ++i) - src[i] = g_random_double_range(-1.0, 1.0); + constexpr unsigned N = 256; + static float zero[N]; + const auto src = TestDataBuffer<float, N>(GlibRandomFloat()); float dest[N]; - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::FLOAT, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::FLOAT, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); - g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, + std::copy(src.begin(), src.end(), dest); + g_assert_cmpint(pcm_volume(dest, sizeof(dest), SampleFormat::FLOAT, PCM_VOLUME_1 / 2), ==, true); for (unsigned i = 0; i < N; ++i) diff --git a/test/test_queue_priority.c b/test/test_queue_priority.c deleted file mode 100644 index 5543edbba..000000000 --- a/test/test_queue_priority.c +++ /dev/null @@ -1,175 +0,0 @@ -#include "queue.h" -#include "song.h" - -void -song_free(G_GNUC_UNUSED struct song *song) -{ -} - -G_GNUC_UNUSED -static void -dump_order(const struct queue *queue) -{ - g_printerr("queue length=%u, order:\n", queue_length(queue)); - for (unsigned i = 0; i < queue_length(queue); ++i) - g_printerr(" [%u] -> %u (prio=%u)\n", i, queue->order[i], - queue->items[queue->order[i]].priority); -} - -static void -check_descending_priority(G_GNUC_UNUSED const struct queue *queue, - unsigned start_order) -{ - assert(start_order < queue_length(queue)); - - uint8_t last_priority = 0xff; - for (unsigned order = start_order; order < queue_length(queue); ++order) { - unsigned position = queue_order_to_position(queue, order); - uint8_t priority = queue->items[position].priority; - assert(priority <= last_priority); - (void)last_priority; - last_priority = priority; - } -} - -int -main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) -{ - struct song songs[16]; - - struct queue queue; - queue_init(&queue, 32); - - for (unsigned i = 0; i < G_N_ELEMENTS(songs); ++i) - queue_append(&queue, &songs[i], 0); - - assert(queue_length(&queue) == G_N_ELEMENTS(songs)); - - /* priority=10 for 4 items */ - - queue_set_priority_range(&queue, 4, 8, 10, -1); - - queue.random = true; - queue_shuffle_order(&queue); - check_descending_priority(&queue, 0); - - for (unsigned i = 0; i < 4; ++i) { - assert(queue_position_to_order(&queue, i) >= 4); - } - - for (unsigned i = 4; i < 8; ++i) { - assert(queue_position_to_order(&queue, i) < 4); - } - - for (unsigned i = 8; i < G_N_ELEMENTS(songs); ++i) { - assert(queue_position_to_order(&queue, i) >= 4); - } - - /* priority=50 one more item */ - - queue_set_priority_range(&queue, 15, 16, 50, -1); - check_descending_priority(&queue, 0); - - assert(queue_position_to_order(&queue, 15) == 0); - - for (unsigned i = 0; i < 4; ++i) { - assert(queue_position_to_order(&queue, i) >= 4); - } - - for (unsigned i = 4; i < 8; ++i) { - assert(queue_position_to_order(&queue, i) >= 1 && - queue_position_to_order(&queue, i) < 5); - } - - for (unsigned i = 8; i < 15; ++i) { - assert(queue_position_to_order(&queue, i) >= 5); - } - - /* priority=20 for one of the 4 priority=10 items */ - - queue_set_priority_range(&queue, 3, 4, 20, -1); - check_descending_priority(&queue, 0); - - assert(queue_position_to_order(&queue, 3) == 1); - assert(queue_position_to_order(&queue, 15) == 0); - - for (unsigned i = 0; i < 3; ++i) { - assert(queue_position_to_order(&queue, i) >= 5); - } - - for (unsigned i = 4; i < 8; ++i) { - assert(queue_position_to_order(&queue, i) >= 2 && - queue_position_to_order(&queue, i) < 6); - } - - for (unsigned i = 8; i < 15; ++i) { - assert(queue_position_to_order(&queue, i) >= 6); - } - - /* priority=20 for another one of the 4 priority=10 items; - pass "after_order" (with priority=10) and see if it's moved - after that one */ - - unsigned current_order = 4; - unsigned current_position = - queue_order_to_position(&queue, current_order); - - unsigned a_order = 3; - unsigned a_position = queue_order_to_position(&queue, a_order); - assert(queue.items[a_position].priority == 10); - queue_set_priority(&queue, a_position, 20, current_order); - - current_order = queue_position_to_order(&queue, current_position); - assert(current_order == 3); - - a_order = queue_position_to_order(&queue, a_position); - assert(a_order == 4); - - check_descending_priority(&queue, current_order + 1); - - /* priority=70 for one of the last items; must be inserted - right after the current song, before the priority=20 one we - just created */ - - unsigned b_order = 10; - unsigned b_position = queue_order_to_position(&queue, b_order); - assert(queue.items[b_position].priority == 0); - queue_set_priority(&queue, b_position, 70, current_order); - - current_order = queue_position_to_order(&queue, current_position); - assert(current_order == 3); - - b_order = queue_position_to_order(&queue, b_position); - assert(b_order == 4); - - check_descending_priority(&queue, current_order + 1); - - /* priority=60 for the old prio50 item; must not be moved, - because it's before the current song, and it's status - hasn't changed (it was already higher before) */ - - unsigned c_order = 0; - unsigned c_position = queue_order_to_position(&queue, c_order); - assert(queue.items[c_position].priority == 50); - queue_set_priority(&queue, c_position, 60, current_order); - - current_order = queue_position_to_order(&queue, current_position); - assert(current_order == 3); - - c_order = queue_position_to_order(&queue, c_position); - assert(c_order == 0); - - /* move the prio=20 item back */ - - a_order = queue_position_to_order(&queue, a_position); - assert(a_order == 5); - assert(queue.items[a_position].priority == 20); - queue_set_priority(&queue, a_position, 5, current_order); - - - current_order = queue_position_to_order(&queue, current_position); - assert(current_order == 3); - - a_order = queue_position_to_order(&queue, a_position); - assert(a_order == 6); -} diff --git a/test/test_queue_priority.cxx b/test/test_queue_priority.cxx new file mode 100644 index 000000000..2e544253d --- /dev/null +++ b/test/test_queue_priority.cxx @@ -0,0 +1,188 @@ +#include "config.h" +#include "Queue.hxx" +#include "Song.hxx" +#include "Directory.hxx" + +#include <glib.h> + +Directory detached_root; + +Directory::Directory() {} +Directory::~Directory() {} + +Song * +Song::DupDetached() const +{ + return const_cast<Song *>(this); +} + +void +Song::Free() +{ +} + +gcc_unused +static void +dump_order(const struct queue *queue) +{ + g_printerr("queue length=%u, order:\n", queue->GetLength()); + for (unsigned i = 0; i < queue->GetLength(); ++i) + g_printerr(" [%u] -> %u (prio=%u)\n", i, queue->order[i], + queue->items[queue->order[i]].priority); +} + +static void +check_descending_priority(const struct queue *queue, + unsigned start_order) +{ + assert(start_order < queue->GetLength()); + + uint8_t last_priority = 0xff; + for (unsigned order = start_order; order < queue->GetLength(); ++order) { + unsigned position = queue->OrderToPosition(order); + uint8_t priority = queue->items[position].priority; + assert(priority <= last_priority); + (void)last_priority; + last_priority = priority; + } +} + +int +main(gcc_unused int argc, gcc_unused char **argv) +{ + static Song songs[16]; + + struct queue queue(32); + + for (unsigned i = 0; i < G_N_ELEMENTS(songs); ++i) + queue.Append(&songs[i], 0); + + assert(queue.GetLength() == G_N_ELEMENTS(songs)); + + /* priority=10 for 4 items */ + + queue.SetPriorityRange(4, 8, 10, -1); + + queue.random = true; + queue.ShuffleOrder(); + check_descending_priority(&queue, 0); + + for (unsigned i = 0; i < 4; ++i) { + assert(queue.PositionToOrder(i) >= 4); + } + + for (unsigned i = 4; i < 8; ++i) { + assert(queue.PositionToOrder(i) < 4); + } + + for (unsigned i = 8; i < G_N_ELEMENTS(songs); ++i) { + assert(queue.PositionToOrder(i) >= 4); + } + + /* priority=50 one more item */ + + queue.SetPriorityRange(15, 16, 50, -1); + check_descending_priority(&queue, 0); + + assert(queue.PositionToOrder(15) == 0); + + for (unsigned i = 0; i < 4; ++i) { + assert(queue.PositionToOrder(i) >= 4); + } + + for (unsigned i = 4; i < 8; ++i) { + assert(queue.PositionToOrder(i) >= 1 && + queue.PositionToOrder(i) < 5); + } + + for (unsigned i = 8; i < 15; ++i) { + assert(queue.PositionToOrder(i) >= 5); + } + + /* priority=20 for one of the 4 priority=10 items */ + + queue.SetPriorityRange(3, 4, 20, -1); + check_descending_priority(&queue, 0); + + assert(queue.PositionToOrder(3) == 1); + assert(queue.PositionToOrder(15) == 0); + + for (unsigned i = 0; i < 3; ++i) { + assert(queue.PositionToOrder(i) >= 5); + } + + for (unsigned i = 4; i < 8; ++i) { + assert(queue.PositionToOrder(i) >= 2 && + queue.PositionToOrder(i) < 6); + } + + for (unsigned i = 8; i < 15; ++i) { + assert(queue.PositionToOrder(i) >= 6); + } + + /* priority=20 for another one of the 4 priority=10 items; + pass "after_order" (with priority=10) and see if it's moved + after that one */ + + unsigned current_order = 4; + unsigned current_position = + queue.OrderToPosition(current_order); + + unsigned a_order = 3; + unsigned a_position = queue.OrderToPosition(a_order); + assert(queue.items[a_position].priority == 10); + queue.SetPriority(a_position, 20, current_order); + + current_order = queue.PositionToOrder(current_position); + assert(current_order == 3); + + a_order = queue.PositionToOrder(a_position); + assert(a_order == 4); + + check_descending_priority(&queue, current_order + 1); + + /* priority=70 for one of the last items; must be inserted + right after the current song, before the priority=20 one we + just created */ + + unsigned b_order = 10; + unsigned b_position = queue.OrderToPosition(b_order); + assert(queue.items[b_position].priority == 0); + queue.SetPriority(b_position, 70, current_order); + + current_order = queue.PositionToOrder(current_position); + assert(current_order == 3); + + b_order = queue.PositionToOrder(b_position); + assert(b_order == 4); + + check_descending_priority(&queue, current_order + 1); + + /* priority=60 for the old prio50 item; must not be moved, + because it's before the current song, and it's status + hasn't changed (it was already higher before) */ + + unsigned c_order = 0; + unsigned c_position = queue.OrderToPosition(c_order); + assert(queue.items[c_position].priority == 50); + queue.SetPriority(c_position, 60, current_order); + + current_order = queue.PositionToOrder(current_position); + assert(current_order == 3); + + c_order = queue.PositionToOrder(c_position); + assert(c_order == 0); + + /* move the prio=20 item back */ + + a_order = queue.PositionToOrder(a_position); + assert(a_order == 5); + assert(queue.items[a_position].priority == 20); + queue.SetPriority(a_position, 5, current_order); + + current_order = queue.PositionToOrder(current_position); + assert(current_order == 3); + + a_order = queue.PositionToOrder(a_position); + assert(a_order == 6); +} diff --git a/test/test_vorbis_encoder.c b/test/test_vorbis_encoder.c deleted file mode 100644 index 619399159..000000000 --- a/test/test_vorbis_encoder.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2003-2012 The Music Player Daemon Project - * http://www.musicpd.org - * - * 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "encoder_list.h" -#include "encoder_plugin.h" -#include "audio_format.h" -#include "conf.h" -#include "stdbin.h" -#include "tag.h" - -#include <glib.h> - -#include <stddef.h> -#include <unistd.h> - -static uint8_t zero[256]; - -static void -encoder_to_stdout(struct encoder *encoder) -{ - size_t length; - static char buffer[32768]; - - while ((length = encoder_read(encoder, buffer, sizeof(buffer))) > 0) { - G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length); - } -} - -int -main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) -{ - G_GNUC_UNUSED bool success; - - /* create the encoder */ - - const struct encoder_plugin *plugin = encoder_plugin_get("vorbis"); - assert(plugin != NULL); - - struct config_param *param = config_new_param(NULL, -1); - config_add_block_param(param, "quality", "5.0", -1); - - struct encoder *encoder = encoder_init(plugin, param, NULL); - assert(encoder != NULL); - - /* open the encoder */ - - struct audio_format audio_format; - - audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); - success = encoder_open(encoder, &audio_format, NULL); - assert(success); - - encoder_to_stdout(encoder); - - /* write a block of data */ - - success = encoder_write(encoder, zero, sizeof(zero), NULL); - assert(success); - - encoder_to_stdout(encoder); - - /* write a tag */ - - success = encoder_pre_tag(encoder, NULL); - assert(success); - - encoder_to_stdout(encoder); - - struct tag *tag = tag_new(); - tag_add_item(tag, TAG_ARTIST, "Foo"); - tag_add_item(tag, TAG_TITLE, "Bar"); - - success = encoder_tag(encoder, tag, NULL); - assert(success); - - tag_free(tag); - - encoder_to_stdout(encoder); - - /* write another block of data */ - - success = encoder_write(encoder, zero, sizeof(zero), NULL); - assert(success); - - /* finish */ - - success = encoder_end(encoder, NULL); - assert(success); - - encoder_to_stdout(encoder); - - encoder_close(encoder); - encoder_finish(encoder); -} diff --git a/test/test_vorbis_encoder.cxx b/test/test_vorbis_encoder.cxx new file mode 100644 index 000000000..1d95f6deb --- /dev/null +++ b/test/test_vorbis_encoder.cxx @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "EncoderList.hxx" +#include "EncoderPlugin.hxx" +#include "AudioFormat.hxx" +#include "ConfigData.hxx" +#include "stdbin.h" +#include "tag/Tag.hxx" +#include "util/Error.hxx" + +#include <stddef.h> +#include <unistd.h> + +static uint8_t zero[256]; + +static void +encoder_to_stdout(Encoder &encoder) +{ + size_t length; + static char buffer[32768]; + + while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) { + gcc_unused ssize_t ignored = write(1, buffer, length); + } +} + +int +main(gcc_unused int argc, gcc_unused char **argv) +{ + gcc_unused bool success; + + /* create the encoder */ + + const auto plugin = encoder_plugin_get("vorbis"); + assert(plugin != NULL); + + config_param param; + param.AddBlockParam("quality", "5.0", -1); + + const auto encoder = encoder_init(*plugin, param, IgnoreError()); + assert(encoder != NULL); + + /* open the encoder */ + + AudioFormat audio_format(44100, SampleFormat::S16, 2); + success = encoder_open(encoder, audio_format, IgnoreError()); + assert(success); + + encoder_to_stdout(*encoder); + + /* write a block of data */ + + success = encoder_write(encoder, zero, sizeof(zero), IgnoreError()); + assert(success); + + encoder_to_stdout(*encoder); + + /* write a tag */ + + success = encoder_pre_tag(encoder, IgnoreError()); + assert(success); + + encoder_to_stdout(*encoder); + + Tag tag; + tag.AddItem(TAG_ARTIST, "Foo"); + tag.AddItem(TAG_TITLE, "Bar"); + + success = encoder_tag(encoder, &tag, IgnoreError()); + assert(success); + + encoder_to_stdout(*encoder); + + /* write another block of data */ + + success = encoder_write(encoder, zero, sizeof(zero), IgnoreError()); + assert(success); + + /* finish */ + + success = encoder_end(encoder, IgnoreError()); + assert(success); + + encoder_to_stdout(*encoder); + + encoder_close(encoder); + encoder_finish(encoder); +} diff --git a/test/visit_archive.cxx b/test/visit_archive.cxx new file mode 100644 index 000000000..6e66c4696 --- /dev/null +++ b/test/visit_archive.cxx @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "stdbin.h" +#include "tag/Tag.hxx" +#include "ConfigGlobal.hxx" +#include "IOThread.hxx" +#include "InputInit.hxx" +#include "ArchiveList.hxx" +#include "ArchivePlugin.hxx" +#include "ArchiveFile.hxx" +#include "ArchiveVisitor.hxx" +#include "fs/Path.hxx" +#include "util/Error.hxx" + +#include <glib.h> + +#include <unistd.h> +#include <stdlib.h> + +static void +my_log_func(const gchar *log_domain, gcc_unused GLogLevelFlags log_level, + const gchar *message, gcc_unused gpointer user_data) +{ + if (log_domain != NULL) + g_printerr("%s: %s\n", log_domain, message); + else + g_printerr("%s\n", message); +} + +class MyArchiveVisitor final : public ArchiveVisitor { + public: + virtual void VisitArchiveEntry(const char *path_utf8) override { + printf("%s\n", path_utf8); + } +}; + +int +main(int argc, char **argv) +{ + Error error; + + if (argc != 3) { + fprintf(stderr, "Usage: visit_archive PLUGIN PATH\n"); + return EXIT_FAILURE; + } + + const char *plugin_name = argv[1]; + const Path path = Path::FromFS(argv[2]); + + /* initialize GLib */ + +#if !GLIB_CHECK_VERSION(2,32,0) + g_thread_init(NULL); +#endif + + g_log_set_default_handler(my_log_func, NULL); + + /* initialize MPD */ + + config_global_init(); + + io_thread_init(); + io_thread_start(); + + archive_plugin_init_all(); + + if (!input_stream_global_init(error)) { + fprintf(stderr, "%s", error.GetMessage()); + return 2; + } + + /* open the archive and dump it */ + + const archive_plugin *plugin = archive_plugin_from_name(plugin_name); + if (plugin == nullptr) { + fprintf(stderr, "No such plugin: %s\n", plugin_name); + return EXIT_FAILURE; + } + + int result = EXIT_SUCCESS; + + ArchiveFile *file = archive_file_open(plugin, path.c_str(), error); + if (file != nullptr) { + MyArchiveVisitor visitor; + file->Visit(visitor); + file->Close(); + } else { + fprintf(stderr, "%s", error.GetMessage()); + result = EXIT_FAILURE; + } + + /* deinitialize everything */ + + input_stream_global_finish(); + + archive_plugin_deinit_all(); + + io_thread_deinit(); + + config_global_finish(); + + return result; +} |