diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/DumpDatabase.cxx | 150 | ||||
-rw-r--r-- | test/FakeReplayGainConfig.cxx | 25 | ||||
-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) | 54 | ||||
-rw-r--r-- | test/dump_rva2.cxx (renamed from test/dump_rva2.c) | 29 | ||||
-rw-r--r-- | test/dump_text_file.cxx (renamed from test/dump_text_file.c) | 40 | ||||
-rw-r--r-- | test/read_conf.cxx (renamed from test/read_conf.c) | 13 | ||||
-rw-r--r-- | test/read_mixer.cxx (renamed from test/read_mixer.c) | 51 | ||||
-rw-r--r-- | test/read_tags.cxx (renamed from test/read_tags.c) | 82 | ||||
-rw-r--r-- | test/run_convert.cxx (renamed from test/run_convert.c) | 34 | ||||
-rw-r--r-- | test/run_decoder.cxx (renamed from test/run_decoder.c) | 57 | ||||
-rw-r--r-- | test/run_encoder.cxx (renamed from test/run_encoder.c) | 41 | ||||
-rw-r--r-- | test/run_filter.cxx (renamed from test/run_filter.c) | 81 | ||||
-rw-r--r-- | test/run_inotify.cxx (renamed from test/run_inotify.c) | 31 | ||||
-rw-r--r-- | test/run_input.cxx (renamed from test/run_input.c) | 39 | ||||
-rw-r--r-- | test/run_normalize.cxx (renamed from test/run_normalize.c) | 11 | ||||
-rw-r--r-- | test/run_output.cxx (renamed from test/run_output.c) | 94 | ||||
-rw-r--r-- | test/run_tcp_connect.c | 164 | ||||
-rw-r--r-- | test/software_volume.cxx (renamed from test/software_volume.c) | 18 | ||||
-rw-r--r-- | test/test_pcm_all.hxx | 80 | ||||
-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.cxx (renamed from test/test_vorbis_encoder.c) | 48 | ||||
-rw-r--r-- | test/visit_archive.cxx | 126 |
32 files changed, 1317 insertions, 931 deletions
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx new file mode 100644 index 000000000..c6a01fa11 --- /dev/null +++ b/test/DumpDatabase.cxx @@ -0,0 +1,150 @@ +/* + * 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 "conf.h" +#include "Tag.hxx" +#include "fs/Path.hxx" + +#include <iostream> +using std::cout; +using std::cerr; +using std::endl; + +#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) +{ + if (log_domain != NULL) + g_printerr("%s: %s\n", log_domain, message); + else + g_printerr("%s\n", message); +} + +static bool +DumpDirectory(const Directory &directory, GError **) +{ + cout << "D " << directory.path << endl; + return true; +} + +static bool +DumpSong(Song &song, GError **) +{ + cout << "S " << song.parent->path << "/" << song.uri << endl; + return true; +} + +static bool +DumpPlaylist(const PlaylistInfo &playlist, + const Directory &directory, GError **) +{ + cout << "P " << directory.path << "/" << playlist.name.c_str() << endl; + return true; +} + +int +main(int argc, char **argv) +{ + GError *error = nullptr; + + 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(); + + if (!ReadConfigFile(config_path, &error)) { + cerr << error->message << endl; + g_error_free(error); + return EXIT_FAILURE; + } + + tag_lib_init(); + + /* 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->message << endl; + g_error_free(error); + return EXIT_FAILURE; + } + + if (!db->Open(&error)) { + delete db; + cerr << error->message << endl; + g_error_free(error); + return EXIT_FAILURE; + } + + const DatabaseSelection selection("", true); + + if (!db->Visit(selection, DumpDirectory, DumpSong, DumpPlaylist, + &error)) { + db->Close(); + delete db; + cerr << error->message << endl; + g_error_free(error); + return EXIT_FAILURE; + } + + db->Close(); + delete db; + + /* deinitialize everything */ + + config_global_finish(); + + return EXIT_SUCCESS; +} diff --git a/test/FakeReplayGainConfig.cxx b/test/FakeReplayGainConfig.cxx new file mode 100644 index 000000000..9c2431bf2 --- /dev/null +++ b/test/FakeReplayGainConfig.cxx @@ -0,0 +1,25 @@ +/* + * 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 "replay_gain_config.h" + +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..bf8ddcdfe 100644 --- a/test/dump_playlist.c +++ b/test/dump_playlist.cxx @@ -18,23 +18,27 @@ */ #include "config.h" -#include "io_thread.h" -#include "input_init.h" +#include "TagSave.hxx" +#include "Song.hxx" +#include "Directory.hxx" #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 "DecoderAPI.hxx" +#include "DecoderList.hxx" +#include "InputInit.hxx" +#include "IOThread.hxx" +#include "PlaylistRegistry.hxx" +#include "PlaylistPlugin.hxx" +#include "fs/Path.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) @@ -47,7 +51,7 @@ 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 const AudioFormat audio_format, G_GNUC_UNUSED bool seekable, G_GNUC_UNUSED float total_time) { @@ -102,12 +106,12 @@ decoder_data(G_GNUC_UNUSED struct decoder *decoder, 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) + G_GNUC_UNUSED Tag &&tag) { return DECODE_COMMAND_NONE; } -float +void decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, const struct replay_gain_info *replay_gain_info) { @@ -121,13 +125,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, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -138,29 +139,30 @@ 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) { + if (!ReadConfigFile(config_path, &error)) { g_printerr("%s\n", error->message); g_error_free(error); return 1; @@ -184,8 +186,8 @@ 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); if (playlist == NULL) { @@ -230,9 +232,9 @@ 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 */ @@ -241,15 +243,11 @@ int main(int argc, char **argv) if (is != NULL) input_stream_close(is); - g_cond_free(cond); - g_mutex_free(mutex); - 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..9dbb018d6 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 "TagId3.hxx" +#include "TagRva2.hxx" #include "replay_gain_info.h" #include "conf.h" -#include "tag.h" +#include "Tag.hxx" #include <id3tag.h> +#include <glib.h> + #ifdef HAVE_LOCALE_H #include <locale.h> #endif @@ -33,28 +35,19 @@ #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) +Tag::AddItem(gcc_unused enum tag_type type, + gcc_unused const char *value) { } -void -tag_free(struct tag *tag) -{ - g_free(tag); -} +Tag::~Tag() {} int main(int argc, char **argv) { diff --git a/test/dump_text_file.c b/test/dump_text_file.cxx index f14371441..40b3a878f 100644 --- a/test/dump_text_file.c +++ b/test/dump_text_file.cxx @@ -18,16 +18,15 @@ */ #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 "IOThread.hxx" +#include "InputInit.hxx" +#include "InputStream.hxx" #include "conf.h" #include "stdbin.h" +#include "TextInputStream.hxx" #ifdef ENABLE_ARCHIVE -#include "archive_list.h" +#include "ArchiveList.hxx" #endif #include <glib.h> @@ -47,11 +46,11 @@ 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 @@ -75,11 +74,10 @@ dump_input_stream(struct input_stream *is) /* 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); - + { + TextInputStream tis(is); + dump_text_file(tis); + } input_stream_lock(is); if (!input_stream_check(is, &error)) { @@ -107,12 +105,14 @@ 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(); @@ -134,8 +134,8 @@ int main(int argc, char **argv) /* 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); if (is != NULL) { @@ -150,9 +150,6 @@ int main(int argc, char **argv) ret = 2; } - g_cond_free(cond); - g_mutex_free(mutex); - /* deinitialize everything */ input_stream_global_finish(); @@ -164,7 +161,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..8759398da 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 @@ -19,6 +19,7 @@ #include "config.h" #include "conf.h" +#include "fs/Path.hxx" #include <glib.h> @@ -42,7 +43,7 @@ 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); @@ -50,14 +51,16 @@ int main(int argc, char **argv) config_global_init(); GError *error = NULL; - bool success = config_read_file(path, &error); - if (!success) { + if (!ReadConfigFile(config_path, &error)) { g_printerr("%s:", error->message); g_error_free(error); 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..54c92eea3 100644 --- a/test/read_mixer.c +++ b/test/read_mixer.cxx @@ -18,11 +18,14 @@ */ #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 <glib.h> @@ -30,33 +33,35 @@ #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(G_GNUC_UNUSED PulseOutput *po) { } void -pulse_output_unlock(G_GNUC_UNUSED struct pulse_output *po) +pulse_output_unlock(G_GNUC_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(G_GNUC_UNUSED PulseOutput *po, + G_GNUC_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(G_GNUC_UNUSED PulseOutput *po, + G_GNUC_UNUSED PulseMixer *pm) { } bool -pulse_output_set_volume(G_GNUC_UNUSED struct pulse_output *po, +pulse_output_set_volume(G_GNUC_UNUSED PulseOutput *po, G_GNUC_UNUSED const struct pa_cvolume *volume, G_GNUC_UNUSED GError **error_r) { @@ -66,16 +71,16 @@ 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, +roar_output_set_volume(gcc_unused RoarOutput *roar, G_GNUC_UNUSED unsigned volume) { return true; @@ -84,7 +89,7 @@ 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) { } @@ -97,7 +102,7 @@ filter_plugin_by_name(G_GNUC_UNUSED const char *name) bool pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED size_t length, - G_GNUC_UNUSED enum sample_format format, + G_GNUC_UNUSED SampleFormat format, G_GNUC_UNUSED int volume) { assert(false); @@ -107,7 +112,6 @@ pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED size_t length, int main(int argc, G_GNUC_UNUSED char **argv) { GError *error = NULL; - struct mixer *mixer; bool success; int volume; @@ -116,9 +120,14 @@ 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()); + + 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); @@ -137,6 +146,8 @@ int main(int argc, G_GNUC_UNUSED char **argv) mixer_close(mixer); mixer_free(mixer); + delete main_loop; + assert(volume >= -1 && volume <= 100); if (volume < 0) { diff --git a/test/read_tags.c b/test/read_tags.cxx index faf9a45c0..420cf9f0e 100644 --- a/test/read_tags.c +++ b/test/read_tags.cxx @@ -18,17 +18,15 @@ */ #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 "TagHandler.hxx" +#include "TagId3.hxx" +#include "ApeTag.hxx" #include <glib.h> @@ -40,28 +38,9 @@ #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) -{ - return true; -} - void decoder_initialized(G_GNUC_UNUSED struct decoder *decoder, - G_GNUC_UNUSED const struct audio_format *audio_format, + G_GNUC_UNUSED const AudioFormat audio_format, G_GNUC_UNUSED bool seekable, G_GNUC_UNUSED float total_time) { @@ -113,21 +92,19 @@ decoder_data(G_GNUC_UNUSED struct decoder *decoder, 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) + G_GNUC_UNUSED Tag &&tag) { return DECODE_COMMAND_NONE; } -float +void decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, G_GNUC_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, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -156,9 +133,9 @@ print_pair(const char *name, const char *value, G_GNUC_UNUSED void *ctx) } 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) @@ -180,7 +157,10 @@ 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); @@ -205,8 +185,8 @@ 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(); + Mutex mutex; + Cond cond; struct input_stream *is = input_stream_open(path, mutex, cond, &error); @@ -218,12 +198,28 @@ int main(int argc, char **argv) return 1; } + mutex.lock(); + + while (!is->ready) { + cond.wait(mutex); + input_stream_update(is); + } + + if (!input_stream_check(is, &error)) { + mutex.unlock(); + + g_printerr("Failed to read %s: %s\n", + path, error->message); + g_error_free(error); + + 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); } decoder_plugin_deinit_all(); diff --git a/test/run_convert.c b/test/run_convert.cxx index 4f57400fd..ce7df42c3 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,11 @@ */ #include "config.h" -#include "audio_parser.h" -#include "audio_format.h" -#include "pcm_convert.h" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" +#include "pcm/PcmConvert.hxx" #include "conf.h" -#include "fifo_buffer.h" +#include "util/fifo_buffer.h" #include "stdbin.h" #include <glib.h> @@ -48,7 +48,8 @@ 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; } @@ -56,8 +57,7 @@ config_get_string(G_GNUC_UNUSED const char *name, const char *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,15 +69,15 @@ int main(int argc, char **argv) g_log_set_default_handler(my_log_func, NULL); - if (!audio_format_parse(&in_audio_format, argv[1], + if (!audio_format_parse(in_audio_format, argv[1], false, &error)) { g_printerr("Failed to parse audio format: %s\n", error->message); return 1; } - struct audio_format out_audio_format_mask; - if (!audio_format_parse(&out_audio_format_mask, argv[2], + 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); @@ -85,11 +85,11 @@ int main(int argc, char **argv) } 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,8 +112,8 @@ 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); return 2; @@ -122,5 +122,5 @@ int main(int argc, char **argv) G_GNUC_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..a5826b278 100644 --- a/test/run_decoder.c +++ b/test/run_decoder.cxx @@ -18,15 +18,12 @@ */ #include "config.h" -#include "io_thread.h" -#include "decoder_list.h" -#include "decoder_api.h" -#include "tag_pool.h" -#include "input_init.h" +#include "IOThread.hxx" +#include "DecoderList.hxx" +#include "DecoderAPI.hxx" +#include "InputInit.hxx" #include "input_stream.h" -#include "audio_format.h" -#include "pcm_volume.h" -#include "idle.h" +#include "AudioFormat.hxx" #include "stdbin.h" #include <glib.h> @@ -45,25 +42,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 +52,14 @@ struct decoder { void decoder_initialized(struct decoder *decoder, - const struct audio_format *audio_format, + const AudioFormat audio_format, G_GNUC_UNUSED bool seekable, G_GNUC_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)); @@ -135,12 +113,12 @@ decoder_data(G_GNUC_UNUSED struct decoder *decoder, 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) + G_GNUC_UNUSED Tag &&tag) { return DECODE_COMMAND_NONE; } -float +void decoder_replay_gain(G_GNUC_UNUSED struct decoder *decoder, const struct replay_gain_info *replay_gain_info) { @@ -154,13 +132,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, char *mixramp_start, char *mixramp_end) { g_free(mixramp_start); @@ -181,7 +156,10 @@ 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(); @@ -191,8 +169,6 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - tag_pool_init(); - if (!input_stream_global_init(&error)) { g_warning("%s", error->message); g_error_free(error); @@ -213,8 +189,8 @@ 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); @@ -231,9 +207,6 @@ int main(int argc, char **argv) decoder_plugin_stream_decode(decoder.plugin, &decoder, is); input_stream_close(is); - - g_cond_free(cond); - g_mutex_free(mutex); } else { g_printerr("Decoder plugin is not usable\n"); return 1; @@ -248,7 +221,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..27ffddedd 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,10 +18,10 @@ */ #include "config.h" -#include "encoder_list.h" -#include "encoder_plugin.h" -#include "audio_format.h" -#include "audio_parser.h" +#include "EncoderList.hxx" +#include "EncoderPlugin.hxx" +#include "AudioFormat.hxx" +#include "AudioParser.hxx" #include "conf.h" #include "stdbin.h" @@ -31,12 +31,12 @@ #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) { + while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) { G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length); } } @@ -44,14 +44,9 @@ encoder_to_stdout(struct encoder *encoder) 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,20 +60,18 @@ 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); + const auto encoder = encoder_init(*plugin, param, &error); if (encoder == NULL) { g_printerr("Failed to initialize encoder: %s\n", error->message); @@ -88,8 +81,9 @@ int main(int argc, char **argv) /* open the encoder */ + AudioFormat audio_format(44100, SampleFormat::S16, 2); if (argc > 2) { - ret = audio_format_parse(&audio_format, argv[2], + ret = audio_format_parse(audio_format, argv[2], false, &error); if (!ret) { g_printerr("Failed to parse audio format: %s\n", @@ -99,17 +93,18 @@ int main(int argc, char **argv) } } - 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); 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) { @@ -119,7 +114,7 @@ int main(int argc, char **argv) return 1; } - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); } ret = encoder_end(encoder, &error); @@ -130,5 +125,5 @@ int main(int argc, char **argv) return 1; } - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); } diff --git a/test/run_filter.c b/test/run_filter.cxx index 8e793b768..761bc14e8 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 @@ -19,13 +19,13 @@ #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 "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 <glib.h> @@ -35,15 +35,8 @@ #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, +mixer_set_volume(gcc_unused Mixer *mixer, G_GNUC_UNUSED unsigned volume, G_GNUC_UNUSED GError **error_r) { return true; @@ -60,13 +53,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,20 +66,19 @@ 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); + Filter *filter = filter_configured_new(*param, &error); if (filter == NULL) { g_printerr("Failed to load filter: %s\n", error->message); g_error_free(error); @@ -99,12 +90,9 @@ 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; char buffer[4096]; if (argc < 3 || argc > 4) { @@ -112,18 +100,22 @@ 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) { + if (!ReadConfigFile(config_path, &error)) { g_printerr("%s:", error->message); g_error_free(error); return 1; @@ -132,7 +124,7 @@ int main(int argc, char **argv) /* parse the audio format */ if (argc > 3) { - success = audio_format_parse(&audio_format, argv[3], + success = audio_format_parse(audio_format, argv[3], false, &error); if (!success) { g_printerr("Failed to parse audio format: %s\n", @@ -144,17 +136,18 @@ int main(int argc, char **argv) /* 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) { + const AudioFormat out_audio_format = + filter->Open(audio_format, &error); + if (!out_audio_format.IsDefined()) { g_printerr("Failed to open filter: %s\n", error->message); g_error_free(error); - filter_free(filter); + delete filter; return 1; } @@ -172,28 +165,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); + 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..29fcf70ab 100644 --- a/test/run_inotify.c +++ b/test/run_inotify.cxx @@ -18,18 +18,20 @@ */ #include "config.h" -#include "inotify_source.h" +#include "InotifySource.hxx" +#include "event/Loop.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) { - g_main_loop_quit(main_loop); + event_loop->Break(); } enum { @@ -59,26 +61,25 @@ 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()); + + InotifySource *source = InotifySource::Create(*event_loop, + my_inotify_callback, + nullptr, &error); if (source == NULL) { g_warning("%s", error->message); g_error_free(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); + delete source; g_warning("%s", error->message); g_error_free(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..e93e817d3 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,17 @@ */ #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.hxx" +#include "conf.h" +#include "input_stream.h" +#include "InputStream.hxx" +#include "InputInit.hxx" +#include "IOThread.hxx" #ifdef ENABLE_ARCHIVE -#include "archive_list.h" +#include "ArchiveList.hxx" #endif #include <glib.h> @@ -68,17 +69,17 @@ dump_input_stream(struct input_stream *is) /* 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); + Tag *tag = input_stream_tag(is); 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), @@ -122,12 +123,14 @@ 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(); @@ -149,8 +152,8 @@ int main(int argc, char **argv) /* 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); if (is != NULL) { @@ -165,9 +168,6 @@ int main(int argc, char **argv) ret = 2; } - g_cond_free(cond); - g_mutex_free(mutex); - /* deinitialize everything */ input_stream_global_finish(); @@ -179,7 +179,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..72e23054f 100644 --- a/test/run_normalize.c +++ b/test/run_normalize.cxx @@ -25,8 +25,8 @@ #include "config.h" #include "AudioCompress/compress.h" -#include "audio_parser.h" -#include "audio_format.h" +#include "AudioParser.hxx" +#include "AudioFormat.hxx" #include "stdbin.h" #include <glib.h> @@ -38,7 +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]; @@ -49,16 +48,16 @@ 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], + ret = audio_format_parse(audio_format, argv[1], false, &error); if (!ret) { g_printerr("Failed to parse audio format: %s\n", error->message); return 1; } - } else - audio_format_init(&audio_format, 48000, 16, 2); + } compressor = Compressor_new(0); diff --git a/test/run_output.c b/test/run_output.cxx index bbb1be7d2..fbdeebcb6 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,18 +18,20 @@ */ #include "config.h" -#include "io_thread.h" -#include "output_plugin.h" -#include "output_internal.h" -#include "output_control.h" +#include "OutputControl.hxx" +#include "OutputInternal.hxx" +#include "OutputPlugin.hxx" #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 "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 <glib.h> @@ -39,33 +41,22 @@ #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) -{ -} +PcmConvert::PcmConvert() {} +PcmConvert::~PcmConvert() {} 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) +PcmConvert::Convert(gcc_unused const AudioFormat src_format, + gcc_unused const void *src, gcc_unused size_t src_size, + gcc_unused const AudioFormat dest_format, + gcc_unused size_t *dest_size_r, + gcc_unused GError **error_r) { g_set_error(error_r, pcm_convert_quark(), 0, "Not implemented"); @@ -80,13 +71,12 @@ filter_plugin_by_name(G_GNUC_UNUSED const char *name) } 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,6 +84,10 @@ 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) { @@ -103,13 +97,13 @@ load_audio_output(const char *name) 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); struct audio_output *ao = - audio_output_new(param, &dummy_player_control, &error); + audio_output_new(*param, &dummy_player_control, &error); if (ao == NULL) { g_printerr("%s\n", error->message); g_error_free(error); @@ -119,7 +113,7 @@ load_audio_output(const char *name) } 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 */ @@ -143,7 +137,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 */ @@ -188,7 +182,6 @@ 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; @@ -197,20 +190,25 @@ 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); + +#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) { + if (!ReadConfigFile(config_path, &error)) { g_printerr("%s:", error->message); g_error_free(error); return 1; } + main_loop = new EventLoop(EventLoop::Default()); + io_thread_init(); if (!io_thread_start(&error)) { g_warning("%s", error->message); @@ -227,7 +225,7 @@ int main(int argc, char **argv) /* parse the audio format */ if (argc > 3) { - success = audio_format_parse(&audio_format, argv[3], + success = audio_format_parse(audio_format, argv[3], false, &error); if (!success) { g_printerr("Failed to parse audio format: %s\n", @@ -239,7 +237,7 @@ int main(int argc, char **argv) /* do it */ - success = run_output(ao, &audio_format); + success = run_output(ao, audio_format); /* cleanup and exit */ @@ -247,6 +245,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_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..c46804731 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,9 @@ */ #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 "stdbin.h" #include <glib.h> @@ -37,7 +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,19 +46,20 @@ 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], + ret = audio_format_parse(audio_format, argv[1], false, &error); if (!ret) { g_printerr("Failed to parse audio format: %s\n", error->message); 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; diff --git a/test/test_pcm_all.hxx b/test/test_pcm_all.hxx new file mode 100644 index 000000000..18202454b --- /dev/null +++ b/test/test_pcm_all.hxx @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#ifndef MPD_TEST_PCM_ALL_HXX +#define MPD_TEST_PCM_ALL_HXX + +void +test_pcm_dither_24(); + +void +test_pcm_dither_32(); + +void +test_pcm_pack_24(); + +void +test_pcm_unpack_24(); + +void +test_pcm_channels_16(); + +void +test_pcm_channels_32(); + +void +test_pcm_volume_8(); + +void +test_pcm_volume_16(); + +void +test_pcm_volume_24(); + +void +test_pcm_volume_32(); + +void +test_pcm_volume_float(); + +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(); + +#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.cxx index 619399159..75e1462dc 100644 --- a/test/test_vorbis_encoder.c +++ b/test/test_vorbis_encoder.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,12 +18,12 @@ */ #include "config.h" -#include "encoder_list.h" -#include "encoder_plugin.h" -#include "audio_format.h" +#include "EncoderList.hxx" +#include "EncoderPlugin.hxx" +#include "AudioFormat.hxx" #include "conf.h" #include "stdbin.h" -#include "tag.h" +#include "Tag.hxx" #include <glib.h> @@ -33,12 +33,12 @@ static uint8_t zero[256]; 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) { + while ((length = encoder_read(&encoder, buffer, sizeof(buffer))) > 0) { G_GNUC_UNUSED ssize_t ignored = write(1, buffer, length); } } @@ -50,49 +50,45 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) /* create the encoder */ - const struct encoder_plugin *plugin = encoder_plugin_get("vorbis"); + const auto 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); + config_param param; + param.AddBlockParam("quality", "5.0", -1); - struct encoder *encoder = encoder_init(plugin, param, NULL); + const auto 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); + AudioFormat audio_format(44100, SampleFormat::S16, 2); + success = encoder_open(encoder, audio_format, NULL); assert(success); - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); /* write a block of data */ success = encoder_write(encoder, zero, sizeof(zero), NULL); assert(success); - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); /* write a tag */ success = encoder_pre_tag(encoder, NULL); assert(success); - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); - struct tag *tag = tag_new(); - tag_add_item(tag, TAG_ARTIST, "Foo"); - tag_add_item(tag, TAG_TITLE, "Bar"); + Tag tag; + tag.AddItem(TAG_ARTIST, "Foo"); + tag.AddItem(TAG_TITLE, "Bar"); - success = encoder_tag(encoder, tag, NULL); + success = encoder_tag(encoder, &tag, NULL); assert(success); - tag_free(tag); - - encoder_to_stdout(encoder); + encoder_to_stdout(*encoder); /* write another block of data */ @@ -104,7 +100,7 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) success = encoder_end(encoder, NULL); assert(success); - encoder_to_stdout(encoder); + 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..047fe62c0 --- /dev/null +++ b/test/visit_archive.cxx @@ -0,0 +1,126 @@ +/* + * 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.hxx" +#include "conf.h" +#include "IOThread.hxx" +#include "InputInit.hxx" +#include "ArchiveList.hxx" +#include "ArchivePlugin.hxx" +#include "ArchiveFile.hxx" +#include "ArchiveVisitor.hxx" +#include "fs/Path.hxx" + +#include <glib.h> + +#include <unistd.h> +#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) +{ + 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) +{ + GError *error = nullptr; + + 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(); + if (!io_thread_start(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + archive_plugin_init_all(); + + if (!input_stream_global_init(&error)) { + g_warning("%s", error->message); + g_error_free(error); + 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\n", error->message); + g_error_free(error); + result = EXIT_FAILURE; + } + + /* deinitialize everything */ + + input_stream_global_finish(); + + archive_plugin_deinit_all(); + + io_thread_deinit(); + + config_global_finish(); + + return result; +} |