diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/DumpDatabase.cxx | 147 | ||||
-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) | 39 | ||||
-rw-r--r-- | test/dump_rva2.c | 9 | ||||
-rw-r--r-- | test/dump_text_file.cxx (renamed from test/dump_text_file.c) | 23 | ||||
-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) | 26 | ||||
-rw-r--r-- | test/read_tags.cxx (renamed from test/read_tags.c) | 67 | ||||
-rw-r--r-- | test/run_convert.cxx (renamed from test/run_convert.c) | 20 | ||||
-rw-r--r-- | test/run_decoder.cxx (renamed from test/run_decoder.c) | 44 | ||||
-rw-r--r-- | test/run_encoder.cxx (renamed from test/run_encoder.c) | 13 | ||||
-rw-r--r-- | test/run_filter.cxx (renamed from test/run_filter.c) | 62 | ||||
-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) | 30 | ||||
-rw-r--r-- | test/run_normalize.cxx (renamed from test/run_normalize.c) | 4 | ||||
-rw-r--r-- | test/run_output.cxx (renamed from test/run_output.c) | 78 | ||||
-rw-r--r-- | test/run_tcp_connect.c | 164 | ||||
-rw-r--r-- | test/software_volume.cxx (renamed from test/software_volume.c) | 9 | ||||
-rw-r--r-- | test/test_pcm_all.hxx | 80 | ||||
-rw-r--r-- | test/test_pcm_channels.cxx (renamed from test/test_pcm_channels.c) | 25 | ||||
-rw-r--r-- | test/test_pcm_dither.cxx (renamed from test/test_pcm_dither.c) | 51 | ||||
-rw-r--r-- | test/test_pcm_format.cxx | 130 | ||||
-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) | 42 | ||||
-rw-r--r-- | test/test_pcm_util.hxx | 85 | ||||
-rw-r--r-- | test/test_pcm_volume.cxx (renamed from test/test_pcm_volume.c) | 101 | ||||
-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) | 8 | ||||
-rw-r--r-- | test/visit_archive.cxx | 123 |
32 files changed, 1184 insertions, 773 deletions
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx new file mode 100644 index 000000000..ba0e74e43 --- /dev/null +++ b/test/DumpDatabase.cxx @@ -0,0 +1,147 @@ +/* + * 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.h" +#include "PlaylistVector.hxx" +#include "conf.h" +#include "tag.h" +#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 */ + + g_thread_init(nullptr); + 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(¶m, &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..927a07652 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.h" +#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 +struct song * +song_dup_detached(gcc_unused const struct song *src) +{ + abort(); +} diff --git a/test/dump_playlist.c b/test/dump_playlist.cxx index 84ac69045..6e1f4858e 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.h" +#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 "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) @@ -107,7 +111,7 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, 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,7 +139,6 @@ 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; @@ -148,6 +148,7 @@ int main(int argc, char **argv) return 1; } + const Path config_path = Path::FromFS(argv[1]); uri = argv[2]; /* initialize GLib */ @@ -157,10 +158,8 @@ int main(int argc, char **argv) /* 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 +183,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) { @@ -241,15 +240,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.c index 4a726518a..6e978c424 100644 --- a/test/dump_rva2.c +++ b/test/dump_rva2.c @@ -26,6 +26,8 @@ #include <id3tag.h> +#include <glib.h> + #ifdef HAVE_LOCALE_H #include <locale.h> #endif @@ -33,7 +35,8 @@ #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; } @@ -45,8 +48,8 @@ tag_new(void) } 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_add_item_n(gcc_unused struct tag *tag, gcc_unused enum tag_type type, + gcc_unused const char *value, gcc_unused size_t len) { } diff --git a/test/dump_text_file.c b/test/dump_text_file.cxx index f14371441..93b0d0185 100644 --- a/test/dump_text_file.c +++ b/test/dump_text_file.cxx @@ -18,16 +18,18 @@ */ #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" +extern "C" { +#include "text_input_stream.h" +} + #ifdef ENABLE_ARCHIVE -#include "archive_list.h" +#include "ArchiveList.hxx" #endif #include <glib.h> @@ -112,7 +114,6 @@ int main(int argc, char **argv) /* initialize MPD */ - tag_pool_init(); config_global_init(); io_thread_init(); @@ -134,8 +135,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 +151,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 +162,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..45344a2f6 100644 --- a/test/read_mixer.c +++ b/test/read_mixer.cxx @@ -18,11 +18,13 @@ */ #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 "PcmVolume.hxx" +#include "GlobalEvents.hxx" +#include "Main.hxx" +#include "event/Loop.hxx" #include <glib.h> @@ -30,6 +32,8 @@ #include <string.h> #include <unistd.h> +EventLoop *main_loop; + #ifdef HAVE_PULSE #include "output/pulse_output_plugin.h" @@ -66,16 +70,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 +88,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) { } @@ -118,6 +122,8 @@ int main(int argc, G_GNUC_UNUSED char **argv) g_thread_init(NULL); + main_loop = new EventLoop(EventLoop::Default()); + mixer = mixer_new(&alsa_mixer_plugin, NULL, NULL, &error); if (mixer == NULL) { g_printerr("mixer_new() failed: %s\n", error->message); @@ -137,6 +143,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..1ceddf1d5 100644 --- a/test/read_tags.c +++ b/test/read_tags.cxx @@ -18,17 +18,17 @@ */ #include "config.h" -#include "io_thread.h" -#include "decoder_list.h" +#include "IOThread.hxx" +#include "DecoderList.hxx" #include "decoder_api.h" -#include "input_init.h" -#include "input_stream.h" +#include "InputInit.hxx" +#include "InputStream.hxx" #include "audio_format.h" -#include "pcm_volume.h" +extern "C" { #include "tag_ape.h" #include "tag_id3.h" +} #include "tag_handler.h" -#include "idle.h" #include <glib.h> @@ -40,25 +40,6 @@ #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, @@ -118,16 +99,14 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, 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 +135,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) @@ -205,8 +184,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 +197,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..e66d0be2b 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 "AudioParser.hxx" #include "audio_format.h" -#include "pcm_convert.h" +#include "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; } @@ -57,7 +58,6 @@ int main(int argc, char **argv) { GError *error = NULL; struct audio_format in_audio_format, out_audio_format; - struct pcm_convert_state state; const void *output; ssize_t nbytes; size_t length; @@ -89,7 +89,7 @@ int main(int argc, char **argv) const size_t in_frame_size = audio_format_frame_size(&in_audio_format); - 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..d5c7c3139 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 "IOThread.hxx" +#include "DecoderList.hxx" #include "decoder_api.h" -#include "tag_pool.h" -#include "input_init.h" +#include "InputInit.hxx" #include "input_stream.h" #include "audio_format.h" -#include "pcm_volume.h" -#include "idle.h" #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; @@ -140,7 +118,7 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, 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); @@ -191,8 +166,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 +186,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 +204,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 +218,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..9039f2db5 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 @@ -21,7 +21,7 @@ #include "encoder_list.h" #include "encoder_plugin.h" #include "audio_format.h" -#include "audio_parser.h" +#include "AudioParser.hxx" #include "conf.h" #include "stdbin.h" @@ -49,9 +49,7 @@ int main(int argc, char **argv) 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 */ @@ -75,10 +73,10 @@ int main(int argc, char **argv) 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); + encoder = encoder_init(plugin, ¶m, &error); if (encoder == NULL) { g_printerr("Failed to initialize encoder: %s\n", error->message); @@ -110,6 +108,7 @@ int main(int argc, char **argv) /* do it */ + ssize_t nbytes; while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) { ret = encoder_write(encoder, buffer, nbytes, &error); if (!ret) { diff --git a/test/run_filter.c b/test/run_filter.cxx index 8e793b768..9ea50ff55 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 "fs/Path.hxx" +#include "AudioParser.hxx" #include "audio_format.h" -#include "filter_plugin.h" -#include "pcm_volume.h" -#include "idle.h" -#include "mixer_control.h" -#include "playlist.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "PcmVolume.hxx" +#include "MixerControl.hxx" #include "stdbin.h" #include <glib.h> @@ -35,13 +35,6 @@ #include <errno.h> #include <unistd.h> -struct playlist g_playlist; - -void -idle_add(G_GNUC_UNUSED unsigned flags) -{ -} - bool mixer_set_volume(G_GNUC_UNUSED struct mixer *mixer, G_GNUC_UNUSED unsigned volume, G_GNUC_UNUSED GError **error_r) @@ -60,11 +53,11 @@ 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) { + while ((param = config_get_next_param(option, param)) != NULL) { const char *current_name = config_get_block_string(param, "name", NULL); if (current_name != NULL && strcmp(current_name, name) == 0) @@ -74,20 +67,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); @@ -103,7 +95,6 @@ int main(int argc, char **argv) struct audio_format_string af_string; bool success; GError *error = NULL; - struct filter *filter; const struct audio_format *out_audio_format; char buffer[4096]; @@ -112,6 +103,8 @@ int main(int argc, char **argv) return 1; } + const Path config_path = Path::FromFS(argv[1]); + audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); /* initialize GLib */ @@ -122,8 +115,7 @@ int main(int argc, char **argv) /* 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; @@ -144,17 +136,17 @@ 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); + out_audio_format = filter->Open(audio_format, &error); if (out_audio_format == NULL) { g_printerr("Failed to open filter: %s\n", error->message); g_error_free(error); - filter_free(filter); + delete filter; return 1; } @@ -172,28 +164,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..157613dbc 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.h" +#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,8 +69,8 @@ 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 */ @@ -127,7 +128,6 @@ int main(int argc, char **argv) /* initialize MPD */ - tag_pool_init(); config_global_init(); io_thread_init(); @@ -149,8 +149,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 +165,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 +176,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..070dbaf5a 100644 --- a/test/run_normalize.c +++ b/test/run_normalize.cxx @@ -25,7 +25,7 @@ #include "config.h" #include "AudioCompress/compress.h" -#include "audio_parser.h" +#include "AudioParser.hxx" #include "audio_format.h" #include "stdbin.h" @@ -58,7 +58,7 @@ int main(int argc, char **argv) return 1; } } else - audio_format_init(&audio_format, 48000, 16, 2); + audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, 2); compressor = Compressor_new(0); diff --git a/test/run_output.c b/test/run_output.cxx index bbb1be7d2..5b6d54a11 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,24 @@ */ #include "config.h" -#include "io_thread.h" +#include "OutputControl.hxx" +#include "conf.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 "PcmConvert.hxx" + +extern "C" { #include "output_plugin.h" #include "output_internal.h" -#include "output_control.h" -#include "conf.h" -#include "audio_parser.h" -#include "filter_registry.h" -#include "pcm_convert.h" -#include "event_pipe.h" -#include "idle.h" -#include "playlist.h" -#include "player_control.h" +} + +#include "FilterRegistry.hxx" +#include "PlayerControl.hxx" #include "stdbin.h" #include <glib.h> @@ -39,33 +45,22 @@ #include <unistd.h> #include <stdlib.h> -struct playlist g_playlist; +EventLoop *main_loop; void -idle_add(G_GNUC_UNUSED unsigned flags) -{ -} - -void -event_pipe_emit(G_GNUC_UNUSED enum pipe_event event) -{ -} - -void pcm_convert_init(G_GNUC_UNUSED struct pcm_convert_state *state) +GlobalEvents::Emit(gcc_unused Event event) { } -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 audio_format *src_format, + gcc_unused const void *src, gcc_unused size_t src_size, + gcc_unused const audio_format *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,11 +75,11 @@ 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) { + while ((param = config_get_next_param(option, param)) != NULL) { const char *current_name = config_get_block_string(param, "name", NULL); if (current_name != NULL && strcmp(current_name, name) == 0) @@ -94,6 +89,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,10 +102,10 @@ 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); @@ -197,6 +196,8 @@ int main(int argc, char **argv) return 1; } + const Path config_path = Path::FromFS(argv[1]); + audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); g_thread_init(NULL); @@ -204,13 +205,14 @@ int main(int argc, char **argv) /* 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); @@ -247,6 +249,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..929932398 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,8 +24,8 @@ */ #include "config.h" -#include "pcm_volume.h" -#include "audio_parser.h" +#include "PcmVolume.hxx" +#include "AudioParser.hxx" #include "audio_format.h" #include "stdbin.h" @@ -59,7 +59,8 @@ int main(int argc, char **argv) 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, + sample_format(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..8e013d5af 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,20 +18,18 @@ */ #include "config.h" -#include "test_pcm_all.h" -#include "pcm_channels.h" +#include "test_pcm_all.hxx" +#include "test_pcm_util.hxx" +#include "PcmChannels.hxx" #include "pcm_buffer.h" #include <glib.h> void -test_pcm_channels_16(void) +test_pcm_channels_16() { - enum { N = 256 }; - int16_t src[N * 2]; - - for (unsigned i = 0; i < G_N_ELEMENTS(src); ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N * 2>(); struct pcm_buffer buffer; pcm_buffer_init(&buffer); @@ -63,13 +61,10 @@ test_pcm_channels_16(void) } void -test_pcm_channels_32(void) +test_pcm_channels_32() { - enum { N = 256 }; - int32_t src[N * 2]; - - for (unsigned i = 0; i < G_N_ELEMENTS(src); ++i) - src[i] = g_random_int(); + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int32_t, N * 2>(); struct pcm_buffer buffer; pcm_buffer_init(&buffer); diff --git a/test/test_pcm_dither.c b/test/test_pcm_dither.cxx index 44d105207..2fb976db5 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 "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..f175a850c --- /dev/null +++ b/test/test_pcm_format.cxx @@ -0,0 +1,130 @@ +/* + * 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 "PcmFormat.hxx" +#include "PcmDither.hxx" +#include "PcmUtils.hxx" +#include "pcm_buffer.h" +#include "audio_format.h" + +#include <glib.h> + +void +test_pcm_format_8_to_16() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int8_t, N>(); + + struct pcm_buffer buffer; + pcm_buffer_init(&buffer); + + size_t d_size; + PcmDither dither; + auto d = pcm_convert_to_16(&buffer, dither, SAMPLE_FORMAT_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); + + pcm_buffer_deinit(&buffer); +} + +void +test_pcm_format_16_to_24() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + struct pcm_buffer buffer; + pcm_buffer_init(&buffer); + + size_t d_size; + auto d = pcm_convert_to_24(&buffer, SAMPLE_FORMAT_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); + + pcm_buffer_deinit(&buffer); +} + +void +test_pcm_format_16_to_32() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + struct pcm_buffer buffer; + pcm_buffer_init(&buffer); + + size_t d_size; + auto d = pcm_convert_to_32(&buffer, SAMPLE_FORMAT_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); + + pcm_buffer_deinit(&buffer); +} + +void +test_pcm_format_float() +{ + constexpr unsigned N = 256; + const auto src = TestDataBuffer<int16_t, N>(); + + struct pcm_buffer buffer1, buffer2; + pcm_buffer_init(&buffer1); + pcm_buffer_init(&buffer2); + + size_t f_size; + auto f = pcm_convert_to_float(&buffer1, SAMPLE_FORMAT_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, + SAMPLE_FORMAT_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]); + + pcm_buffer_deinit(&buffer1); + pcm_buffer_deinit(&buffer2); +} 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..a6e01d20f --- /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 "PcmMix.hxx" + +#include <glib.h> + +template<typename T, sample_format 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, SAMPLE_FORMAT_S8>(); +} + +void +test_pcm_mix_16() +{ + TestPcmMix<int16_t, SAMPLE_FORMAT_S16>(); +} + +void +test_pcm_mix_24() +{ + TestPcmMix<int32_t, SAMPLE_FORMAT_S24_P32>(GlibRandomInt24()); +} + +void +test_pcm_mix_32() +{ + TestPcmMix<int32_t, SAMPLE_FORMAT_S32>(); +} diff --git a/test/test_pcm_pack.c b/test/test_pcm_pack.cxx index 5127536fb..e23acad58 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 "test_pcm_all.hxx" +#include "test_pcm_util.hxx" + +extern "C" { #include "pcm_pack.h" +} #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_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..1ab590490 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,35 +17,36 @@ * 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 "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)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S8, PCM_VOLUME_1 / 2), ==, true); @@ -56,27 +57,25 @@ 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)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S16, PCM_VOLUME_1 / 2), ==, true); @@ -86,40 +85,26 @@ 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)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S24_P32, PCM_VOLUME_1 / 2), ==, true); @@ -130,27 +115,25 @@ 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)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_S32, PCM_VOLUME_1 / 2), ==, true); @@ -161,27 +144,25 @@ 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)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, 0), ==, true); g_assert_cmpint(memcmp(dest, zero, sizeof(zero)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, PCM_VOLUME_1), ==, true); g_assert_cmpint(memcmp(dest, src, sizeof(src)), ==, 0); - memcpy(dest, src, sizeof(src)); + std::copy(src.begin(), src.end(), dest); g_assert_cmpint(pcm_volume(dest, sizeof(dest), SAMPLE_FORMAT_FLOAT, PCM_VOLUME_1 / 2), ==, true); 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..8dd1c3f5f --- /dev/null +++ b/test/test_queue_priority.cxx @@ -0,0 +1,188 @@ +#include "config.h" +#include "Queue.hxx" +#include "song.h" +#include "Directory.hxx" + +#include <glib.h> + +Directory detached_root; + +Directory::Directory() {} +Directory::~Directory() {} + +struct song * +song_dup_detached(const struct song *src) +{ + return const_cast<song *>(src); +} + +void +song_free(gcc_unused struct song *song) +{ +} + +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 struct 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..0e502b154 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 @@ -53,10 +53,10 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) const struct encoder_plugin *plugin = encoder_plugin_get("vorbis"); assert(plugin != NULL); - struct config_param *param = config_new_param(NULL, -1); - config_add_block_param(param, "quality", "5.0", -1); + config_param param; + param.AddBlockParam("quality", "5.0", -1); - struct encoder *encoder = encoder_init(plugin, param, NULL); + struct encoder *encoder = encoder_init(plugin, ¶m, NULL); assert(encoder != NULL); /* open the encoder */ diff --git a/test/visit_archive.cxx b/test/visit_archive.cxx new file mode 100644 index 000000000..6faf4f3ae --- /dev/null +++ b/test/visit_archive.cxx @@ -0,0 +1,123 @@ +/* + * 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.h" +#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 */ + + g_thread_init(NULL); + 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; +} |